| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:async'; |
| import 'dart:convert'; |
| |
| import 'package:fidl/fidl.dart'; |
| import 'package:fidl_fuchsia_mem/fidl.dart' as fuchsia_mem; |
| import 'package:fidl_fuchsia_modular/fidl.dart' as fidl; |
| import 'package:json_schema/json_schema.dart' as json_schema; |
| import 'package:lib.app.dart/logging.dart'; |
| import 'package:zircon/zircon.dart'; |
| |
| /// Provides an idiomatic way to access and type-validate data from an [fidl.Entity]. |
| class EntityClient { |
| /// The underlying [Proxy] used to send client requests to the |
| /// [fidl.Entity] service. |
| final fidl.EntityProxy proxy; |
| |
| /// Constructor. |
| EntityClient() : proxy = fidl.EntityProxy() { |
| proxy.ctrl |
| ..onBind = _handleBind |
| ..onClose = _handleClose |
| ..onConnectionError = _handleConnectionError |
| ..onUnbind = _handleUnbind; |
| } |
| |
| /// Constructor. |
| EntityClient.fromEntity(this.proxy); |
| |
| /// List of types this entity supports. |
| Future<List<String>> getTypes() { |
| Completer<List<String>> result = Completer<List<String>>(); |
| proxy.getTypes(result.complete); |
| return result.future; |
| } |
| |
| /// Given one of the types returned from [getTypes], this method gets the data |
| /// for it, validates it using [jsonTypeSchema], and returns non-null data if |
| /// the data is valid. |
| Future<String> getValidatedData(String type, String jsonTypeSchema) async { |
| String data = await getData(type); |
| json_schema.Schema schema = |
| await json_schema.Schema.createSchema(json.decode(jsonTypeSchema)); |
| if (data != null && schema.validate(jsonTypeSchema)) { |
| return data; |
| } |
| return null; |
| } |
| |
| Future<fuchsia_mem.Buffer> _getVmoData(String type) { |
| Completer<fuchsia_mem.Buffer> result = Completer<fuchsia_mem.Buffer>(); |
| proxy.getData(type, result.complete); |
| return result.future; |
| } |
| |
| /// Returns the data associated with the given type without validating it. |
| Future<String> getData(String type) async { |
| var buffer = await _getVmoData(type); |
| var dataVmo = SizedVmo(buffer.vmo.handle, buffer.size); |
| var data = dataVmo.read(buffer.size); |
| dataVmo.close(); |
| return utf8.decode(data.bytesAsUint8List()); |
| } |
| |
| /// Closes the underlying proxy connection, should be called as a response to |
| /// Lifecycle::terminate (see https://goo.gl/MmZ2dc). |
| Future<Null> terminate() async { |
| log.info('terminate called'); |
| proxy.ctrl.close(); |
| return; |
| } |
| |
| void _handleBind() { |
| log.fine('proxy ready'); |
| } |
| |
| void _handleUnbind() { |
| log.fine('proxy unbound'); |
| } |
| |
| void _handleClose() { |
| log.fine('proxy closed'); |
| } |
| |
| void _handleConnectionError() { |
| log.warning('Entity connection error'); |
| } |
| } |