From c01cbd23cce18fac149ce8206516cde00e9d40b7 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 25 Mar 2022 17:50:09 -0700 Subject: [PATCH] Add `CADisableMinimumFrameDurationOnPhone` migration (#100647) --- packages/flutter_tools/lib/src/ios/mac.dart | 2 + .../minimum_frame_duration_migration.dart | 53 ++++++++++++ .../ios/ios_project_migration_test.dart | 83 +++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 packages/flutter_tools/lib/src/ios/migrations/minimum_frame_duration_migration.dart diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index b4092720670..567d5ed6d0d 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -25,6 +25,7 @@ import 'application_package.dart'; import 'code_signing.dart'; import 'iproxy.dart'; import 'migrations/deployment_target_migration.dart'; +import 'migrations/minimum_frame_duration_migration.dart'; import 'migrations/project_base_configuration_migration.dart'; import 'migrations/project_build_location_migration.dart'; import 'migrations/project_object_version_migration.dart'; @@ -123,6 +124,7 @@ Future buildXcodeProject({ ProjectBuildLocationMigration(app.project, globals.logger), DeploymentTargetMigration(app.project, globals.logger), ProjectObjectVersionMigration(app.project, globals.logger), + MinimumFrameDurationMigration(app.project, globals.logger), ]; final ProjectMigration migration = ProjectMigration(migrators); diff --git a/packages/flutter_tools/lib/src/ios/migrations/minimum_frame_duration_migration.dart b/packages/flutter_tools/lib/src/ios/migrations/minimum_frame_duration_migration.dart new file mode 100644 index 00000000000..04941a2efac --- /dev/null +++ b/packages/flutter_tools/lib/src/ios/migrations/minimum_frame_duration_migration.dart @@ -0,0 +1,53 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import '../../base/file_system.dart'; +import '../../base/logger.dart'; +import '../../base/project_migrator.dart'; +import '../../xcode_project.dart'; + +const String _kDisableMinimumFrameDurationKey = 'CADisableMinimumFrameDurationOnPhone'; + +/// Add "CADisableMinimumFrameDurationOnPhone: true" to the Info.plist. +class MinimumFrameDurationMigration extends ProjectMigrator { + MinimumFrameDurationMigration( + IosProject project, + Logger logger, + ) : _infoPlist = project.defaultHostInfoPlist, + super(logger); + + final File _infoPlist; + + @override + bool migrate() { + if (!_infoPlist.existsSync()) { + logger.printTrace('Info.plist not found, skipping minimum frame duration migration.'); + return true; + } + + processFileLines(_infoPlist); + return true; + } + + @override + String migrateFileContents(String fileContents) { + if (fileContents.contains(_kDisableMinimumFrameDurationKey)) { + // No migration needed if the key already exits. + return fileContents; + } + logger.printTrace('Adding $_kDisableMinimumFrameDurationKey to Info.plist'); + const String plistEnd = ''' + + +'''; + const String plistWithKey = ''' + $_kDisableMinimumFrameDurationKey + + + +'''; + + return fileContents.replaceAll(plistEnd, plistWithKey); + } +} diff --git a/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart b/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart index e44d65d06d5..41d1fe8638d 100644 --- a/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart @@ -7,6 +7,7 @@ import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/project_migrator.dart'; import 'package:flutter_tools/src/ios/migrations/deployment_target_migration.dart'; +import 'package:flutter_tools/src/ios/migrations/minimum_frame_duration_migration.dart'; import 'package:flutter_tools/src/ios/migrations/project_base_configuration_migration.dart'; import 'package:flutter_tools/src/ios/migrations/project_build_location_migration.dart'; import 'package:flutter_tools/src/ios/migrations/project_object_version_migration.dart'; @@ -708,6 +709,85 @@ keep this 3 expect('Updating project for Xcode compatibility'.allMatches(testLogger.statusText).length, 1); }); }); + + group('add CADisableMinimumFrameDurationOnPhone key to info.plist migration', () { + late MemoryFileSystem memoryFileSystem; + late BufferLogger testLogger; + late FakeIosProject project; + late File infoPlistFile; + + setUp(() { + memoryFileSystem = MemoryFileSystem(); + testLogger = BufferLogger.test(); + project = FakeIosProject(); + infoPlistFile = memoryFileSystem.file('info.plist'); + project.defaultHostInfoPlist = infoPlistFile; + }); + + testWithoutContext('skipped if files are missing', () { + final MinimumFrameDurationMigration iosProjectMigration = MinimumFrameDurationMigration( + project, + testLogger, + ); + expect(iosProjectMigration.migrate(), isTrue); + expect(infoPlistFile.existsSync(), isFalse); + + expect(testLogger.traceText, contains('Info.plist not found, skipping minimum frame duration migration.')); + expect(testLogger.statusText, isEmpty); + }); + + testWithoutContext('skipped if nothing to upgrade', () { + const String infoPlistFileContent = ''' + + + + + CADisableMinimumFrameDurationOnPhone + + + +'''; + infoPlistFile.writeAsStringSync(infoPlistFileContent); + + final MinimumFrameDurationMigration iosProjectMigration = MinimumFrameDurationMigration( + project, + testLogger, + ); + final DateTime infoPlistFileLastModified = infoPlistFile.lastModifiedSync(); + expect(iosProjectMigration.migrate(), isTrue); + + expect(infoPlistFile.lastModifiedSync(), infoPlistFileLastModified); + expect(testLogger.statusText, isEmpty); + }); + + testWithoutContext('info.plist is migrated to use CADisableMinimumFrameDurationOnPhone', () { + const String infoPlistFileContent = ''' + + + + + + +'''; + infoPlistFile.writeAsStringSync(infoPlistFileContent); + + final MinimumFrameDurationMigration iosProjectMigration = MinimumFrameDurationMigration( + project, + testLogger, + ); + expect(iosProjectMigration.migrate(), isTrue); + expect(infoPlistFile.readAsStringSync(), equals(''' + + + + + CADisableMinimumFrameDurationOnPhone + + + +''')); + }); + }); }); } @@ -726,6 +806,9 @@ class FakeIosProject extends Fake implements IosProject { @override File appFrameworkInfoPlist = MemoryFileSystem.test().file('appFrameworkInfoPlist'); + + @override + File defaultHostInfoPlist = MemoryFileSystem.test().file('defaultHostInfoPlist'); } class FakeIOSMigrator extends ProjectMigrator {