Send analytics on 'build ios' and 'build ipa' for plist impeller value (#135193)
This analytics event only records the value of the plist entry on `build` commands. This will give an idea of the proportion of users who are disabling Impeller when shipping apps.
This commit is contained in:
parent
c627dbfbc6
commit
30a9f99bc8
@ -20,6 +20,7 @@ import '../globals.dart' as globals;
|
||||
import '../ios/application_package.dart';
|
||||
import '../ios/mac.dart';
|
||||
import '../ios/plist_parser.dart';
|
||||
import '../reporting/reporting.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
import 'build.dart';
|
||||
|
||||
@ -724,6 +725,21 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand {
|
||||
if (result.output != null) {
|
||||
globals.printStatus('Built ${result.output}.');
|
||||
|
||||
// When an app is successfully built, record to analytics whether Impeller
|
||||
// is enabled or disabled.
|
||||
final BuildableIOSApp app = await buildableIOSApp;
|
||||
final String plistPath = app.project.infoPlist.path;
|
||||
final bool? impellerEnabled = globals.plistParser.getValueFromFile<bool>(
|
||||
plistPath, PlistParser.kFLTEnableImpellerKey,
|
||||
);
|
||||
BuildEvent(
|
||||
impellerEnabled == false
|
||||
? 'plist-impeller-disabled'
|
||||
: 'plist-impeller-enabled',
|
||||
type: 'ios',
|
||||
flutterUsage: globals.flutterUsage,
|
||||
).send();
|
||||
|
||||
return FlutterCommandResult.success();
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ class PlistParser {
|
||||
static const String kCFBundleVersionKey = 'CFBundleVersion';
|
||||
static const String kCFBundleDisplayNameKey = 'CFBundleDisplayName';
|
||||
static const String kCFBundleNameKey = 'CFBundleName';
|
||||
static const String kFLTEnableImpellerKey = 'FLTEnableImpeller';
|
||||
static const String kMinimumOSVersionKey = 'MinimumOSVersion';
|
||||
static const String kNSPrincipalClassKey = 'NSPrincipalClass';
|
||||
|
||||
|
@ -17,7 +17,9 @@ import 'package:flutter_tools/src/commands/build.dart';
|
||||
import 'package:flutter_tools/src/commands/build_ios.dart';
|
||||
import 'package:flutter_tools/src/ios/code_signing.dart';
|
||||
import 'package:flutter_tools/src/ios/mac.dart';
|
||||
import 'package:flutter_tools/src/ios/plist_parser.dart';
|
||||
import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
import 'package:test/fake.dart';
|
||||
|
||||
@ -438,6 +440,133 @@ void main() {
|
||||
Usage: () => usage,
|
||||
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
|
||||
});
|
||||
|
||||
group('Analytics for impeller plist setting', () {
|
||||
const String plistContents = '''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>FLTEnableImpeller</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
''';
|
||||
const FakeCommand plutilCommand = FakeCommand(
|
||||
command: <String>[
|
||||
'/usr/bin/plutil', '-convert', 'xml1', '-o', '-', '/ios/Runner/Info.plist',
|
||||
],
|
||||
stdout: plistContents,
|
||||
);
|
||||
|
||||
testUsingContext('Sends an analytics event when Impeller is enabled', () async {
|
||||
final BuildCommand command = BuildCommand(
|
||||
androidSdk: FakeAndroidSdk(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
fileSystem: MemoryFileSystem.test(),
|
||||
logger: BufferLogger.test(),
|
||||
osUtils: FakeOperatingSystemUtils(),
|
||||
);
|
||||
createMinimalMockProjectFiles();
|
||||
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>['build', 'ios', '--no-pub']
|
||||
);
|
||||
|
||||
expect(usage.events, contains(
|
||||
const TestUsageEvent(
|
||||
'build', 'ios',
|
||||
label:'plist-impeller-enabled',
|
||||
parameters:CustomDimensions(),
|
||||
),
|
||||
));
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
|
||||
xattrCommand,
|
||||
setUpFakeXcodeBuildHandler(onRun: () {
|
||||
fileSystem.directory('build/ios/Release-iphoneos/Runner.app')
|
||||
.createSync(recursive: true);
|
||||
}),
|
||||
setUpRsyncCommand(onRun: () =>
|
||||
fileSystem.file('build/ios/iphoneos/Runner.app/Frameworks/App.framework/App')
|
||||
..createSync(recursive: true)
|
||||
..writeAsBytesSync(List<int>.generate(10000, (int index) => 0))),
|
||||
]),
|
||||
Platform: () => macosPlatform,
|
||||
FileSystemUtils: () => FileSystemUtils(
|
||||
fileSystem: fileSystem,
|
||||
platform: macosPlatform,
|
||||
),
|
||||
Usage: () => usage,
|
||||
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
|
||||
});
|
||||
|
||||
testUsingContext('Sends an analytics event when Impeller is disabled', () async {
|
||||
final BuildCommand command = BuildCommand(
|
||||
androidSdk: FakeAndroidSdk(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
fileSystem: fileSystem,
|
||||
logger: BufferLogger.test(),
|
||||
osUtils: FakeOperatingSystemUtils(),
|
||||
);
|
||||
createMinimalMockProjectFiles();
|
||||
|
||||
fileSystem.file(
|
||||
fileSystem.path.join('usr', 'bin', 'plutil'),
|
||||
).createSync(recursive: true);
|
||||
|
||||
final File infoPlist = fileSystem.file(fileSystem.path.join(
|
||||
'ios', 'Runner', 'Info.plist',
|
||||
))..createSync(recursive: true);
|
||||
|
||||
infoPlist.writeAsStringSync(plistContents);
|
||||
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>['build', 'ios', '--no-pub']
|
||||
);
|
||||
|
||||
expect(usage.events, contains(
|
||||
const TestUsageEvent(
|
||||
'build', 'ios',
|
||||
label:'plist-impeller-disabled',
|
||||
parameters:CustomDimensions(),
|
||||
),
|
||||
));
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
|
||||
xattrCommand,
|
||||
setUpFakeXcodeBuildHandler(onRun: () {
|
||||
fileSystem.directory('build/ios/Release-iphoneos/Runner.app')
|
||||
.createSync(recursive: true);
|
||||
}),
|
||||
setUpRsyncCommand(onRun: () =>
|
||||
fileSystem.file('build/ios/iphoneos/Runner.app/Frameworks/App.framework/App')
|
||||
..createSync(recursive: true)
|
||||
..writeAsBytesSync(List<int>.generate(10000, (int index) => 0))),
|
||||
]),
|
||||
Platform: () => macosPlatform,
|
||||
FileSystemUtils: () => FileSystemUtils(
|
||||
fileSystem: fileSystem,
|
||||
platform: macosPlatform,
|
||||
),
|
||||
Usage: () => usage,
|
||||
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
|
||||
FlutterProjectFactory: () => FlutterProjectFactory(
|
||||
fileSystem: fileSystem,
|
||||
logger: BufferLogger.test(),
|
||||
),
|
||||
PlistParser: () => PlistParser(
|
||||
fileSystem: fileSystem,
|
||||
logger: BufferLogger.test(),
|
||||
processManager: FakeProcessManager.list(<FakeCommand>[
|
||||
plutilCommand, plutilCommand, plutilCommand,
|
||||
]),
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
group('xcresults device', () {
|
||||
testUsingContext('Trace error if xcresult is empty.', () async {
|
||||
final BuildCommand command = BuildCommand(
|
||||
|
@ -63,7 +63,8 @@ class FakePlistUtils extends Fake implements PlistParser {
|
||||
|
||||
@override
|
||||
T? getValueFromFile<T>(String plistFilePath, String key) {
|
||||
return fileContents[plistFilePath]![key] as T?;
|
||||
final Map<String, Object>? plistFile = fileContents[plistFilePath];
|
||||
return plistFile == null ? null : plistFile[key] as T?;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user