blob: ce3bff48aca9a5a6a2ae0303e965db73b03a568b [file] [log] [blame]
// 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 '';
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() {
..onBind = _handleBind
..onClose = _handleClose
..onConnectionError = _handleConnectionError
..onUnbind = _handleUnbind;
/// Constructor.
/// List of types this entity supports.
Future<List<String>> getTypes() {
Completer<List<String>> result = Completer<List<String>>();
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 =;
return utf8.decode(data.bytesAsUint8List());
/// Closes the underlying proxy connection, should be called as a response to
/// Lifecycle::terminate (see
Future<Null> terminate() async {'terminate called');
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');