Unverified Commit 532a8fed authored by Emmanuel Garcia's avatar Emmanuel Garcia Committed by GitHub

Print message and log event when app isn't using AndroidX (#42548)

parent 3fea2838
...@@ -745,6 +745,20 @@ Future<void> _buildGradleProjectV2( ...@@ -745,6 +745,20 @@ Future<void> _buildGradleProjectV2(
); );
} }
final String exclamationMark = terminal.color('[!]', TerminalColor.red);
final bool usesAndroidX = isAppUsingAndroidX(flutterProject.android.hostAppGradleRoot);
if (usesAndroidX) {
BuildEvent('app-using-android-x').send();
} else if (!usesAndroidX) {
BuildEvent('app-not-using-android-x').send();
printStatus('$exclamationMark Your app isn\'t using AndroidX.', emphasis: true);
printStatus(
'To avoid potential build failures, you can quickly migrate your app '
'by following the steps on https://goo.gl/CP92wY.',
indent: 4,
);
}
final BuildInfo buildInfo = androidBuildInfo.buildInfo; final BuildInfo buildInfo = androidBuildInfo.buildInfo;
String assembleTask; String assembleTask;
...@@ -847,14 +861,12 @@ Future<void> _buildGradleProjectV2( ...@@ -847,14 +861,12 @@ Future<void> _buildGradleProjectV2(
if (exitCode != 0) { if (exitCode != 0) {
if (potentialR8Failure) { if (potentialR8Failure) {
final String exclamationMark = terminal.color('[!]', TerminalColor.red);
printStatus('$exclamationMark The shrinker may have failed to optimize the Java bytecode.', emphasis: true); printStatus('$exclamationMark The shrinker may have failed to optimize the Java bytecode.', emphasis: true);
printStatus('To disable the shrinker, pass the `--no-shrink` flag to this command.', indent: 4); printStatus('To disable the shrinker, pass the `--no-shrink` flag to this command.', indent: 4);
printStatus('To learn more, see: https://developer.android.com/studio/build/shrink-code', indent: 4); printStatus('To learn more, see: https://developer.android.com/studio/build/shrink-code', indent: 4);
BuildEvent('r8-failure').send(); BuildEvent('r8-failure').send();
} else if (potentialAndroidXFailure) { } else if (potentialAndroidXFailure) {
final bool hasPlugins = flutterProject.flutterPluginsFile.existsSync(); final bool hasPlugins = flutterProject.flutterPluginsFile.existsSync();
final bool usesAndroidX = isAppUsingAndroidX(flutterProject.android.hostAppGradleRoot);
if (!hasPlugins) { if (!hasPlugins) {
// If the app doesn't use any plugin, then it's unclear where the incompatibility is coming from. // If the app doesn't use any plugin, then it's unclear where the incompatibility is coming from.
BuildEvent('android-x-failure', eventError: 'app-not-using-plugins').send(); BuildEvent('android-x-failure', eventError: 'app-not-using-plugins').send();
......
...@@ -9,7 +9,9 @@ import 'package:file/memory.dart'; ...@@ -9,7 +9,9 @@ import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_builder.dart'; import 'package:flutter_tools/src/android/android_builder.dart';
import 'package:flutter_tools/src/android/android_sdk.dart'; import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/gradle.dart'; import 'package:flutter_tools/src/android/gradle.dart';
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build_apk.dart'; import 'package:flutter_tools/src/commands/build_apk.dart';
...@@ -312,6 +314,116 @@ flutter: ...@@ -312,6 +314,116 @@ flutter:
Usage: () => mockUsage, Usage: () => mockUsage,
}, },
timeout: allowForCreateFlutterProject); timeout: allowForCreateFlutterProject);
testUsingContext('reports when the app isn\'t using AndroidX', () async {
final String projectPath = await createProject(tempDir,
arguments: <String>['--no-pub', '--no-androidx', '--template=app']);
when(mockProcessManager.start(
<String>[
gradlew,
'-q',
'-Ptarget=${fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Ptrack-widget-creation=false',
'-Pshrink=true',
'-Ptarget-platform=android-arm,android-arm64,android-x64',
'assembleRelease',
],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenAnswer((_) {
return Future<Process>.value(
createMockProcess(
exitCode: 0,
stdout: '',
),
);
});
// The command throws a [ToolExit] because it expects an APK in the file system.
await expectLater(() async {
await runBuildApkCommand(
projectPath,
);
}, throwsToolExit());
final BufferLogger logger = context.get<Logger>();
expect(logger.statusText, contains('[!] Your app isn\'t using AndroidX'));
expect(logger.statusText, contains(
'To avoid potential build failures, you can quickly migrate your app by '
'following the steps on https://goo.gl/CP92wY'
)
);
verify(mockUsage.sendEvent(
'build',
'apk',
label: 'app-not-using-android-x',
parameters: anyNamed('parameters'),
)).called(1);
},
overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk,
GradleUtils: () => GradleUtils(),
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager,
Usage: () => mockUsage,
},
timeout: allowForCreateFlutterProject);
testUsingContext('reports when the app is using AndroidX', () async {
final String projectPath = await createProject(tempDir,
arguments: <String>['--no-pub', '--template=app']);
when(mockProcessManager.start(
<String>[
gradlew,
'-q',
'-Ptarget=${fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Ptrack-widget-creation=false',
'-Pshrink=true',
'-Ptarget-platform=android-arm,android-arm64,android-x64',
'assembleRelease',
],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenAnswer((_) {
return Future<Process>.value(
createMockProcess(
exitCode: 0,
stdout: '',
),
);
});
// The command throws a [ToolExit] because it expects an APK in the file system.
await expectLater(() async {
await runBuildApkCommand(
projectPath,
);
}, throwsToolExit());
final BufferLogger logger = context.get<Logger>();
expect(logger.statusText.contains('[!] Your app isn\'t using AndroidX'), isFalse);
expect(
logger.statusText.contains(
'To avoid potential build failures, you can quickly migrate your app by '
'following the steps on https://goo.gl/CP92wY'
),
isFalse,
);
verify(mockUsage.sendEvent(
'build',
'apk',
label: 'app-using-android-x',
parameters: anyNamed('parameters'),
)).called(1);
},
overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk,
GradleUtils: () => GradleUtils(),
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager,
Usage: () => mockUsage,
},
timeout: allowForCreateFlutterProject);
}); });
} }
......
...@@ -9,7 +9,9 @@ import 'package:file/memory.dart'; ...@@ -9,7 +9,9 @@ import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_builder.dart'; import 'package:flutter_tools/src/android/android_builder.dart';
import 'package:flutter_tools/src/android/android_sdk.dart'; import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/gradle.dart'; import 'package:flutter_tools/src/android/gradle.dart';
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build_appbundle.dart'; import 'package:flutter_tools/src/commands/build_appbundle.dart';
...@@ -303,6 +305,116 @@ flutter: ...@@ -303,6 +305,116 @@ flutter:
Usage: () => mockUsage, Usage: () => mockUsage,
}, },
timeout: allowForCreateFlutterProject); timeout: allowForCreateFlutterProject);
testUsingContext('reports when the app isn\'t using AndroidX', () async {
final String projectPath = await createProject(tempDir,
arguments: <String>['--no-pub', '--no-androidx', '--template=app']);
when(mockProcessManager.start(
<String>[
gradlew,
'-q',
'-Ptarget=${fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Ptrack-widget-creation=false',
'-Pshrink=true',
'-Ptarget-platform=android-arm,android-arm64,android-x64',
'assembleRelease',
],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenAnswer((_) {
return Future<Process>.value(
createMockProcess(
exitCode: 0,
stdout: '',
),
);
});
// The command throws a [ToolExit] because it expects an AAB in the file system.
await expectLater(() async {
await runBuildAppBundleCommand(
projectPath,
);
}, throwsToolExit());
final BufferLogger logger = context.get<Logger>();
expect(logger.statusText, contains('[!] Your app isn\'t using AndroidX'));
expect(logger.statusText, contains(
'To avoid potential build failures, you can quickly migrate your app by '
'following the steps on https://goo.gl/CP92wY'
)
);
verify(mockUsage.sendEvent(
'build',
'appbundle',
label: 'app-not-using-android-x',
parameters: anyNamed('parameters'),
)).called(1);
},
overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk,
GradleUtils: () => GradleUtils(),
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager,
Usage: () => mockUsage,
},
timeout: allowForCreateFlutterProject);
testUsingContext('reports when the app is using AndroidX', () async {
final String projectPath = await createProject(tempDir,
arguments: <String>['--no-pub', '--template=app']);
when(mockProcessManager.start(
<String>[
gradlew,
'-q',
'-Ptarget=${fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Ptrack-widget-creation=false',
'-Pshrink=true',
'-Ptarget-platform=android-arm,android-arm64,android-x64',
'assembleRelease',
],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).thenAnswer((_) {
return Future<Process>.value(
createMockProcess(
exitCode: 0,
stdout: '',
),
);
});
// The command throws a [ToolExit] because it expects an AAB in the file system.
await expectLater(() async {
await runBuildAppBundleCommand(
projectPath,
);
}, throwsToolExit());
final BufferLogger logger = context.get<Logger>();
expect(logger.statusText.contains('[!] Your app isn\'t using AndroidX'), isFalse);
expect(
logger.statusText.contains(
'To avoid potential build failures, you can quickly migrate your app by '
'following the steps on https://goo.gl/CP92wY'
),
isFalse,
);
verify(mockUsage.sendEvent(
'build',
'appbundle',
label: 'app-using-android-x',
parameters: anyNamed('parameters'),
)).called(1);
},
overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk,
GradleUtils: () => GradleUtils(),
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager,
Usage: () => mockUsage,
},
timeout: allowForCreateFlutterProject);
}); });
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment