mirror of
https://github.com/flutter/flutter
synced 2024-08-24 18:36:03 +00:00
Show Mac Designed For iPad in 'flutter devices' (#141718)
Addresses https://github.com/flutter/flutter/issues/141290 by allow Mac Designed For IPad Devices to appear with 'flutter devices'. <img width="573" alt="Screenshot 2024-01-29 at 12 23 24â¯AM" src="https://github.com/flutter/flutter/assets/36148254/35709a93-56fc-44c9-98d5-cf45afce967d"> <img width="725" alt="Screenshot 2024-01-29 at 12 26 01â¯AM" src="https://github.com/flutter/flutter/assets/36148254/b6cbcfce-44db-42c6-ac01-0ab716d30373">
This commit is contained in:
parent
071830663a
commit
42317804ee
|
@ -213,9 +213,6 @@ known, it can be explicitly provided to attach via the command-line, e.g.
|
|||
|
||||
@override
|
||||
Future<void> validateCommand() async {
|
||||
// ARM macOS as an iOS target is hidden, except for attach.
|
||||
MacOSDesignedForIPadDevices.allowDiscovery = true;
|
||||
|
||||
await super.validateCommand();
|
||||
|
||||
final Device? targetDevice = await findTargetDevice();
|
||||
|
|
|
@ -25,6 +25,7 @@ import '../drive/drive_service.dart';
|
|||
import '../drive/web_driver_service.dart' show Browser;
|
||||
import '../globals.dart' as globals;
|
||||
import '../ios/devices.dart';
|
||||
import '../macos/macos_ipad_device.dart';
|
||||
import '../resident_runner.dart';
|
||||
import '../runner/flutter_command.dart' show FlutterCommandCategory, FlutterCommandResult, FlutterOptions;
|
||||
import '../web/web_device.dart';
|
||||
|
@ -222,6 +223,9 @@ class DriveCommand extends RunCommandBase {
|
|||
if (device is! AndroidDevice) {
|
||||
throwToolExit('--${FlutterOptions.kDeviceUser} is only supported for Android');
|
||||
}
|
||||
if (device is MacOSDesignedForIPadDevice) {
|
||||
throwToolExit('Mac Designed for iPad is currently not supported for flutter drive.');
|
||||
}
|
||||
}
|
||||
return super.validateCommand();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import '../device.dart';
|
|||
import '../features.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../ios/devices.dart';
|
||||
import '../macos/macos_ipad_device.dart';
|
||||
import '../project.dart';
|
||||
import '../reporting/reporting.dart';
|
||||
import '../resident_runner.dart';
|
||||
|
@ -591,6 +592,15 @@ class RunCommand extends RunCommandBase {
|
|||
if (devices == null) {
|
||||
throwToolExit(null);
|
||||
}
|
||||
|
||||
if (devices!.length == 1 && devices!.first is MacOSDesignedForIPadDevice) {
|
||||
throwToolExit('Mac Designed for iPad is currently not supported for flutter run -d.');
|
||||
}
|
||||
|
||||
if (globals.deviceManager!.hasSpecifiedAllDevices) {
|
||||
devices?.removeWhere((Device device) => device is MacOSDesignedForIPadDevice);
|
||||
}
|
||||
|
||||
if (globals.deviceManager!.hasSpecifiedAllDevices && runningWithPrebuiltApplication) {
|
||||
throwToolExit('Using "-d all" with "--${FlutterOptions.kUseApplicationBinary}" is not supported');
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ class MacOSDesignedForIPadDevice extends DesktopDevice {
|
|||
required OperatingSystemUtils operatingSystemUtils,
|
||||
}) : _operatingSystemUtils = operatingSystemUtils,
|
||||
super(
|
||||
'designed-for-ipad',
|
||||
'mac-designed-for-ipad',
|
||||
platformType: PlatformType.macos,
|
||||
ephemeral: false,
|
||||
processManager: processManager,
|
||||
|
@ -120,10 +120,7 @@ class MacOSDesignedForIPadDevices extends PollingDeviceDiscovery {
|
|||
/// and discovery is allowed for this command.
|
||||
@override
|
||||
bool get canListAnything =>
|
||||
_iosWorkflow.canListDevices && _operatingSystemUtils.hostPlatform == HostPlatform.darwin_arm64 && allowDiscovery;
|
||||
|
||||
/// Set to show ARM macOS as an iOS device target.
|
||||
static bool allowDiscovery = false;
|
||||
_iosWorkflow.canListDevices && _operatingSystemUtils.hostPlatform == HostPlatform.darwin_arm64;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices({Duration? timeout}) async {
|
||||
|
@ -144,5 +141,5 @@ class MacOSDesignedForIPadDevices extends PollingDeviceDiscovery {
|
|||
Future<List<String>> getDiagnostics() async => const <String>[];
|
||||
|
||||
@override
|
||||
List<String> get wellKnownIds => const <String>['designed-for-ipad'];
|
||||
List<String> get wellKnownIds => const <String>['mac-designed-for-ipad'];
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import 'package:flutter_tools/src/device.dart';
|
|||
import 'package:flutter_tools/src/device_port_forwarder.dart';
|
||||
import 'package:flutter_tools/src/ios/application_package.dart';
|
||||
import 'package:flutter_tools/src/ios/devices.dart';
|
||||
import 'package:flutter_tools/src/macos/macos_ipad_device.dart';
|
||||
import 'package:flutter_tools/src/mdns_discovery.dart';
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
|
@ -52,10 +51,6 @@ class FakeProcessInfo extends Fake implements ProcessInfo {
|
|||
}
|
||||
|
||||
void main() {
|
||||
tearDown(() {
|
||||
MacOSDesignedForIPadDevices.allowDiscovery = false;
|
||||
});
|
||||
|
||||
group('attach', () {
|
||||
late StreamLogger logger;
|
||||
late FileSystem testFileSystem;
|
||||
|
@ -1067,7 +1062,6 @@ void main() {
|
|||
expect(testLogger.statusText, containsIgnoringWhitespace('More than one device'));
|
||||
expect(testLogger.statusText, contains('xx1'));
|
||||
expect(testLogger.statusText, contains('yy2'));
|
||||
expect(MacOSDesignedForIPadDevices.allowDiscovery, isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => testFileSystem,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
|
|
|
@ -25,6 +25,7 @@ import 'package:flutter_tools/src/devfs.dart';
|
|||
import 'package:flutter_tools/src/device.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:flutter_tools/src/ios/devices.dart';
|
||||
import 'package:flutter_tools/src/macos/macos_ipad_device.dart';
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
import 'package:flutter_tools/src/resident_runner.dart';
|
||||
|
@ -242,6 +243,62 @@ void main() {
|
|||
Cache: () => Cache.test(processManager: FakeProcessManager.any()),
|
||||
});
|
||||
|
||||
testUsingContext('Using flutter run -d with MacOSDesignedForIPadDevices throws an error', () async {
|
||||
final RunCommand command = RunCommand();
|
||||
testDeviceManager.devices = <Device>[FakeMacDesignedForIpadDevice()];
|
||||
|
||||
await expectLater(
|
||||
() => createTestCommandRunner(command).run(<String>[
|
||||
'run',
|
||||
'-d',
|
||||
'mac-designed-for-ipad',
|
||||
]), throwsToolExit(message: 'Mac Designed for iPad is currently not supported for flutter run -d'));
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
DeviceManager: () => testDeviceManager,
|
||||
Stdio: () => FakeStdio(),
|
||||
Cache: () => Cache.test(processManager: FakeProcessManager.any()),
|
||||
});
|
||||
|
||||
testUsingContext('Using flutter run -d all with a single MacOSDesignedForIPadDevices throws a tool error', () async {
|
||||
final RunCommand command = RunCommand();
|
||||
testDeviceManager.devices = <Device>[FakeMacDesignedForIpadDevice()];
|
||||
|
||||
await expectLater(
|
||||
() => createTestCommandRunner(command).run(<String>[
|
||||
'run',
|
||||
'-d',
|
||||
'all',
|
||||
]), throwsToolExit(message: 'Mac Designed for iPad is currently not supported for flutter run -d'));
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
DeviceManager: () => testDeviceManager,
|
||||
Stdio: () => FakeStdio(),
|
||||
Cache: () => Cache.test(processManager: FakeProcessManager.any()),
|
||||
});
|
||||
|
||||
testUsingContext('Using flutter run -d all with MacOSDesignedForIPadDevices removes from device list, and attempts to launch', () async {
|
||||
final RunCommand command = TestRunCommandThatOnlyValidates();
|
||||
testDeviceManager.devices = <Device>[FakeMacDesignedForIpadDevice(), FakeDevice()];
|
||||
|
||||
await createTestCommandRunner(command).run(<String>[
|
||||
'run',
|
||||
'-d',
|
||||
'all',
|
||||
]);
|
||||
|
||||
expect(command.devices?.length, 1);
|
||||
expect(command.devices?.single.id, 'fake_device');
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
DeviceManager: () => testDeviceManager,
|
||||
Stdio: () => FakeStdio(),
|
||||
Cache: () => Cache.test(processManager: FakeProcessManager.any()),
|
||||
});
|
||||
|
||||
testUsingContext('exits and lists available devices when specified device not found', () async {
|
||||
final RunCommand command = RunCommand();
|
||||
final FakeDevice device = FakeDevice(isLocalEmulator: true);
|
||||
|
@ -1413,6 +1470,27 @@ class FakeDevice extends Fake implements Device {
|
|||
}
|
||||
}
|
||||
|
||||
class FakeMacDesignedForIpadDevice extends Fake implements MacOSDesignedForIPadDevice {
|
||||
|
||||
@override
|
||||
String get id => 'mac-designed-for-ipad';
|
||||
|
||||
@override
|
||||
bool get isConnected => true;
|
||||
|
||||
@override
|
||||
Future<TargetPlatform> get targetPlatform async => TargetPlatform.darwin;
|
||||
|
||||
@override
|
||||
DeviceConnectionInterface connectionInterface = DeviceConnectionInterface.attached;
|
||||
|
||||
@override
|
||||
bool isSupported() => true;
|
||||
|
||||
@override
|
||||
bool isSupportedForProject(FlutterProject project) => true;
|
||||
}
|
||||
|
||||
class FakeIOSDevice extends Fake implements IOSDevice {
|
||||
FakeIOSDevice({
|
||||
this.connectionInterface = DeviceConnectionInterface.attached,
|
||||
|
@ -1479,6 +1557,9 @@ class TestRunCommandThatOnlyValidates extends RunCommand {
|
|||
Future<FlutterCommandResult> runCommand() async {
|
||||
return FlutterCommandResult.success();
|
||||
}
|
||||
|
||||
@override
|
||||
bool get shouldRunPub => false;
|
||||
}
|
||||
|
||||
class FakeResidentRunner extends Fake implements ResidentRunner {
|
||||
|
|
|
@ -21,12 +21,7 @@ import '../../src/fakes.dart';
|
|||
|
||||
void main() {
|
||||
group('MacOSDesignedForIPadDevices', () {
|
||||
tearDown(() {
|
||||
MacOSDesignedForIPadDevices.allowDiscovery = false;
|
||||
});
|
||||
|
||||
testWithoutContext('does not support non-macOS platforms', () async {
|
||||
MacOSDesignedForIPadDevices.allowDiscovery = true;
|
||||
final MacOSDesignedForIPadDevices discoverer = MacOSDesignedForIPadDevices(
|
||||
platform: FakePlatform(operatingSystem: 'windows'),
|
||||
logger: BufferLogger.test(),
|
||||
|
@ -39,7 +34,7 @@ void main() {
|
|||
expect(discoverer.supportsPlatform, isFalse);
|
||||
});
|
||||
|
||||
testWithoutContext('discovery not allowed', () async {
|
||||
testWithoutContext('discovery is allowed', () async {
|
||||
final MacOSDesignedForIPadDevices discoverer = MacOSDesignedForIPadDevices(
|
||||
platform: FakePlatform(operatingSystem: 'macos'),
|
||||
logger: BufferLogger.test(),
|
||||
|
@ -51,11 +46,12 @@ void main() {
|
|||
expect(discoverer.supportsPlatform, isTrue);
|
||||
|
||||
final List<Device> devices = await discoverer.devices();
|
||||
expect(devices, isEmpty);
|
||||
expect(devices, isNotNull);
|
||||
expect(devices.first.id, 'mac-designed-for-ipad');
|
||||
expect(devices.first is MacOSDesignedForIPadDevice, true);
|
||||
});
|
||||
|
||||
testWithoutContext('no device on x86', () async {
|
||||
MacOSDesignedForIPadDevices.allowDiscovery = true;
|
||||
final MacOSDesignedForIPadDevices discoverer = MacOSDesignedForIPadDevices(
|
||||
platform: FakePlatform(operatingSystem: 'macos'),
|
||||
logger: BufferLogger.test(),
|
||||
|
@ -71,7 +67,6 @@ void main() {
|
|||
});
|
||||
|
||||
testWithoutContext('no device on when iOS development off', () async {
|
||||
MacOSDesignedForIPadDevices.allowDiscovery = true;
|
||||
final MacOSDesignedForIPadDevices discoverer = MacOSDesignedForIPadDevices(
|
||||
platform: FakePlatform(operatingSystem: 'macos'),
|
||||
logger: BufferLogger.test(),
|
||||
|
@ -87,7 +82,6 @@ void main() {
|
|||
});
|
||||
|
||||
testWithoutContext('device discovery on arm', () async {
|
||||
MacOSDesignedForIPadDevices.allowDiscovery = true;
|
||||
final MacOSDesignedForIPadDevices discoverer = MacOSDesignedForIPadDevices(
|
||||
platform: FakePlatform(operatingSystem: 'macos'),
|
||||
logger: BufferLogger.test(),
|
||||
|
@ -103,7 +97,7 @@ void main() {
|
|||
|
||||
final Device device = devices.single;
|
||||
expect(device, isA<MacOSDesignedForIPadDevice>());
|
||||
expect(device.id, 'designed-for-ipad');
|
||||
expect(device.id, 'mac-designed-for-ipad');
|
||||
|
||||
// Timeout ignored.
|
||||
devices = await discoverer.discoverDevices(timeout: const Duration(seconds: 10));
|
||||
|
@ -118,7 +112,7 @@ void main() {
|
|||
fileSystem: MemoryFileSystem.test(),
|
||||
operatingSystemUtils: FakeOperatingSystemUtils(hostPlatform: HostPlatform.darwin_arm64),
|
||||
);
|
||||
expect(device.id, 'designed-for-ipad');
|
||||
expect(device.id, 'mac-designed-for-ipad');
|
||||
expect(await device.isLocalEmulator, isFalse);
|
||||
expect(device.name, 'Mac Designed for iPad');
|
||||
expect(device.portForwarder, isNot(isNull));
|
||||
|
|
Loading…
Reference in a new issue