macos_device.dart 4.47 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
import 'package:process/process.dart';
6

7
import '../base/file_system.dart';
8
import '../base/io.dart';
9
import '../base/logger.dart';
10
import '../base/os.dart';
11
import '../base/platform.dart';
12
import '../build_info.dart';
13
import '../desktop_device.dart';
14
import '../device.dart';
15
import '../macos/application_package.dart';
16 17
import '../project.dart';
import 'build_macos.dart';
18 19 20
import 'macos_workflow.dart';

/// A device that represents a desktop MacOS target.
21
class MacOSDevice extends DesktopDevice {
22
  MacOSDevice({
23 24 25 26
    required ProcessManager processManager,
    required Logger logger,
    required FileSystem fileSystem,
    required OperatingSystemUtils operatingSystemUtils,
27 28
  }) : _processManager = processManager,
       _logger = logger,
29
       _operatingSystemUtils = operatingSystemUtils,
30 31 32 33 34 35
       super(
        'macos',
        platformType: PlatformType.macos,
        ephemeral: false,
        processManager: processManager,
        logger: logger,
36 37
        fileSystem: fileSystem,
        operatingSystemUtils: operatingSystemUtils,
38 39 40 41
      );

  final ProcessManager _processManager;
  final Logger _logger;
42
  final OperatingSystemUtils _operatingSystemUtils;
43 44 45 46 47

  @override
  bool isSupported() => true;

  @override
48
  String get name => 'macOS';
49 50

  @override
51
  Future<TargetPlatform> get targetPlatform async => TargetPlatform.darwin;
52

53 54
  @override
  Future<String> get targetPlatformDisplayName async {
55
    if (_operatingSystemUtils.hostPlatform == HostPlatform.darwin_arm64) {
56
      return 'darwin-arm64';
57 58
    } else {
      return 'darwin-x64';
59 60 61
    }
  }

62
  @override
63 64 65
  bool isSupportedForProject(FlutterProject flutterProject) {
    return flutterProject.macos.existsSync();
  }
66 67

  @override
68
  Future<void> buildForDevice({
69 70
    required BuildInfo buildInfo,
    String? mainPath,
71
  }) async {
72 73 74 75
    await buildMacOS(
      flutterProject: FlutterProject.current(),
      buildInfo: buildInfo,
      targetOverride: mainPath,
76
      verboseLogging: _logger.isVerbose,
77
    );
78 79
  }

80
  @override
81 82
  String? executablePathForDevice(covariant MacOSApp package, BuildInfo buildInfo) {
    return package.executable(buildInfo);
83 84 85
  }

  @override
86
  void onAttached(covariant MacOSApp package, BuildInfo buildInfo, Process process) {
87 88
    // Bring app to foreground. Ideally this would be done post-launch rather
    // than post-attach, since this won't run for release builds, but there's
89
    // no general-purpose way of knowing when a process is far enough along in
90
    // the launch process for 'open' to foreground it.
91
    final String? applicationBundle = package.applicationBundle(buildInfo);
92 93 94 95
    if (applicationBundle == null) {
      _logger.printError('Failed to foreground app; application bundle not found');
      return;
    }
96
    _processManager.run(<String>[
97
      'open', applicationBundle,
98 99
    ]).then((ProcessResult result) {
      if (result.exitCode != 0) {
100
        _logger.printError('Failed to foreground app; open returned ${result.exitCode}');
101 102
      }
    });
103
  }
104 105 106
}

class MacOSDevices extends PollingDeviceDiscovery {
107
  MacOSDevices({
108 109 110 111 112 113
    required Platform platform,
    required MacOSWorkflow macOSWorkflow,
    required ProcessManager processManager,
    required Logger logger,
    required FileSystem fileSystem,
    required OperatingSystemUtils operatingSystemUtils,
114 115 116 117
  }) : _logger = logger,
       _platform = platform,
       _macOSWorkflow = macOSWorkflow,
       _processManager = processManager,
118 119
       _fileSystem = fileSystem,
       _operatingSystemUtils = operatingSystemUtils,
120 121 122 123 124 125
       super('macOS devices');

  final MacOSWorkflow _macOSWorkflow;
  final Platform _platform;
  final ProcessManager _processManager;
  final Logger _logger;
126
  final FileSystem _fileSystem;
127
  final OperatingSystemUtils _operatingSystemUtils;
128 129

  @override
130
  bool get supportsPlatform => _platform.isMacOS;
131 132

  @override
133
  bool get canListAnything => _macOSWorkflow.canListDevices;
134 135

  @override
136
  Future<List<Device>> pollingGetDevices({ Duration? timeout }) async {
137 138 139 140
    if (!canListAnything) {
      return const <Device>[];
    }
    return <Device>[
141 142 143 144
      MacOSDevice(
        processManager: _processManager,
        logger: _logger,
        fileSystem: _fileSystem,
145
        operatingSystemUtils: _operatingSystemUtils,
146
      ),
147 148 149 150 151
    ];
  }

  @override
  Future<List<String>> getDiagnostics() async => const <String>[];
152 153 154

  @override
  List<String> get wellKnownIds => const <String>['macos'];
155
}