[various] Add `targetCompatibility` to build.gradle (#3825)

While current docs about `targetCompatibility` say that it defaults to `sourceCompatibility`, for older toolchains (AGP?) that is apparently not the case, and it's a build error to set `sourceCompatibility` without `targetCompatibility`.

This adds enforcement that it's set to `gradle-check`, and fixes all of the violations.

Fixes https://github.com/flutter/flutter/issues/125482
diff --git a/packages/espresso/CHANGELOG.md b/packages/espresso/CHANGELOG.md
index 660fcc7..7204107 100644
--- a/packages/espresso/CHANGELOG.md
+++ b/packages/espresso/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.3.0+3
+
+* Adds `targetCompatibilty` matching `sourceCompatibility` for older toolchains.
+
 ## 0.3.0+2
 
 * Adds a namespace for compatibility with AGP 8.0.
diff --git a/packages/espresso/android/build.gradle b/packages/espresso/android/build.gradle
index 0b8960b..034779a 100644
--- a/packages/espresso/android/build.gradle
+++ b/packages/espresso/android/build.gradle
@@ -32,6 +32,7 @@
 
     compileOptions {
         sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
     }
 
     lintOptions {
diff --git a/packages/espresso/pubspec.yaml b/packages/espresso/pubspec.yaml
index a67455d..ef0d6dd 100644
--- a/packages/espresso/pubspec.yaml
+++ b/packages/espresso/pubspec.yaml
@@ -3,7 +3,7 @@
   Allows driving Flutter widgets from a native Espresso test.
 repository: https://github.com/flutter/packages/tree/main/packages/espresso
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+espresso%22
-version: 0.3.0+2
+version: 0.3.0+3
 
 environment:
   sdk: ">=2.17.0 <4.0.0"
diff --git a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md
index 9e97351..ca354c8 100644
--- a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md
+++ b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.0.12
+
+* Adds `targetCompatibilty` matching `sourceCompatibility` for older toolchains.
+
 ## 2.0.11
 
 * Adds a namespace for compatibility with AGP 8.0.
diff --git a/packages/flutter_plugin_android_lifecycle/android/build.gradle b/packages/flutter_plugin_android_lifecycle/android/build.gradle
index c12cc35..1203eb3 100644
--- a/packages/flutter_plugin_android_lifecycle/android/build.gradle
+++ b/packages/flutter_plugin_android_lifecycle/android/build.gradle
@@ -33,6 +33,7 @@
 
     compileOptions {
         sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
     }
 
     lintOptions {
diff --git a/packages/flutter_plugin_android_lifecycle/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/pubspec.yaml
index ae7686f..d76dabd 100644
--- a/packages/flutter_plugin_android_lifecycle/pubspec.yaml
+++ b/packages/flutter_plugin_android_lifecycle/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Flutter plugin for accessing an Android Lifecycle within other plugins.
 repository: https://github.com/flutter/packages/tree/main/packages/flutter_plugin_android_lifecycle
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_plugin_android_lifecycle%22
-version: 2.0.11
+version: 2.0.12
 
 environment:
   sdk: ">=2.17.0 <4.0.0"
diff --git a/packages/google_sign_in/google_sign_in_android/CHANGELOG.md b/packages/google_sign_in/google_sign_in_android/CHANGELOG.md
index fcbe694..d9082a6 100644
--- a/packages/google_sign_in/google_sign_in_android/CHANGELOG.md
+++ b/packages/google_sign_in/google_sign_in_android/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 6.1.13
+
+* Adds `targetCompatibilty` matching `sourceCompatibility` for older toolchains.
+
 ## 6.1.12
 
 * Adds a namespace for compatibility with AGP 8.0.
diff --git a/packages/google_sign_in/google_sign_in_android/android/build.gradle b/packages/google_sign_in/google_sign_in_android/android/build.gradle
index 88ae5fc..72c383c 100644
--- a/packages/google_sign_in/google_sign_in_android/android/build.gradle
+++ b/packages/google_sign_in/google_sign_in_android/android/build.gradle
@@ -32,6 +32,7 @@
 
     compileOptions {
         sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
     }
 
     lintOptions {
diff --git a/packages/google_sign_in/google_sign_in_android/pubspec.yaml b/packages/google_sign_in/google_sign_in_android/pubspec.yaml
index 2998b53..1ff448e 100644
--- a/packages/google_sign_in/google_sign_in_android/pubspec.yaml
+++ b/packages/google_sign_in/google_sign_in_android/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Android implementation of the google_sign_in plugin.
 repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_android
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22
-version: 6.1.12
+version: 6.1.13
 
 environment:
   sdk: ">=2.17.0 <4.0.0"
diff --git a/packages/local_auth/local_auth_android/CHANGELOG.md b/packages/local_auth/local_auth_android/CHANGELOG.md
index 2cf84b9..1f65132 100644
--- a/packages/local_auth/local_auth_android/CHANGELOG.md
+++ b/packages/local_auth/local_auth_android/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.26
+
+* Adds `targetCompatibilty` matching `sourceCompatibility` for older toolchains.
+
 ## 1.0.25
 
 * Adds a namespace for compatibility with AGP 8.0.
diff --git a/packages/local_auth/local_auth_android/android/build.gradle b/packages/local_auth/local_auth_android/android/build.gradle
index bcb7183..a212f23 100644
--- a/packages/local_auth/local_auth_android/android/build.gradle
+++ b/packages/local_auth/local_auth_android/android/build.gradle
@@ -32,6 +32,7 @@
 
     compileOptions {
         sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
     }
 
     lintOptions {
diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml
index e5f4196..d9cf8df 100644
--- a/packages/local_auth/local_auth_android/pubspec.yaml
+++ b/packages/local_auth/local_auth_android/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Android implementation of the local_auth plugin.
 repository: https://github.com/flutter/packages/tree/main/packages/local_auth/local_auth_android
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22
-version: 1.0.25
+version: 1.0.26
 
 environment:
   sdk: ">=2.17.0 <4.0.0"
diff --git a/packages/url_launcher/url_launcher_android/CHANGELOG.md b/packages/url_launcher/url_launcher_android/CHANGELOG.md
index e75e9d0..fdf4eb9 100644
--- a/packages/url_launcher/url_launcher_android/CHANGELOG.md
+++ b/packages/url_launcher/url_launcher_android/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 6.0.30
+
+* Adds `targetCompatibilty` matching `sourceCompatibility` for older toolchains.
+
 ## 6.0.29
 
 * Adds a namespace for compatibility with AGP 8.0.
diff --git a/packages/url_launcher/url_launcher_android/android/build.gradle b/packages/url_launcher/url_launcher_android/android/build.gradle
index d371a80..e0c2fc6 100644
--- a/packages/url_launcher/url_launcher_android/android/build.gradle
+++ b/packages/url_launcher/url_launcher_android/android/build.gradle
@@ -32,6 +32,7 @@
 
     compileOptions {
         sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
     }
 
     lintOptions {
diff --git a/packages/url_launcher/url_launcher_android/pubspec.yaml b/packages/url_launcher/url_launcher_android/pubspec.yaml
index 5a9de34..cf35a0b 100644
--- a/packages/url_launcher/url_launcher_android/pubspec.yaml
+++ b/packages/url_launcher/url_launcher_android/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Android implementation of the url_launcher plugin.
 repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_android
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
-version: 6.0.29
+version: 6.0.30
 
 environment:
   sdk: ">=2.18.0 <4.0.0"
diff --git a/script/tool/lib/src/gradle_check_command.dart b/script/tool/lib/src/gradle_check_command.dart
index 6bce292..a3a1e76 100644
--- a/script/tool/lib/src/gradle_check_command.dart
+++ b/script/tool/lib/src/gradle_check_command.dart
@@ -101,7 +101,7 @@
     if (!_validateNamespace(package, contents, isExample: false)) {
       succeeded = false;
     }
-    if (!_validateSourceCompatibilityVersion(lines)) {
+    if (!_validateCompatibilityVersions(lines)) {
       succeeded = false;
     }
     if (!_validateGradleDrivenLintConfig(package, lines)) {
@@ -204,18 +204,27 @@
   /// Checks for a source compatibiltiy version, so that it's explicit rather
   /// than using whatever the client's local toolchaing defaults to (which can
   /// lead to compile errors that show up for clients, but not in CI).
-  bool _validateSourceCompatibilityVersion(List<String> gradleLines) {
-    if (!gradleLines.any((String line) =>
-            line.contains('languageVersion') && !_isCommented(line)) &&
-        !gradleLines.any((String line) =>
-            line.contains('sourceCompatibility') && !_isCommented(line))) {
+  bool _validateCompatibilityVersions(List<String> gradleLines) {
+    final bool hasLanguageVersion = gradleLines.any((String line) =>
+        line.contains('languageVersion') && !_isCommented(line));
+    final bool hasCompabilityVersions = gradleLines.any((String line) =>
+            line.contains('sourceCompatibility') && !_isCommented(line)) &&
+        // Newer toolchains default targetCompatibility to the same value as
+        // sourceCompatibility, but older toolchains require it to be set
+        // explicitly. The exact version cutoff (and of which piece of the
+        // toolchain; likely AGP) is unknown; for context see
+        // https://github.com/flutter/flutter/issues/125482
+        gradleLines.any((String line) =>
+            line.contains('targetCompatibility') && !_isCommented(line));
+    if (!hasLanguageVersion && !hasCompabilityVersions) {
       const String errorMessage = '''
 build.gradle must set an explicit Java compatibility version.
 
-This can be done either via "sourceCompatibility":
+This can be done either via "sourceCompatibility"/"targetCompatibility":
     android {
         compileOptions {
             sourceCompatibility JavaVersion.VERSION_1_8
+            targetCompatibility JavaVersion.VERSION_1_8
         }
     }
 
diff --git a/script/tool/test/gradle_check_command_test.dart b/script/tool/test/gradle_check_command_test.dart
index ca37309..e72d3f8 100644
--- a/script/tool/test/gradle_check_command_test.dart
+++ b/script/tool/test/gradle_check_command_test.dart
@@ -38,6 +38,7 @@
     RepositoryPackage package, {
     bool includeLanguageVersion = false,
     bool includeSourceCompat = false,
+    bool includeTargetCompat = false,
     bool commentSourceLanguage = false,
     bool includeNamespace = true,
     bool commentNamespace = false,
@@ -64,11 +65,10 @@
 }
 
 ''';
-    final String compileOptionsSection = '''
-    compileOptions {
-        ${commentSourceLanguage ? '// ' : ''}sourceCompatibility JavaVersion.VERSION_1_8
-    }
-''';
+    final String sourceCompat =
+        '${commentSourceLanguage ? '// ' : ''}sourceCompatibility JavaVersion.VERSION_1_8';
+    final String targetCompat =
+        '${commentSourceLanguage ? '// ' : ''}targetCompatibility JavaVersion.VERSION_1_8';
     final String namespace =
         "${commentNamespace ? '// ' : ''}namespace '$_defaultFakeNamespace'";
 
@@ -94,7 +94,10 @@
         minSdkVersion 30
     }
 ${warningsConfigured ? warningConfig : ''}
-${includeSourceCompat ? compileOptionsSection : ''}
+    compileOptions {
+        ${includeSourceCompat ? sourceCompat : ''}
+        ${includeTargetCompat ? targetCompat : ''}
+    }
     testOptions {
         unitTests.includeAndroidResources = true
     }
@@ -280,12 +283,38 @@
     );
   });
 
-  test('passes when sourceCompatibility is specified', () async {
+  test(
+      'fails when sourceCompatibility is provided with out targetCompatibility',
+      () async {
     final RepositoryPackage package =
         createFakePlugin('a_plugin', packagesDir, examples: <String>[]);
     writeFakePluginBuildGradle(package, includeSourceCompat: true);
     writeFakeManifest(package);
 
+    Error? commandError;
+    final List<String> output = await runCapturingPrint(
+        runner, <String>['gradle-check'], errorHandler: (Error e) {
+      commandError = e;
+    });
+
+    expect(commandError, isA<ToolExit>());
+    expect(
+      output,
+      containsAllInOrder(<Matcher>[
+        contains(
+            'build.gradle must set an explicit Java compatibility version.'),
+      ]),
+    );
+  });
+
+  test('passes when sourceCompatibility and targetCompatibility are specified',
+      () async {
+    final RepositoryPackage package =
+        createFakePlugin('a_plugin', packagesDir, examples: <String>[]);
+    writeFakePluginBuildGradle(package,
+        includeSourceCompat: true, includeTargetCompat: true);
+    writeFakeManifest(package);
+
     final List<String> output =
         await runCapturingPrint(runner, <String>['gradle-check']);
 
@@ -339,7 +368,9 @@
     final RepositoryPackage package =
         createFakePlugin('a_plugin', packagesDir, examples: <String>[]);
     writeFakePluginBuildGradle(package,
-        includeSourceCompat: true, commentSourceLanguage: true);
+        includeSourceCompat: true,
+        includeTargetCompat: true,
+        commentSourceLanguage: true);
     writeFakeManifest(package);
 
     Error? commandError;