Enable R8 (#40453)

diff --git a/packages/flutter_tools/gradle/flutter.gradle b/packages/flutter_tools/gradle/flutter.gradle
index 7d26259..e11d7ff 100644
--- a/packages/flutter_tools/gradle/flutter.gradle
+++ b/packages/flutter_tools/gradle/flutter.gradle
@@ -159,8 +159,12 @@
                     "gradle", "flutter_proguard_rules.pro")
             project.android.buildTypes {
                 release {
+                    // Enables code shrinking, obfuscation, and optimization for only
+                    // your project's release build type.
                     minifyEnabled true
-                    useProguard true
+                    // Enables resource shrinking, which is performed by the
+                    // Android Gradle plugin.
+                    shrinkResources true
                     // Fallback to `android/app/proguard-rules.pro`.
                     // This way, custom Proguard rules can be configured as needed.
                     proguardFiles project.android.getDefaultProguardFile("proguard-android.txt"), flutterProguardRules, "proguard-rules.pro"
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index 049065a..c670388 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -306,6 +306,10 @@
   final Status status = logger.startProgress('Initializing gradle...',
       timeout: timeoutConfiguration.slowOperation);
 
+
+  // Update the project if needed.
+  // TODO(egarciad): https://github.com/flutter/flutter/issues/40460.
+  migrateToR8(android);
   injectGradleWrapperIfNeeded(android);
 
   final String gradle = _locateGradlewExecutable(android);
@@ -335,6 +339,31 @@
   return gradle;
 }
 
+/// Migrates the Android's [directory] to R8.
+/// https://developer.android.com/studio/build/shrink-code
+@visibleForTesting
+void migrateToR8(Directory directory) {
+  final File gradleProperties = directory.childFile('gradle.properties');
+  if (!gradleProperties.existsSync()) {
+    throwToolExit('Expected file ${gradleProperties.path}.');
+  }
+  final String propertiesContent = gradleProperties.readAsStringSync();
+  if (propertiesContent.contains('android.enableR8')) {
+    printTrace('gradle.properties already sets `android.enableR8`');
+    return;
+  }
+  printTrace('set `android.enableR8=true` in gradle.properties');
+  try {
+    gradleProperties
+      .writeAsStringSync('android.enableR8=true\n', mode: FileMode.append);
+  } on FileSystemException {
+    throwToolExit(
+      'The tool failed to add `android.enableR8=true` to ${gradleProperties.path}. '
+      'Please update the file manually and try this command again.'
+    );
+  }
+}
+
 /// Injects the Gradle wrapper files if any of these files don't exist in [directory].
 void injectGradleWrapperIfNeeded(Directory directory) {
   copyDirectorySync(
@@ -754,8 +783,8 @@
   if (androidBuildInfo.splitPerAbi) {
     command.add('-Psplit-per-abi=true');
   }
-  if (androidBuildInfo.proguard) {
-    command.add('-Pproguard=true');
+  if (androidBuildInfo.shrink) {
+    command.add('-Pshrink=true');
   }
   if (androidBuildInfo.targetArchs.isNotEmpty) {
     final String targetPlatforms = androidBuildInfo.targetArchs
@@ -772,7 +801,7 @@
   }
   command.add(assembleTask);
   bool potentialAndroidXFailure = false;
-  bool potentialProguardFailure = false;
+  bool potentialR8Failure = false;
   final Stopwatch sw = Stopwatch()..start();
   int exitCode = 1;
   try {
@@ -789,10 +818,10 @@
         if (!isAndroidXPluginWarning && androidXFailureRegex.hasMatch(line)) {
           potentialAndroidXFailure = true;
         }
-        // Proguard errors include this url.
-        if (!potentialProguardFailure && androidBuildInfo.proguard &&
-            line.contains('http://proguard.sourceforge.net')) {
-          potentialProguardFailure = true;
+        // R8 errors include references to this package.
+        if (!potentialR8Failure && androidBuildInfo.shrink &&
+            line.contains('com.android.tools.r8')) {
+          potentialR8Failure = true;
         }
         // Always print the full line in verbose mode.
         if (logger.isVerbose) {
@@ -808,12 +837,12 @@
   }
 
   if (exitCode != 0) {
-    if (potentialProguardFailure) {
+    if (potentialR8Failure) {
       final String exclamationMark = terminal.color('[!]', TerminalColor.red);
-      printStatus('$exclamationMark Proguard may have failed to optimize the Java bytecode.', emphasis: true);
-      printStatus('To disable proguard, pass the `--no-proguard` flag to this command.', indent: 4);
-      printStatus('To learn more about Proguard, see: https://flutter.dev/docs/deployment/android#enabling-proguard', indent: 4);
-      BuildEvent('proguard-failure').send();
+      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 learn more, see: https://developer.android.com/studio/build/shrink-code', indent: 4);
+      BuildEvent('r8-failure').send();
     } else if (potentialAndroidXFailure) {
       printStatus('AndroidX incompatibilities may have caused this build to fail. See https://goo.gl/CP92wY.');
       BuildEvent('android-x-failure').send();
diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart
index c406438..57ee601 100644
--- a/packages/flutter_tools/lib/src/build_info.dart
+++ b/packages/flutter_tools/lib/src/build_info.dart
@@ -92,7 +92,7 @@
       AndroidArch.arm64_v8a,
     ],
     this.splitPerAbi = false,
-    this.proguard = false,
+    this.shrink = false,
   });
 
   // The build info containing the mode and flavor.
@@ -105,8 +105,8 @@
   /// will be produced.
   final bool splitPerAbi;
 
-  /// Whether to enable Proguard on release mode.
-  final bool proguard;
+  /// Whether to enable code shrinking on release mode.
+  final bool shrink;
 
   /// The target platforms for the build.
   final Iterable<AndroidArch> targetArchs;
diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart
index a27d9f4..8936f0f 100644
--- a/packages/flutter_tools/lib/src/commands/build_apk.dart
+++ b/packages/flutter_tools/lib/src/commands/build_apk.dart
@@ -21,6 +21,7 @@
     usesPubOption();
     usesBuildNumberOption();
     usesBuildNameOption();
+    addShrinkingFlag();
 
     argParser
       ..addFlag('split-per-abi',
@@ -28,12 +29,6 @@
         help: 'Whether to split the APKs per ABIs. '
               'To learn more, see: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split',
       )
-      ..addFlag('proguard',
-        negatable: true,
-        defaultsTo: false,
-        help: 'Whether to enable Proguard on release mode. '
-              'To learn more, see: https://flutter.dev/docs/deployment/android#enabling-proguard',
-      )
       ..addMultiOption('target-platform',
         splitCommas: true,
         defaultsTo: <String>['android-arm', 'android-arm64'],
@@ -83,10 +78,11 @@
   @override
   Future<FlutterCommandResult> runCommand() async {
     final BuildInfo buildInfo = getBuildInfo();
-    final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(buildInfo,
+    final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(
+      buildInfo,
       splitPerAbi: argResults['split-per-abi'],
       targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName),
-      proguard: argResults['proguard'],
+      shrink: argResults['shrink'],
     );
 
     if (buildInfo.isRelease && !androidBuildInfo.splitPerAbi && androidBuildInfo.targetArchs.length > 1) {
diff --git a/packages/flutter_tools/lib/src/commands/build_appbundle.dart b/packages/flutter_tools/lib/src/commands/build_appbundle.dart
index 1a53b52..bfea24f 100644
--- a/packages/flutter_tools/lib/src/commands/build_appbundle.dart
+++ b/packages/flutter_tools/lib/src/commands/build_appbundle.dart
@@ -19,15 +19,10 @@
     usesPubOption();
     usesBuildNumberOption();
     usesBuildNameOption();
+    addShrinkingFlag();
 
     argParser
       ..addFlag('track-widget-creation', negatable: false, hide: !verboseHelp)
-      ..addFlag('proguard',
-        negatable: true,
-        defaultsTo: false,
-        help: 'Whether to enable Proguard on release mode. '
-              'To learn more, see: https://flutter.dev/docs/deployment/android#enabling-proguard',
-      )
       ..addMultiOption('target-platform',
         splitCommas: true,
         defaultsTo: <String>['android-arm', 'android-arm64'],
@@ -70,7 +65,7 @@
   Future<FlutterCommandResult> runCommand() async {
     final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(getBuildInfo(),
       targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName),
-      proguard: argResults['proguard'],
+      shrink: argResults['shrink'],
     );
     await androidBuilder.buildAab(
       project: FlutterProject.current(),
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index e22c692..597143e 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -277,6 +277,19 @@
       help: 'Build a release version of your app${defaultToRelease ? ' (default mode)' : ''}.');
   }
 
+  void addShrinkingFlag() {
+    argParser.addFlag('shrink',
+      negatable: true,
+      defaultsTo: true,
+      help: 'Whether to enable code shrinking on release mode.'
+            'When enabling shrinking, you also benefit from obfuscation, '
+            'which shortens the names of your app’s classes and members, '
+            'and optimization, which applies more aggressive strategies to '
+            'further reduce the size of your app.'
+            'To learn more, see: https://developer.android.com/studio/build/shrink-code'
+      );
+  }
+
   void usesFuchsiaOptions({ bool hide = false }) {
     argParser.addOption(
       'target-model',
diff --git a/packages/flutter_tools/templates/app/android.tmpl/gradle.properties.tmpl b/packages/flutter_tools/templates/app/android.tmpl/gradle.properties.tmpl
index a2296f5..2a0d268 100644
--- a/packages/flutter_tools/templates/app/android.tmpl/gradle.properties.tmpl
+++ b/packages/flutter_tools/templates/app/android.tmpl/gradle.properties.tmpl
@@ -1,5 +1,5 @@
 org.gradle.jvmargs=-Xmx1536M
-
+android.enableR8=true
 {{#androidX}}
 android.useAndroidX=true
 android.enableJetifier=true
diff --git a/packages/flutter_tools/templates/module/android/gradle/gradle.properties.tmpl b/packages/flutter_tools/templates/module/android/gradle/gradle.properties.tmpl
index a2296f5..2a0d268 100644
--- a/packages/flutter_tools/templates/module/android/gradle/gradle.properties.tmpl
+++ b/packages/flutter_tools/templates/module/android/gradle/gradle.properties.tmpl
@@ -1,5 +1,5 @@
 org.gradle.jvmargs=-Xmx1536M
-
+android.enableR8=true
 {{#androidX}}
 android.useAndroidX=true
 android.enableJetifier=true
diff --git a/packages/flutter_tools/templates/plugin/android.tmpl/gradle.properties.tmpl b/packages/flutter_tools/templates/plugin/android.tmpl/gradle.properties.tmpl
index a2296f5..2a0d268 100644
--- a/packages/flutter_tools/templates/plugin/android.tmpl/gradle.properties.tmpl
+++ b/packages/flutter_tools/templates/plugin/android.tmpl/gradle.properties.tmpl
@@ -1,5 +1,5 @@
 org.gradle.jvmargs=-Xmx1536M
-
+android.enableR8=true
 {{#androidX}}
 android.useAndroidX=true
 android.enableJetifier=true
diff --git a/packages/flutter_tools/test/general.shard/android/gradle_test.dart b/packages/flutter_tools/test/general.shard/android/gradle_test.dart
index e583a46..b650ab0 100644
--- a/packages/flutter_tools/test/general.shard/android/gradle_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/gradle_test.dart
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 import 'dart:async';
-import 'dart:io';
 
 import 'package:file/memory.dart';
 import 'package:flutter_tools/src/android/android_sdk.dart';
@@ -13,6 +12,7 @@
 import 'package:flutter_tools/src/artifacts.dart';
 import 'package:flutter_tools/src/base/common.dart';
 import 'package:flutter_tools/src/base/file_system.dart';
+import 'package:flutter_tools/src/base/io.dart';
 import 'package:flutter_tools/src/base/os.dart';
 import 'package:flutter_tools/src/base/platform.dart';
 import 'package:flutter_tools/src/build_info.dart';
@@ -867,6 +867,13 @@
       gradleWrapperDirectory
         .childFile(gradleBinary)
         .writeAsStringSync('irrelevant');
+      fs.currentDirectory
+        .childDirectory('android')
+        .createSync();
+      fs.currentDirectory
+        .childDirectory('android')
+        .childFile('gradle.properties')
+        .writeAsStringSync('irrelevant');
       gradleWrapperDirectory
         .childDirectory('gradle')
         .childDirectory('wrapper')
@@ -1072,6 +1079,82 @@
     });
   });
 
+  group('migrateToR8', () {
+    MemoryFileSystem memoryFileSystem;
+
+    setUp(() {
+      memoryFileSystem = MemoryFileSystem();
+    });
+
+    testUsingContext('throws ToolExit if gradle.properties doesn\'t exist', () {
+      final Directory sampleAppAndroid = fs.directory('/sample-app/android');
+      sampleAppAndroid.createSync(recursive: true);
+
+      expect(() {
+        migrateToR8(sampleAppAndroid);
+      }, throwsToolExit(message: 'Expected file ${sampleAppAndroid.path}'));
+
+    }, overrides: <Type, Generator>{
+      FileSystem: () => memoryFileSystem,
+    });
+
+    testUsingContext('throws ToolExit if it cannot write gradle.properties', () {
+      final MockDirectory sampleAppAndroid = MockDirectory();
+      final MockFile gradleProperties = MockFile();
+
+      when(gradleProperties.path).thenReturn('foo/gradle.properties');
+      when(gradleProperties.existsSync()).thenReturn(true);
+      when(gradleProperties.readAsStringSync()).thenReturn('');
+      when(gradleProperties.writeAsStringSync('android.enableR8=true\n', mode: FileMode.append))
+        .thenThrow(const FileSystemException());
+
+      when(sampleAppAndroid.childFile('gradle.properties'))
+        .thenReturn(gradleProperties);
+
+      expect(() {
+        migrateToR8(sampleAppAndroid);
+      },
+      throwsToolExit(message:
+        'The tool failed to add `android.enableR8=true` to foo/gradle.properties. '
+        'Please update the file manually and try this command again.'));
+    });
+
+    testUsingContext('does not update gradle.properties if it already uses R8', () {
+      final Directory sampleAppAndroid = fs.directory('/sample-app/android');
+      sampleAppAndroid.createSync(recursive: true);
+      sampleAppAndroid.childFile('gradle.properties')
+        .writeAsStringSync('android.enableR8=true');
+
+      migrateToR8(sampleAppAndroid);
+
+      expect(testLogger.traceText,
+        contains('gradle.properties already sets `android.enableR8`'));
+      expect(sampleAppAndroid.childFile('gradle.properties').readAsStringSync(),
+        equals('android.enableR8=true'));
+    }, overrides: <Type, Generator>{
+      FileSystem: () => memoryFileSystem,
+    });
+
+    testUsingContext('sets android.enableR8=true', () {
+      final Directory sampleAppAndroid = fs.directory('/sample-app/android');
+      sampleAppAndroid.createSync(recursive: true);
+      sampleAppAndroid.childFile('gradle.properties')
+        .writeAsStringSync('org.gradle.jvmargs=-Xmx1536M\n');
+
+      migrateToR8(sampleAppAndroid);
+
+      expect(testLogger.traceText, contains('set `android.enableR8=true` in gradle.properties'));
+      expect(sampleAppAndroid.childFile('gradle.properties').readAsStringSync(),
+        equals(
+          'org.gradle.jvmargs=-Xmx1536M\n'
+          'android.enableR8=true\n'
+        )
+      );
+    }, overrides: <Type, Generator>{
+      FileSystem: () => memoryFileSystem,
+    });
+  });
+
   group('gradle build', () {
     MockAndroidSdk mockAndroidSdk;
     MockAndroidStudio mockAndroidStudio;
@@ -1136,6 +1219,9 @@
       final File gradlew = fs.file('path/to/project/.android/gradlew');
       gradlew.createSync(recursive: true);
 
+      fs.file('path/to/project/.android/gradle.properties')
+        .writeAsStringSync('irrelevant');
+
       when(mockProcessManager.run(
           <String> ['/path/to/project/.android/gradlew', '-v'],
           workingDirectory: anyNamed('workingDirectory'),
@@ -1198,9 +1284,11 @@
   return FakePlatform.fromPlatform(const LocalPlatform())..operatingSystem = name;
 }
 
+class MockAndroidStudio extends Mock implements AndroidStudio {}
+class MockDirectory extends Mock implements Directory {}
+class MockFile extends Mock implements File {}
+class MockGradleProject extends Mock implements GradleProject {}
 class MockLocalEngineArtifacts extends Mock implements LocalEngineArtifacts {}
 class MockProcessManager extends Mock implements ProcessManager {}
 class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
-class MockGradleProject extends Mock implements GradleProject {}
 class MockitoAndroidSdk extends Mock implements AndroidSdk {}
-class MockAndroidStudio extends Mock implements AndroidStudio {}
diff --git a/packages/flutter_tools/test/general.shard/application_package_test.dart b/packages/flutter_tools/test/general.shard/application_package_test.dart
index a374142..05855b0 100644
--- a/packages/flutter_tools/test/general.shard/application_package_test.dart
+++ b/packages/flutter_tools/test/general.shard/application_package_test.dart
@@ -103,6 +103,10 @@
         platform.isWindows ? 'gradlew.bat' : 'gradlew',
       )..createSync(recursive: true);
 
+      project.android.hostAppGradleRoot
+        .childFile('gradle.properties')
+        .writeAsStringSync('irrelevant');
+
       final Directory gradleWrapperDir = fs.systemTempDirectory.createTempSync('gradle_wrapper.');
       when(mockCache.getArtifactDirectory('gradle_wrapper')).thenReturn(gradleWrapperDir);
 
diff --git a/packages/flutter_tools/test/general.shard/commands/build_apk_test.dart b/packages/flutter_tools/test/general.shard/commands/build_apk_test.dart
index f3d19b8..1c961ad 100644
--- a/packages/flutter_tools/test/general.shard/commands/build_apk_test.dart
+++ b/packages/flutter_tools/test/general.shard/commands/build_apk_test.dart
@@ -137,7 +137,7 @@
       tryToDelete(tempDir);
     });
 
-    testUsingContext('proguard is enabled by default on release mode', () async {
+    testUsingContext('shrinking is enabled by default on release mode', () async {
       final String projectPath = await createProject(tempDir,
           arguments: <String>['--no-pub', '--template=app']);
 
@@ -151,7 +151,7 @@
           '-q',
           '-Ptarget=${fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
           '-Ptrack-widget-creation=false',
-          '-Pproguard=true',
+          '-Pshrink=true',
           '-Ptarget-platform=android-arm,android-arm64',
           'assembleRelease',
         ],
@@ -165,17 +165,16 @@
       GradleUtils: () => GradleUtils(),
       ProcessManager: () => mockProcessManager,
     },
-    skip: true,
     timeout: allowForCreateFlutterProject);
 
-    testUsingContext('proguard is disabled when --no-proguard is passed', () async {
+    testUsingContext('shrinking is disabled when --no-shrink is passed', () async {
       final String projectPath = await createProject(tempDir,
           arguments: <String>['--no-pub', '--template=app']);
 
       await expectLater(() async {
         await runBuildApkCommand(
           projectPath,
-          arguments: <String>['--no-proguard'],
+          arguments: <String>['--no-shrink'],
         );
       }, throwsToolExit(message: 'Gradle task assembleRelease failed with exit code 1'));
 
@@ -198,10 +197,9 @@
       GradleUtils: () => GradleUtils(),
       ProcessManager: () => mockProcessManager,
     },
-    skip: true,
     timeout: allowForCreateFlutterProject);
 
-    testUsingContext('guides the user when proguard fails', () async {
+    testUsingContext('guides the user when the shrinker fails', () async {
       final String projectPath = await createProject(tempDir,
           arguments: <String>['--no-pub', '--template=app']);
 
@@ -211,22 +209,20 @@
           '-q',
           '-Ptarget=${fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
           '-Ptrack-widget-creation=false',
-          '-Pproguard=true',
+          '-Pshrink=true',
           '-Ptarget-platform=android-arm,android-arm64',
           'assembleRelease',
         ],
         workingDirectory: anyNamed('workingDirectory'),
         environment: anyNamed('environment'),
       )).thenAnswer((_) {
-        const String proguardStdoutWarning =
-            'Warning: there were 6 unresolved references to program class members.'
-            'Your input classes appear to be inconsistent.'
-            'You may need to recompile the code.'
-            '(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)';
+        const String r8StdoutWarning =
+            'Execution failed for task \':app:transformClassesAndResourcesWithR8ForStageInternal\'.'
+            '> com.android.tools.r8.CompilationFailedException: Compilation failed to complete';
         return Future<Process>.value(
           createMockProcess(
             exitCode: 1,
-            stdout: proguardStdoutWarning,
+            stdout: r8StdoutWarning,
           )
         );
       });
@@ -238,15 +234,15 @@
       }, throwsToolExit(message: 'Gradle task assembleRelease failed with exit code 1'));
 
       expect(testLogger.statusText,
-          contains('Proguard may have failed to optimize the Java bytecode.'));
+          contains('The shrinker may have failed to optimize the Java bytecode.'));
       expect(testLogger.statusText,
-          contains('To disable proguard, pass the `--no-proguard` flag to this command.'));
+          contains('To disable the shrinker, pass the `--no-shrink` flag to this command.'));
       expect(testLogger.statusText,
-          contains('To learn more about Proguard, see: https://flutter.dev/docs/deployment/android#enabling-proguard'));
+          contains('To learn more, see: https://developer.android.com/studio/build/shrink-code'));
 
       verify(mockUsage.sendEvent(
         'build-apk',
-        'proguard-failure',
+        'r8-failure',
         parameters: anyNamed('parameters'),
       )).called(1);
     },
@@ -257,7 +253,6 @@
       ProcessManager: () => mockProcessManager,
       Usage: () => mockUsage,
     },
-    skip: true,
     timeout: allowForCreateFlutterProject);
   });
 }
diff --git a/packages/flutter_tools/test/general.shard/commands/build_appbundle_test.dart b/packages/flutter_tools/test/general.shard/commands/build_appbundle_test.dart
index 4548e3c..4a7d98f 100644
--- a/packages/flutter_tools/test/general.shard/commands/build_appbundle_test.dart
+++ b/packages/flutter_tools/test/general.shard/commands/build_appbundle_test.dart
@@ -75,7 +75,7 @@
     }, timeout: allowForCreateFlutterProject);
   });
 
-  group('Flags', () {
+  group('Gradle', () {
     Directory tempDir;
     ProcessManager mockProcessManager;
     MockAndroidSdk mockAndroidSdk;
@@ -122,7 +122,7 @@
       tryToDelete(tempDir);
     });
 
-    testUsingContext('proguard is enabled by default on release mode', () async {
+    testUsingContext('shrinking is enabled by default on release mode', () async {
       final String projectPath = await createProject(
           tempDir,
           arguments: <String>['--no-pub', '--template=app'],
@@ -138,7 +138,7 @@
           '-q',
           '-Ptarget=${fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
           '-Ptrack-widget-creation=false',
-          '-Pproguard=true',
+          '-Pshrink=true',
           '-Ptarget-platform=android-arm,android-arm64',
           'bundleRelease',
         ],
@@ -152,10 +152,9 @@
       GradleUtils: () => GradleUtils(),
       ProcessManager: () => mockProcessManager,
     },
-    skip: true,
     timeout: allowForCreateFlutterProject);
 
-    testUsingContext('proguard is disabled when --no-proguard is passed', () async {
+    testUsingContext('shrinking is disabled when --no-shrink is passed', () async {
       final String projectPath = await createProject(
           tempDir,
           arguments: <String>['--no-pub', '--template=app'],
@@ -164,7 +163,7 @@
       await expectLater(() async {
         await runBuildAppBundleCommand(
           projectPath,
-          arguments: <String>['--no-proguard'],
+          arguments: <String>['--no-shrink'],
         );
       }, throwsToolExit(message: 'Gradle task bundleRelease failed with exit code 1'));
 
@@ -187,10 +186,9 @@
       GradleUtils: () => GradleUtils(),
       ProcessManager: () => mockProcessManager,
     },
-    skip: true,
     timeout: allowForCreateFlutterProject);
 
-    testUsingContext('guides the user when proguard fails', () async {
+    testUsingContext('guides the user when the shrinker fails', () async {
       final String projectPath = await createProject(tempDir,
           arguments: <String>['--no-pub', '--template=app']);
 
@@ -200,22 +198,20 @@
           '-q',
           '-Ptarget=${fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
           '-Ptrack-widget-creation=false',
-          '-Pproguard=true',
+          '-Pshrink=true',
           '-Ptarget-platform=android-arm,android-arm64',
           'bundleRelease',
         ],
         workingDirectory: anyNamed('workingDirectory'),
         environment: anyNamed('environment'),
       )).thenAnswer((_) {
-        const String proguardStdoutWarning =
-            'Warning: there were 6 unresolved references to program class members.'
-            'Your input classes appear to be inconsistent.'
-            'You may need to recompile the code.'
-            '(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)';
+        const String r8StdoutWarning =
+            'Execution failed for task \':app:transformClassesAndResourcesWithR8ForStageInternal\'.'
+            '> com.android.tools.r8.CompilationFailedException: Compilation failed to complete';
         return Future<Process>.value(
           createMockProcess(
             exitCode: 1,
-            stdout: proguardStdoutWarning,
+            stdout: r8StdoutWarning,
           )
         );
       });
@@ -227,15 +223,15 @@
       }, throwsToolExit(message: 'Gradle task bundleRelease failed with exit code 1'));
 
       expect(testLogger.statusText,
-          contains('Proguard may have failed to optimize the Java bytecode.'));
+          contains('The shrinker may have failed to optimize the Java bytecode.'));
       expect(testLogger.statusText,
-          contains('To disable proguard, pass the `--no-proguard` flag to this command.'));
+          contains('To disable the shrinker, pass the `--no-shrink` flag to this command.'));
       expect(testLogger.statusText,
-          contains('To learn more about Proguard, see: https://flutter.dev/docs/deployment/android#enabling-proguard'));
+          contains('To learn more, see: https://developer.android.com/studio/build/shrink-code'));
 
       verify(mockUsage.sendEvent(
         'build-appbundle',
-        'proguard-failure',
+        'r8-failure',
         parameters: anyNamed('parameters'),
       )).called(1);
     },
@@ -246,7 +242,6 @@
       ProcessManager: () => mockProcessManager,
       Usage: () => mockUsage,
     },
-    skip: true,
     timeout: allowForCreateFlutterProject);
   });
 }