• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'package:meta/meta.dart';
6
7import '../application_package.dart';
8import '../base/file_system.dart';
9import '../base/io.dart';
10import '../base/platform.dart';
11import '../base/process_manager.dart';
12import '../build_info.dart';
13import '../device.dart';
14import '../features.dart';
15import '../project.dart';
16import 'chrome.dart';
17import 'workflow.dart';
18
19class WebApplicationPackage extends ApplicationPackage {
20  WebApplicationPackage(this.flutterProject) : super(id: flutterProject.manifest.appName);
21
22  final FlutterProject flutterProject;
23
24  @override
25  String get name => flutterProject.manifest.appName;
26
27  /// The location of the web source assets.
28  Directory get webSourcePath => flutterProject.directory.childDirectory('web');
29}
30
31class ChromeDevice extends Device {
32  ChromeDevice() : super(
33      'chrome',
34      category: Category.web,
35      platformType: PlatformType.web,
36      ephemeral: false,
37  );
38
39  // TODO(jonahwilliams): this is technically false, but requires some refactoring
40  // to allow hot mode restart only devices.
41  @override
42  bool get supportsHotReload => true;
43
44  @override
45  bool get supportsHotRestart => true;
46
47  @override
48  bool get supportsStartPaused => true;
49
50  @override
51  bool get supportsFlutterExit => true;
52
53  @override
54  bool get supportsScreenshot => false;
55
56  @override
57  void clearLogs() { }
58
59  @override
60  DeviceLogReader getLogReader({ApplicationPackage app}) {
61    return NoOpDeviceLogReader(app.name);
62  }
63
64  @override
65  Future<bool> installApp(ApplicationPackage app) async => true;
66
67  @override
68  Future<bool> isAppInstalled(ApplicationPackage app) async => true;
69
70  @override
71  Future<bool> isLatestBuildInstalled(ApplicationPackage app) async => true;
72
73  @override
74  Future<bool> get isLocalEmulator async => false;
75
76  @override
77  Future<String> get emulatorId async => null;
78
79  @override
80  bool isSupported() =>  featureFlags.isWebEnabled && canFindChrome();
81
82  @override
83  String get name => 'Chrome';
84
85  @override
86  DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder();
87
88  @override
89  Future<String> get sdkNameAndVersion async {
90    if (!isSupported()) {
91      return 'unknown';
92    }
93    // See https://bugs.chromium.org/p/chromium/issues/detail?id=158372
94    String version = 'unknown';
95    if (platform.isWindows) {
96      final ProcessResult result = await processManager.run(<String>[
97        r'reg', 'query', 'HKEY_CURRENT_USER\\Software\\Google\\Chrome\\BLBeacon', '/v', 'version'
98      ]);
99      if (result.exitCode == 0) {
100        final List<String> parts = result.stdout.split(RegExp(r'\s+'));
101        if (parts.length > 2) {
102          version = 'Google Chrome ' + parts[parts.length - 2];
103        }
104      }
105    } else {
106      final String chrome = findChromeExecutable();
107      final ProcessResult result = await processManager.run(<String>[
108        chrome,
109        '--version',
110      ]);
111      if (result.exitCode == 0) {
112        version = result.stdout;
113      }
114    }
115    return version;
116  }
117
118  @override
119  Future<LaunchResult> startApp(
120    covariant WebApplicationPackage package, {
121    String mainPath,
122    String route,
123    DebuggingOptions debuggingOptions,
124    Map<String, Object> platformArgs,
125    bool prebuiltApplication = false,
126    bool usesTerminalUi = true,
127    bool ipv6 = false,
128  }) async {
129    // See [ResidentWebRunner.run] in flutter_tools/lib/src/resident_web_runner.dart
130    // for the web initialization and server logic.
131    return LaunchResult.succeeded(observatoryUri: null);
132  }
133
134  @override
135  Future<bool> stopApp(ApplicationPackage app) async {
136    return true;
137  }
138
139  @override
140  Future<TargetPlatform> get targetPlatform async => TargetPlatform.web_javascript;
141
142  @override
143  Future<bool> uninstallApp(ApplicationPackage app) async => true;
144
145  @override
146  bool isSupportedForProject(FlutterProject flutterProject) {
147    return flutterProject.web.existsSync();
148  }
149}
150
151class WebDevices extends PollingDeviceDiscovery {
152  WebDevices() : super('chrome');
153
154  final ChromeDevice _webDevice = ChromeDevice();
155
156  @override
157  bool get canListAnything => featureFlags.isWebEnabled;
158
159  @override
160  Future<List<Device>> pollingGetDevices() async {
161    return <Device>[
162      _webDevice,
163    ];
164  }
165
166  @override
167  bool get supportsPlatform =>  featureFlags.isWebEnabled;
168}
169
170@visibleForTesting
171String parseVersionForWindows(String input) {
172  return input.split(RegExp('\w')).last;
173}
174