blob: 3305c69af868659ca58c0533fcfba0a1d5d4ea3c [file] [log] [blame]
// Copyright 2018 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
/// A version of app.dart built on the new async bindings.
import 'dart:async';
import 'package:fidl/fidl.dart';
import 'package:fuchsia/fuchsia.dart';
import 'package:fidl_fuchsia_sys/fidl_async.dart';
import 'package:zircon/zircon.dart';
import 'package:fidl_fuchsia_io/fidl_async.dart';
import 'app.dart' as sync_app;
import 'src/outgoing.dart';
export 'src/outgoing.dart';
/// Deprecated! Use package:fuchsia_services/services.dart instead
class StartupContext {
static StartupContext _context;
StartupContext();
final EnvironmentProxy environment = new EnvironmentProxy();
final LauncherProxy launcher = new LauncherProxy();
final ServiceProviderProxy environmentServices = new ServiceProviderProxy();
final Outgoing outgoingServices = new Outgoing();
factory StartupContext.fromStartupInfo() {
if (_context != null) {
return _context;
}
if (sync_app.StartupContext.initialTrace != null) {
print(
"WARNING: app.dart's StartupContext was created at:\n${sync_app.StartupContext.initialTrace}");
}
final StartupContext context = new StartupContext();
final Handle environmentHandle = MxStartupInfo.takeEnvironment();
if (environmentHandle != null) {
context.environment
..ctrl.bind(
new InterfaceHandle<Environment>(new Channel(environmentHandle)))
..getLauncher(context.launcher.ctrl.request())
..getServices(context.environmentServices.ctrl.request());
}
final Handle outgoingServicesHandle = MxStartupInfo.takeOutgoingServices();
if (outgoingServicesHandle != null) {
context.outgoingServices
.serve(InterfaceRequest<Node>(Channel(outgoingServicesHandle)));
}
_context = context;
return context;
}
/// Provide an alternative startup context that will then be provided on
/// through [StartupContext.fromStartupInfo].
///
/// This is primarily used to provide alternative environment services for
/// testing purposes.
static void provideStartupContext(StartupContext context) {
assert(_context != null, 'StartupContext should never be overwritten.');
_context = context;
}
void close() {
environment.ctrl.close();
launcher.ctrl.close();
environmentServices.ctrl.close();
outgoingServices.close();
}
}
/// Deprecated! Use package:fuchsia_services/services.dart instead
Future<void> connectToService<T>(
ServiceProvider serviceProvider, AsyncProxyController<T> controller) async {
final String serviceName = controller.$serviceName;
if (serviceName == null) {
throw new Exception(
"${controller.$interfaceName}'s controller.\$serviceName"
' must not be null. Check the FIDL file for a missing [Discoverable]');
}
await serviceProvider.connectToService(
serviceName, controller.request().passChannel());
}
/// Deprecated! Use package:fuchsia_services/services.dart instead
InterfaceHandle<T> connectToServiceByName<T>(
ServiceProvider serviceProvider, String serviceName) {
final ChannelPair pair = new ChannelPair();
serviceProvider.connectToService(serviceName, pair.first);
return new InterfaceHandle<T>(pair.second);
}
typedef ServiceConnector<T> = void Function(InterfaceRequest<T> request);
typedef DefaultServiceConnector<T> = void Function(
String serviceName, InterfaceRequest<T> request);
typedef _ServiceConnectorThunk = void Function(Channel channel);
/// Deprecated! Use package:fuchsia_services/services.dart instead
class ServiceProviderImpl extends ServiceProvider {
final ServiceProviderBinding _binding = new ServiceProviderBinding();
void bind(InterfaceRequest<ServiceProvider> interfaceRequest) {
_binding.bind(this, interfaceRequest);
}
void close() {
_binding.close();
}
DefaultServiceConnector<dynamic> defaultConnector;
final Map<String, _ServiceConnectorThunk> _connectorThunks =
<String, _ServiceConnectorThunk>{};
void addServiceForName<T>(ServiceConnector<T> connector, String serviceName) {
_connectorThunks[serviceName] = (Channel channel) {
connector(new InterfaceRequest<T>(channel));
};
}
@override
Future<Null> connectToService(String serviceName, Channel channel) {
final _ServiceConnectorThunk connectorThunk = _connectorThunks[serviceName];
if (connectorThunk != null) {
connectorThunk(channel);
} else if (defaultConnector != null) {
defaultConnector(serviceName, new InterfaceRequest<dynamic>(channel));
} else {
channel.close();
}
return null;
}
}
/// Deprecated! Use package:fuchsia_services/services.dart instead
class Services {
DirectoryProxy _proxy;
static const int _openFlags =
openRightReadable | openRightWritable; // connect flags for service
static const int _openMode = 0x1ED; // 0755
Services();
Channel request() {
_proxy = DirectoryProxy();
return _proxy.ctrl.request().passChannel();
}
Future<void> connectToService<T>(AsyncProxyController<T> controller) async {
final String serviceName = controller.$serviceName;
if (serviceName == null) {
throw new Exception(
"${controller.$interfaceName}'s controller.\$serviceName"
' must not be null. Check the FIDL file for a missing [Discoverable]');
}
await _proxy.open(_openFlags, _openMode, serviceName,
InterfaceRequest<Node>(controller.request().passChannel()));
}
Future<InterfaceHandle<T>> connectToServiceByName<T>(
String serviceName) async {
final ChannelPair pair = new ChannelPair();
await _proxy.open(
_openFlags, _openMode, serviceName, InterfaceRequest<Node>(pair.first));
return new InterfaceHandle<T>(pair.second);
}
Future<void> close() async {
await _proxy.close();
}
}