let flutter build aar use a local engine (#39312)

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 79a6a72..b33bbc0 100644
--- a/packages/flutter_tools/test/general.shard/android/gradle_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/gradle_test.dart
@@ -3,8 +3,11 @@
 // 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';
+import 'package:flutter_tools/src/android/android_studio.dart';
 import 'package:flutter_tools/src/android/gradle.dart';
 import 'package:flutter_tools/src/base/logger.dart';
 import 'package:flutter_tools/src/artifacts.dart';
@@ -20,6 +23,7 @@
 
 import '../../src/common.dart';
 import '../../src/context.dart';
+import '../../src/mocks.dart';
 import '../../src/pubspec_schema.dart';
 
 void main() {
@@ -843,6 +847,92 @@
           throwsA(predicate<Exception>((Exception e) => e is ToolExit)));
     });
   });
+
+  group('gradle build', () {
+    MockAndroidSdk mockAndroidSdk;
+    MockAndroidStudio mockAndroidStudio;
+    MockLocalEngineArtifacts mockArtifacts;
+    MockProcessManager mockProcessManager;
+    FakePlatform android;
+    FileSystem fs;
+
+    setUp(() {
+      fs = MemoryFileSystem();
+      mockAndroidSdk = MockAndroidSdk();
+      mockAndroidStudio = MockAndroidStudio();
+      mockArtifacts = MockLocalEngineArtifacts();
+      mockProcessManager = MockProcessManager();
+      android = fakePlatform('android');
+    });
+
+    testUsingContext('build aar uses selected local engine', () async {
+      when(mockArtifacts.getArtifactPath(Artifact.flutterFramework,
+          platform: TargetPlatform.android_arm, mode: anyNamed('mode'))).thenReturn('engine');
+      when(mockArtifacts.engineOutPath).thenReturn(fs.path.join('out', 'android_arm'));
+
+      final File manifestFile = fs.file('path/to/project/pubspec.yaml');
+      manifestFile.createSync(recursive: true);
+      manifestFile.writeAsStringSync('''
+        name: test
+        version: 1.0.0+1
+        dependencies:
+          flutter:
+            sdk: flutter
+        flutter:
+          module:
+            androidX: false
+            androidPackage: com.example.test
+            iosBundleIdentifier: com.example.test
+        '''
+      );
+
+      final File gradlew = fs.file('path/to/project/.android/gradlew');
+      gradlew.createSync(recursive: true);
+
+      when(mockProcessManager.run(
+          <String> ['/path/to/project/.android/gradlew', '-v'],
+          workingDirectory: anyNamed('workingDirectory'),
+          environment: anyNamed('environment'),
+      )).thenAnswer(
+          (_) async => ProcessResult(1, 0, '5.1.1', ''),
+      );
+
+      // write schemaData otherwise pubspec.yaml file can't be loaded
+      writeEmptySchemaFile(fs);
+      fs.currentDirectory = 'path/to/project';
+
+      // Let any process start. Assert after.
+      when(mockProcessManager.start(
+        any,
+        environment: anyNamed('environment'),
+        workingDirectory: anyNamed('workingDirectory'))
+      ).thenAnswer((Invocation invocation) => Future<Process>.value(MockProcess()));
+      fs.directory('build/outputs/repo').createSync(recursive: true);
+
+      await buildGradleAar(
+        androidBuildInfo: const AndroidBuildInfo(BuildInfo(BuildMode.release, null)),
+        project: FlutterProject.current(),
+        outputDir: 'build/',
+        target: ''
+      );
+
+      final List<String> actualGradlewCall = verify(mockProcessManager.start(
+        captureAny,
+        environment: anyNamed('environment'),
+        workingDirectory: anyNamed('workingDirectory')),
+      ).captured.single;
+
+      expect(actualGradlewCall, contains('/path/to/project/.android/gradlew'));
+      expect(actualGradlewCall, contains('-PlocalEngineOut=out/android_arm'));
+    }, overrides: <Type, Generator>{
+        AndroidSdk: () => mockAndroidSdk,
+        AndroidStudio: () => mockAndroidStudio,
+        Artifacts: () => mockArtifacts,
+        ProcessManager: () => mockProcessManager,
+        Platform: () => android,
+        FileSystem: () => fs,
+      });
+  });
 }
 
 /// Generates a fake app bundle at the location [directoryName]/[fileName].
@@ -864,3 +954,5 @@
 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 {}