| // 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 'package:fidl_fuchsia_cobalt/fidl_async.dart' as cobalt; |
| import 'package:fidl_fuchsia_mem/fidl_async.dart'; |
| import 'package:fidl_fuchsia_netstack/fidl_async.dart'; |
| import 'package:flutter/material.dart'; |
| import 'package:fuchsia_logger/logger.dart'; |
| import 'package:fuchsia_services/services.dart'; |
| import 'package:lib.base_shell/base_shell_widget.dart'; |
| import 'package:lib.base_shell/netstack_model.dart'; |
| import 'package:lib.widgets/application.dart'; |
| import 'package:lib.widgets/model.dart'; |
| import 'package:meta/meta.dart'; |
| import 'package:zircon/zircon.dart'; |
| |
| import 'authentication_overlay.dart'; |
| import 'authentication_overlay_model.dart'; |
| import 'authentication_ui_context_impl.dart'; |
| import 'user_picker_base_shell_model.dart'; |
| import 'user_picker_base_shell_screen.dart'; |
| |
| const double _kMousePointerElevation = 800.0; |
| const double _kIndicatorElevation = _kMousePointerElevation - 1.0; |
| |
| const String _kCobaltConfigBinProtoPath = '/pkg/data/sysui_metrics_config.pb'; |
| |
| /// The main base shell widget. |
| BaseShellWidget<UserPickerBaseShellModel> _baseShellWidget; |
| |
| void main() { |
| setupLogger(name: 'userpicker_base_shell'); |
| StartupContext startupContext = new StartupContext.fromStartupInfo(); |
| |
| // Connect to Cobalt |
| cobalt.LoggerProxy logger = new cobalt.LoggerProxy(); |
| |
| cobalt.LoggerFactoryProxy loggerFactory = new cobalt.LoggerFactoryProxy(); |
| connectToEnvironmentService(loggerFactory); |
| |
| SizedVmo configVmo = SizedVmo.fromFile(_kCobaltConfigBinProtoPath); |
| cobalt.ProjectProfile profile = cobalt.ProjectProfile( |
| config: Buffer(vmo: configVmo, size: configVmo.size), |
| releaseStage: cobalt.ReleaseStage.ga); |
| loggerFactory |
| .createLogger(profile, logger.ctrl.request()) |
| .then((cobalt.Status s) { |
| if (s != cobalt.Status.ok) { |
| print('Failed to obtain Logger. Cobalt config is invalid.'); |
| } |
| }); |
| loggerFactory.ctrl.close(); |
| |
| NetstackProxy netstackProxy = new NetstackProxy(); |
| connectToEnvironmentService(netstackProxy); |
| |
| NetstackModel netstackModel = new NetstackModel(netstack: netstackProxy) |
| ..start(); |
| |
| _OverlayModel wifiInfoOverlayModel = new _OverlayModel(); |
| |
| final AuthenticationOverlayModel authModel = AuthenticationOverlayModel(); |
| |
| UserPickerBaseShellModel userPickerBaseShellModel = |
| new UserPickerBaseShellModel( |
| onBaseShellStopped: () { |
| netstackProxy.ctrl.close(); |
| netstackModel.dispose(); |
| }, |
| onLogin: () { |
| wifiInfoOverlayModel.showing = false; |
| }, |
| onWifiTapped: () { |
| wifiInfoOverlayModel.showing = !wifiInfoOverlayModel.showing; |
| }, |
| logger: logger, |
| ); |
| |
| Widget mainWidget = new Stack( |
| fit: StackFit.passthrough, |
| children: <Widget>[ |
| new UserPickerBaseShellScreen( |
| launcher: startupContext.launcher, |
| ), |
| new ScopedModel<AuthenticationOverlayModel>( |
| model: authModel, |
| child: AuthenticationOverlay(), |
| ), |
| ], |
| ); |
| |
| Widget app = mainWidget; |
| |
| List<OverlayEntry> overlays = <OverlayEntry>[ |
| new OverlayEntry( |
| builder: (BuildContext context) => new MediaQuery( |
| data: const MediaQueryData(), |
| child: new FocusScope( |
| node: new FocusScopeNode(), |
| autofocus: true, |
| child: app, |
| ), |
| ), |
| ), |
| new OverlayEntry( |
| builder: (BuildContext context) => new ScopedModel<_OverlayModel>( |
| model: wifiInfoOverlayModel, |
| child: new _WifiInfo( |
| wifiWidget: new ApplicationWidget( |
| url: |
| 'fuchsia-pkg://fuchsia.com/wifi_settings#meta/wifi_settings.cmx', |
| launcher: startupContext.launcher, |
| ), |
| ), |
| ), |
| ), |
| ]; |
| |
| _baseShellWidget = new BaseShellWidget<UserPickerBaseShellModel>( |
| startupContext: startupContext, |
| baseShellModel: userPickerBaseShellModel, |
| authenticationUiContext: new AuthenticationUiContextImpl( |
| onStartOverlay: authModel.onStartOverlay, |
| onStopOverlay: authModel.onStopOverlay), |
| child: new LayoutBuilder( |
| builder: (BuildContext context, BoxConstraints constraints) => |
| (constraints.biggest == Size.zero) |
| ? const Offstage() |
| : new ScopedModel<NetstackModel>( |
| model: netstackModel, |
| child: new Overlay(initialEntries: overlays), |
| ), |
| ), |
| ); |
| |
| runApp(_baseShellWidget); |
| |
| _baseShellWidget.advertise(); |
| } |
| |
| class _WifiInfo extends StatelessWidget { |
| final Widget wifiWidget; |
| |
| const _WifiInfo({@required this.wifiWidget}) : assert(wifiWidget != null); |
| |
| @override |
| Widget build(BuildContext context) => |
| new ScopedModelDescendant<_OverlayModel>( |
| builder: ( |
| BuildContext context, |
| Widget child, |
| _OverlayModel model, |
| ) => |
| new Offstage( |
| offstage: !model.showing, |
| child: new Stack( |
| children: <Widget>[ |
| new Listener( |
| behavior: HitTestBehavior.opaque, |
| onPointerDown: (PointerDownEvent event) { |
| model.showing = false; |
| }, |
| ), |
| new Center( |
| child: new FractionallySizedBox( |
| widthFactor: 0.75, |
| heightFactor: 0.75, |
| child: new Container( |
| margin: const EdgeInsets.all(8.0), |
| child: new PhysicalModel( |
| color: Colors.grey[900], |
| elevation: _kIndicatorElevation, |
| borderRadius: new BorderRadius.circular(8.0), |
| child: wifiWidget, |
| ), |
| ), |
| ), |
| ), |
| ], |
| ), |
| ), |
| ); |
| } |
| |
| class _OverlayModel extends Model { |
| bool _showing = false; |
| |
| set showing(bool showing) { |
| if (_showing != showing) { |
| _showing = showing; |
| notifyListeners(); |
| } |
| } |
| |
| bool get showing => _showing; |
| } |