Unverified Commit 6067571f authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] support flutter run -d edge (#56173)

Support Microsoft Edge as a device for flutter run when web is enabled. Currently this only works on Windows, and does not include a validator for edge.

Fixes #55322
parent e54f8f52
...@@ -11,6 +11,7 @@ import '../base/io.dart'; ...@@ -11,6 +11,7 @@ import '../base/io.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../base/os.dart'; import '../base/os.dart';
import '../base/platform.dart'; import '../base/platform.dart';
import '../base/version.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../device.dart'; import '../device.dart';
import '../features.dart'; import '../features.dart';
...@@ -232,24 +233,54 @@ class GoogleChromeDevice extends ChromiumDevice { ...@@ -232,24 +233,54 @@ class GoogleChromeDevice extends ChromiumDevice {
} }
/// The Microsoft Edge browser based on Chromium. /// The Microsoft Edge browser based on Chromium.
// This is not currently used, see https://github.com/flutter/flutter/issues/55322
class MicrosoftEdgeDevice extends ChromiumDevice { class MicrosoftEdgeDevice extends ChromiumDevice {
MicrosoftEdgeDevice({ MicrosoftEdgeDevice({
@required ChromiumLauncher chromiumLauncher, @required ChromiumLauncher chromiumLauncher,
@required Logger logger, @required Logger logger,
@required FileSystem fileSystem, @required FileSystem fileSystem,
}) : super( @required ProcessManager processManager,
}) : _processManager = processManager,
super(
name: 'edge', name: 'edge',
chromeLauncher: chromiumLauncher, chromeLauncher: chromiumLauncher,
logger: logger, logger: logger,
fileSystem: fileSystem, fileSystem: fileSystem,
); );
final ProcessManager _processManager;
// The first version of Edge with chromium support.
static const int _kFirstChromiumEdgeMajorVersion = 79;
@override @override
String get name => 'Edge'; String get name => 'Edge';
Future<bool> _meetsVersionConstraint() async {
final String rawVersion = (await sdkNameAndVersion).replaceFirst('Microsoft Edge ', '');
final Version version = Version.parse(rawVersion);
if (version == null) {
return false;
}
return version.major >= _kFirstChromiumEdgeMajorVersion;
}
@override @override
Future<String> get sdkNameAndVersion async => '<?>'; Future<String> get sdkNameAndVersion async => _sdkNameAndVersion ??= await _getSdkNameAndVersion();
String _sdkNameAndVersion;
Future<String> _getSdkNameAndVersion() async {
final ProcessResult result = await _processManager.run(<String>[
r'reg', 'query', r'HKEY_CURRENT_USER\Software\Microsoft\Edge\BLBeacon', '/v', 'version',
]);
if (result.exitCode == 0) {
final List<String> parts = (result.stdout as String).split(RegExp(r'\s+'));
if (parts.length > 2) {
return 'Microsoft Edge ' + parts[parts.length - 2];
}
}
// Return a non-null string so that the tool can validate the version
// does not meet the constraint above in _meetsVersionConstraint.
return '';
}
} }
class WebDevices extends PollingDeviceDiscovery { class WebDevices extends PollingDeviceDiscovery {
...@@ -281,6 +312,21 @@ class WebDevices extends PollingDeviceDiscovery { ...@@ -281,6 +312,21 @@ class WebDevices extends PollingDeviceDiscovery {
operatingSystemUtils: operatingSystemUtils, operatingSystemUtils: operatingSystemUtils,
), ),
); );
if (platform.isWindows) {
_edgeDevice = MicrosoftEdgeDevice(
chromiumLauncher: ChromiumLauncher(
browserFinder: findEdgeExecutable,
fileSystem: fileSystem,
logger: logger,
platform: platform,
processManager: processManager,
operatingSystemUtils: operatingSystemUtils,
),
processManager: processManager,
logger: logger,
fileSystem: fileSystem,
);
}
_webServerDevice = WebServerDevice( _webServerDevice = WebServerDevice(
logger: logger, logger: logger,
); );
...@@ -288,6 +334,7 @@ class WebDevices extends PollingDeviceDiscovery { ...@@ -288,6 +334,7 @@ class WebDevices extends PollingDeviceDiscovery {
GoogleChromeDevice _chromeDevice; GoogleChromeDevice _chromeDevice;
WebServerDevice _webServerDevice; WebServerDevice _webServerDevice;
MicrosoftEdgeDevice _edgeDevice;
final FeatureFlags _featureFlags; final FeatureFlags _featureFlags;
@override @override
...@@ -302,6 +349,8 @@ class WebDevices extends PollingDeviceDiscovery { ...@@ -302,6 +349,8 @@ class WebDevices extends PollingDeviceDiscovery {
_webServerDevice, _webServerDevice,
if (_chromeDevice.isSupported()) if (_chromeDevice.isSupported())
_chromeDevice, _chromeDevice,
if (await _edgeDevice?._meetsVersionConstraint() ?? false)
_edgeDevice,
]; ];
} }
......
...@@ -67,7 +67,6 @@ class ChromeValidator extends ChromiumValidator { ...@@ -67,7 +67,6 @@ class ChromeValidator extends ChromiumValidator {
} }
/// A validator that checks whethere Edge is installed and can run. /// A validator that checks whethere Edge is installed and can run.
// This is not currently used, see https://github.com/flutter/flutter/issues/55322
class EdgeValidator extends ChromiumValidator { class EdgeValidator extends ChromiumValidator {
const EdgeValidator({ const EdgeValidator({
@required Platform platform, @required Platform platform,
......
...@@ -63,6 +63,7 @@ void main() { ...@@ -63,6 +63,7 @@ void main() {
chromiumLauncher: null, chromiumLauncher: null,
fileSystem: MemoryFileSystem.test(), fileSystem: MemoryFileSystem.test(),
logger: BufferLogger.test(), logger: BufferLogger.test(),
processManager: FakeProcessManager.any(),
); );
expect(chromeDevice.name, 'Edge'); expect(chromeDevice.name, 'Edge');
...@@ -140,6 +141,24 @@ void main() { ...@@ -140,6 +141,24 @@ void main() {
isNot(contains(isA<GoogleChromeDevice>()))); isNot(contains(isA<GoogleChromeDevice>())));
}); });
testWithoutContext('Edge device is not listed when Edge cannot be run', () async {
final MockProcessManager processManager = MockProcessManager();
when(processManager.canRun(any)).thenReturn(false);
final WebDevices webDevices = WebDevices(
featureFlags: TestFeatureFlags(isWebEnabled: true),
fileSystem: MemoryFileSystem.test(),
logger: BufferLogger.test(),
platform: FakePlatform(
operatingSystem: 'linux',
environment: <String, String>{}
),
processManager: processManager,
);
expect(await webDevices.pollingGetDevices(),
isNot(contains(isA<MicrosoftEdgeDevice>())));
});
testWithoutContext('Web Server device is listed by default', () async { testWithoutContext('Web Server device is listed by default', () async {
final WebDevices webDevices = WebDevices( final WebDevices webDevices = WebDevices(
featureFlags: TestFeatureFlags(isWebEnabled: true), featureFlags: TestFeatureFlags(isWebEnabled: true),
...@@ -189,8 +208,18 @@ void main() { ...@@ -189,8 +208,18 @@ void main() {
expect(processManager.hasRemainingExpectations, false); expect(processManager.hasRemainingExpectations, false);
}); });
testWithoutContext('Chrome version check invokes registry query on windows.', () async { testWithoutContext('Chrome and Edge version check invokes registry query on windows.', () async {
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
const FakeCommand(
command: <String>[
'reg',
'query',
r'HKEY_CURRENT_USER\Software\Microsoft\Edge\BLBeacon',
'/v',
'version',
],
stdout: r'HKEY_CURRENT_USER\Software\Microsoft\Edge\BLBeacon\ version REG_SZ 83.0.478.44 ',
),
const FakeCommand( const FakeCommand(
command: <String>[ command: <String>[
'reg', 'reg',
...@@ -224,6 +253,61 @@ void main() { ...@@ -224,6 +253,61 @@ void main() {
expect(await chromeDevice.sdkNameAndVersion, 'Google Chrome 74.0.0'); expect(await chromeDevice.sdkNameAndVersion, 'Google Chrome 74.0.0');
expect(processManager.hasRemainingExpectations, false); expect(processManager.hasRemainingExpectations, false);
}); });
testWithoutContext('Edge is not supported on versions less than 73', () async {
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
const FakeCommand(
command: <String>[
'reg',
'query',
r'HKEY_CURRENT_USER\Software\Microsoft\Edge\BLBeacon',
'/v',
'version',
],
stdout: r'HKEY_CURRENT_USER\Software\Microsoft\Edge\BLBeacon\ version REG_SZ 72.0.478.44 ',
),
]);
final WebDevices webDevices = WebDevices(
featureFlags: TestFeatureFlags(isWebEnabled: true),
fileSystem: MemoryFileSystem.test(),
logger: BufferLogger.test(),
platform: FakePlatform(
operatingSystem: 'windows',
environment: <String, String>{}
),
processManager: processManager,
);
expect((await webDevices.pollingGetDevices()).whereType<MicrosoftEdgeDevice>(), isEmpty);
});
testWithoutContext('Edge is not support on non-windows platform', () async {
final WebDevices webDevices = WebDevices(
featureFlags: TestFeatureFlags(isWebEnabled: true),
fileSystem: MemoryFileSystem.test(),
logger: BufferLogger.test(),
platform: FakePlatform(
operatingSystem: 'linux',
environment: <String, String>{}
),
processManager: FakeProcessManager.list(<FakeCommand>[]),
);
expect((await webDevices.pollingGetDevices()).whereType<MicrosoftEdgeDevice>(), isEmpty);
final WebDevices macosWebDevices = WebDevices(
featureFlags: TestFeatureFlags(isWebEnabled: true),
fileSystem: MemoryFileSystem.test(),
logger: BufferLogger.test(),
platform: FakePlatform(
operatingSystem: 'macos',
environment: <String, String>{}
),
processManager: FakeProcessManager.list(<FakeCommand>[]),
);
expect((await macosWebDevices.pollingGetDevices()).whereType<MicrosoftEdgeDevice>(), isEmpty);
});
} }
// This is used to set `canRun` to false in a test. // This is used to set `canRun` to false in a test.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment