Allow multi-abi shared libraries in APKs and App bundles (#34123)

* Gradle generates ELF shared libraries instead of AOT snapshots.
* `flutter build apk/appbundle` supports multiple `--target-platform` and defaults to `android-arm` and `android-arm64`.
* `flutter build apk` now has a flag called `--split-per-abi`.
diff --git a/packages/flutter_tools/test/base/build_test.dart b/packages/flutter_tools/test/base/build_test.dart
index 60d3724..8c32fd9 100644
--- a/packages/flutter_tools/test/base/build_test.dart
+++ b/packages/flutter_tools/test/base/build_test.dart
@@ -80,7 +80,7 @@
     });
   });
 
-  group('Snapshotter - iOS AOT', () {
+  group('Snapshotter - AOT', () {
     const String kSnapshotDart = 'snapshot.dart';
     String skyEnginePath;
 
@@ -395,10 +395,11 @@
       ]);
     }, overrides: contextOverrides);
 
-    testUsingContext('returns failure if buildSharedLibrary is true but no NDK is found', () async {
-      final String outputPath = fs.path.join('build', 'foo');
+    testUsingContext('builds shared library for android-arm', () async {
+      fs.file('main.dill').writeAsStringSync('binary magic');
 
-      when(mockAndroidSdk.ndk).thenReturn(null);
+      final String outputPath = fs.path.join('build', 'foo');
+      fs.directory(outputPath).createSync(recursive: true);
 
       final int genSnapshotExitCode = await snapshotter.build(
         platform: TargetPlatform.android_arm,
@@ -409,8 +410,45 @@
         buildSharedLibrary: true,
       );
 
-      expect(genSnapshotExitCode, isNot(0));
-      expect(genSnapshot.callCount, 0);
+      expect(genSnapshotExitCode, 0);
+      expect(genSnapshot.callCount, 1);
+      expect(genSnapshot.snapshotType.platform, TargetPlatform.android_arm);
+      expect(genSnapshot.snapshotType.mode, BuildMode.release);
+      expect(genSnapshot.additionalArgs, <String>[
+        '--deterministic',
+        '--snapshot_kind=app-aot-elf',
+        '--elf=build/foo/app.so',
+        '--no-sim-use-hardfp',
+        '--no-use-integer-division',
+        'main.dill',
+      ]);
+    }, overrides: contextOverrides);
+
+    testUsingContext('builds shared library for android-arm64', () async {
+      fs.file('main.dill').writeAsStringSync('binary magic');
+
+      final String outputPath = fs.path.join('build', 'foo');
+      fs.directory(outputPath).createSync(recursive: true);
+
+      final int genSnapshotExitCode = await snapshotter.build(
+        platform: TargetPlatform.android_arm64,
+        buildMode: BuildMode.release,
+        mainPath: 'main.dill',
+        packagesPath: '.packages',
+        outputPath: outputPath,
+        buildSharedLibrary: true,
+      );
+
+      expect(genSnapshotExitCode, 0);
+      expect(genSnapshot.callCount, 1);
+      expect(genSnapshot.snapshotType.platform, TargetPlatform.android_arm64);
+      expect(genSnapshot.snapshotType.mode, BuildMode.release);
+      expect(genSnapshot.additionalArgs, <String>[
+        '--deterministic',
+        '--snapshot_kind=app-aot-elf',
+        '--elf=build/foo/app.so',
+        'main.dill',
+      ]);
     }, overrides: contextOverrides);
 
     testUsingContext('builds Android arm release AOT snapshot', () async {