@@ -14,9 +14,90 @@ import 'test_utils.dart';
1414/// ABI → index map (same as FlutterPluginConstants.ABI_VERSION)
1515const _abiIndexMap = < String , int > {'armeabi-v7a' : 1 , 'arm64-v8a' : 2 , 'x86_64' : 4 };
1616
17+ const _appGradleWithVersionCodeModification = r'''
18+ import com.android.build.api.variant.FilterConfiguration.FilterType.*
19+ import java.util.Properties
20+ import java.io.FileInputStream
21+
22+ plugins {
23+ id("com.android.application")
24+ id("kotlin-android")
25+ // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
26+ id("dev.flutter.flutter-gradle-plugin")
27+ }
28+
29+ android {
30+ namespace = "com.example.splitperabi"
31+ compileSdk = flutter.compileSdkVersion
32+ ndkVersion = flutter.ndkVersion
33+
34+ compileOptions {
35+ sourceCompatibility = JavaVersion.VERSION_11
36+ targetCompatibility = JavaVersion.VERSION_11
37+ }
38+
39+ kotlinOptions {
40+ jvmTarget = JavaVersion.VERSION_11.toString()
41+ }
42+
43+ defaultConfig {
44+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
45+ applicationId = "com.example.splitperabi"
46+ // You can update the following values to match your application needs.
47+ // For more information, see: https://flutter.dev/to/review-gradle-config.
48+ minSdk = flutter.minSdkVersion
49+ targetSdk = flutter.targetSdkVersion
50+ versionCode = flutter.versionCode
51+ versionName = flutter.versionName
52+ }
53+
54+ buildTypes {
55+ release {
56+ // TODO: Add your own signing config for the release build.
57+ // Signing with the debug keys for now, so `flutter run --release` works.
58+ signingConfig = signingConfigs.getByName("debug")
59+ }
60+ }
61+ }
62+
63+ flutter {
64+ source = "../.."
65+ }
66+
67+ val abiCodes = mapOf("x86_64" to 1, "armeabi-v7a" to 2, "arm64-v8a" to 3, "universal" to 4)
68+
69+ androidComponents {
70+ onVariants { variant ->
71+
72+ variant.outputs.forEach { output ->
73+ val name = output.filters.find { it.filterType == ABI }?.identifier
74+
75+ val baseAbiCode = abiCodes[name ?: "universal"]
76+ if (baseAbiCode != null) {
77+ output.versionCode.set(output.versionCode.get() * 10000)
78+ }
79+ }
80+ }
81+ }
82+
83+ ''' ;
84+
1785// Check that `flutter build apk --split-per-abi` generates a versionCode equal to abiIndex * 1000 + buildNumber
18- Future <void > _assertSplitPerAbiVersionCodes (int ? buildNumber) async {
19- final String workingDirectory = fileSystem.path.join (getFlutterRoot (), 'examples' , 'hello_world' );
86+ Future <void > _assertSplitPerAbiVersionCodes (
87+ int ? buildNumber,
88+ Directory workingDirectory,
89+ bool usingCustomAppGradleFile,
90+ ) async {
91+ if (usingCustomAppGradleFile) {
92+ // Replace the app level build.gradle with one that modifies the version code.
93+ final File appBuildGradle = fileSystem
94+ .directory (workingDirectory)
95+ .childDirectory ('android' )
96+ .childDirectory ('app' )
97+ .childFile ('build.gradle.kts' );
98+
99+ await appBuildGradle.writeAsString (_appGradleWithVersionCodeModification);
100+ }
20101
21102 final args = < String > [
22103 flutterBin,
@@ -31,7 +112,10 @@ Future<void> _assertSplitPerAbiVersionCodes(int? buildNumber) async {
31112 args.addAll (< String > ['--build-number' , buildNumber.toString ()]);
32113 }
33114
34- final ProcessResult result = processManager.runSync (args, workingDirectory: workingDirectory);
115+ final ProcessResult result = processManager.runSync (
116+ args,
117+ workingDirectory: workingDirectory.path,
118+ );
35119 expect (
36120 result.exitCode,
37121 0 ,
@@ -92,7 +176,8 @@ Future<void> _assertSplitPerAbiVersionCodes(int? buildNumber) async {
92176 );
93177
94178 final int actual = actualVersionCodes[abi]! ;
95- final int expected = (abiIndex * 1000 ) + (buildNumber ?? 1 );
179+ final int expected =
180+ (abiIndex * 1000 ) + ((buildNumber ?? 1 ) * (usingCustomAppGradleFile ? 10000 : 1 ));
96181 expect (
97182 actual,
98183 expected,
@@ -105,19 +190,46 @@ Future<void> _assertSplitPerAbiVersionCodes(int? buildNumber) async {
105190}
106191
107192void main () {
193+ late Directory tempDir;
194+ late Directory appDir;
195+ setUp (() async {
196+ tempDir = createResolvedTempDirectorySync ('flutter_split_per_abi_test.' );
197+
198+ processManager.runSync (< String > [
199+ flutterBin,
200+ ...getLocalEngineArguments (),
201+ 'create' ,
202+ '--platforms=android' ,
203+ 'splitperabi' ,
204+ ], workingDirectory: tempDir.path);
205+ appDir = tempDir.childDirectory ('splitperabi' );
206+ });
207+
208+ tearDown (() async {
209+ tryToDelete (tempDir);
210+ });
211+
108212 // Check with no build-number
109213 testWithoutContext (
110214 'APK versionCodes after --split-per-abi (no explicit build-number) follow "(abiIndex * 1000) + 1"' ,
111215 () async {
112- await _assertSplitPerAbiVersionCodes (null );
216+ await _assertSplitPerAbiVersionCodes (null , appDir, false );
113217 },
114218 );
115219
116220 // Check with custom buildNumber=42
117221 testWithoutContext (
118222 'APK versionCodes after --split-per-abi with custom build-number=42 follow "(abiIndex * 1000) + 42"' ,
119223 () async {
120- await _assertSplitPerAbiVersionCodes (42 );
224+ await _assertSplitPerAbiVersionCodes (42 , appDir, false );
225+ },
226+ );
227+
228+ // Check with custom buildNumber=42 and custom gradle file which multiplies build number by 10000
229+ testWithoutContext (
230+ 'APK versionCodes after --split-per-abi with custom build-number=42 and gradle file follow "(abiIndex * 1000) + (42 * 10000)"' ,
231+ () async {
232+ await _assertSplitPerAbiVersionCodes (42 , appDir, true );
121233 },
122234 );
123235}
0 commit comments