Only set `flutter run` usage values for targeted device platforms (#46931)
diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index f854a92..811761e 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -228,30 +228,55 @@ Future<Map<CustomDimensions, String>> get usageValues async { String deviceType, deviceOsVersion; bool isEmulator; + bool anyAndroidDevices = false; + bool anyIOSDevices = false; if (devices == null || devices.isEmpty) { deviceType = 'none'; deviceOsVersion = 'none'; isEmulator = false; } else if (devices.length == 1) { - deviceType = getNameForTargetPlatform(await devices[0].targetPlatform); + final TargetPlatform platform = await devices[0].targetPlatform; + anyAndroidDevices = platform == TargetPlatform.android; + anyIOSDevices = platform == TargetPlatform.ios; + deviceType = getNameForTargetPlatform(platform); deviceOsVersion = await devices[0].sdkNameAndVersion; isEmulator = await devices[0].isLocalEmulator; } else { deviceType = 'multiple'; deviceOsVersion = 'multiple'; isEmulator = false; + for (Device device in devices) { + final TargetPlatform platform = await device.targetPlatform; + anyAndroidDevices = anyAndroidDevices || (platform == TargetPlatform.android); + anyIOSDevices = anyIOSDevices || (platform == TargetPlatform.ios); + if (anyAndroidDevices && anyIOSDevices) { + break; + } + } } - final String modeName = getBuildInfo().modeName; - final AndroidProject androidProject = FlutterProject.current().android; - final IosProject iosProject = FlutterProject.current().ios; - final List<String> hostLanguage = <String>[ - if (androidProject != null && androidProject.existsSync()) - if (androidProject.isKotlin) 'kotlin' else 'java', - if (iosProject != null && iosProject.exists) - if (await iosProject.isSwift) 'swift' else 'objc', - ]; + String androidEmbeddingVersion; + final List<String> hostLanguage = <String>[]; + if (anyAndroidDevices) { + final AndroidProject androidProject = FlutterProject.current().android; + if (androidProject != null && androidProject.existsSync()) { + hostLanguage.add(androidProject.isKotlin ? 'kotlin' : 'java'); + androidEmbeddingVersion = androidProject.getEmbeddingVersion().toString().split('.').last; + } + } + if (anyIOSDevices) { + final IosProject iosProject = FlutterProject.current().ios; + if (iosProject != null && iosProject.exists) { + final Iterable<File> swiftFiles = iosProject.hostAppRoot + .listSync(recursive: true, followLinks: false) + .whereType<File>() + .where((File file) => fs.path.extension(file.path) == '.swift'); + hostLanguage.add(swiftFiles.isNotEmpty ? 'swift' : 'objc'); + } + } + + final String modeName = getBuildInfo().modeName; return <CustomDimensions, String>{ CustomDimensions.commandRunIsEmulator: '$isEmulator', CustomDimensions.commandRunTargetName: deviceType, @@ -259,7 +284,8 @@ CustomDimensions.commandRunModeName: modeName, CustomDimensions.commandRunProjectModule: '${FlutterProject.current().isModule}', CustomDimensions.commandRunProjectHostLanguage: hostLanguage.join(','), - CustomDimensions.commandRunAndroidEmbeddingVersion: androidProject.getEmbeddingVersion().toString().split('.').last, + if (androidEmbeddingVersion != null) + CustomDimensions.commandRunAndroidEmbeddingVersion: androidEmbeddingVersion, }; }
diff --git a/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart b/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart index 01856b7..5c673d6 100644 --- a/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart +++ b/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart
@@ -36,7 +36,6 @@ final bool didPodInstall = await cocoaPods.processPods( xcodeProject: xcodeProject, engineDir: flutterFrameworkDir(buildMode), - isSwift: await xcodeProject.isSwift, dependenciesChanged: !fingerprinter.doesFingerprintMatch(), ); if (didPodInstall) {
diff --git a/packages/flutter_tools/lib/src/macos/cocoapods.dart b/packages/flutter_tools/lib/src/macos/cocoapods.dart index 8fb1dd6..ca29dee 100644 --- a/packages/flutter_tools/lib/src/macos/cocoapods.dart +++ b/packages/flutter_tools/lib/src/macos/cocoapods.dart
@@ -138,7 +138,6 @@ @required XcodeBasedProject xcodeProject, // For backward compatibility with previously created Podfile only. @required String engineDir, - bool isSwift = false, bool dependenciesChanged = true, }) async { if (!xcodeProject.podfile.existsSync()) {
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index bc9dba0..2671a03 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart
@@ -292,9 +292,6 @@ /// The CocoaPods 'Manifest.lock'. File get podManifestLock; - /// True if the host app project is using Swift. - Future<bool> get isSwift; - /// Directory containing symlinks to pub cache plugins source generated on `pod install`. Directory get symlinks; } @@ -410,10 +407,6 @@ return null; } - @override - Future<bool> get isSwift async => - (await buildSettings)?.containsKey('SWIFT_VERSION') ?? false; - /// The build settings for the host app of this project, as a detached map. /// /// Returns null, if iOS tooling is unavailable. @@ -820,9 +813,6 @@ @override Directory get symlinks => ephemeralDirectory.childDirectory('.symlinks'); - @override - Future<bool> get isSwift async => true; - /// The file where the Xcode build will write the name of the built app. /// /// Ideally this will be replaced in the future with inspection of the Runner
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart index 83d98db..9fb909c 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart
@@ -237,6 +237,7 @@ when(mockDevice.isLocalEmulator).thenAnswer((Invocation invocation) => Future<bool>.value(false)); when(mockDevice.getLogReader(app: anyNamed('app'))).thenReturn(MockDeviceLogReader()); when(mockDevice.supportsFastStart).thenReturn(true); + when(mockDevice.sdkNameAndVersion).thenAnswer((Invocation invocation) => Future<String>.value('iOS 13')); // App fails to start because we're only interested in usage when(mockDevice.startApp( any, @@ -262,6 +263,15 @@ (Invocation invocation) => Future<List<Device>>.value(<Device>[mockDevice]) ); + final Directory tempDir = fs.systemTempDirectory.createTempSync('flutter_run_test.'); + tempDir.childDirectory('ios').childFile('AppDelegate.swift').createSync(recursive: true); + tempDir.childFile('.packages').createSync(); + tempDir.childDirectory('lib').childFile('main.dart').createSync(recursive: true); + tempDir.childFile('pubspec.yaml') + ..createSync() + ..writeAsStringSync('# Hello, World'); + fs.currentDirectory = tempDir; + try { await createTestCommandRunner(command).run(<String>[ 'run', @@ -281,7 +291,14 @@ )).captured; expect(captures[0], 'run'); final Map<String, String> parameters = captures[1] as Map<String, String>; - expect(parameters['cd4'], 'ios'); + + expect(parameters[cdKey(CustomDimensions.commandRunIsEmulator)], 'false'); + expect(parameters[cdKey(CustomDimensions.commandRunTargetName)], 'ios'); + expect(parameters[cdKey(CustomDimensions.commandRunProjectHostLanguage)], 'swift'); + expect(parameters[cdKey(CustomDimensions.commandRunTargetOsVersion)], 'iOS 13'); + expect(parameters[cdKey(CustomDimensions.commandRunModeName)], 'debug'); + expect(parameters[cdKey(CustomDimensions.commandRunProjectModule)], 'false'); + expect(parameters.containsKey(cdKey(CustomDimensions.commandRunAndroidEmbeddingVersion)), false); }, overrides: <Type, Generator>{ ApplicationPackageFactory: () => mockApplicationPackageFactory, Artifacts: () => mockArtifacts,
diff --git a/packages/flutter_tools/test/general.shard/project_test.dart b/packages/flutter_tools/test/general.shard/project_test.dart index 845af31..c5b6805 100644 --- a/packages/flutter_tools/test/general.shard/project_test.dart +++ b/packages/flutter_tools/test/general.shard/project_test.dart
@@ -304,19 +304,12 @@ testInMemory('default host app language', () async { final FlutterProject project = await someProject(); - expect(await project.ios.isSwift, isFalse); expect(project.android.isKotlin, isFalse); }); - testUsingContext('swift and kotlin host app language', () async { + testUsingContext('kotlin host app language', () async { final FlutterProject project = await someProject(); - when(mockXcodeProjectInterpreter.getBuildSettings(any, any)).thenAnswer( - (_) { - return Future<Map<String, String>>.value(<String, String>{ - 'SWIFT_VERSION': '5.0', - }); - }); addAndroidGradleFile(project.directory, gradleFileContent: () { return ''' @@ -324,7 +317,6 @@ apply plugin: 'kotlin-android' '''; }); - expect(await project.ios.isSwift, isTrue); expect(project.android.isKotlin, isTrue); }, overrides: <Type, Generator>{ FileSystem: () => fs,