Support R.txt files generated with aapt2 link --package-id
ResourceProcessorBusyBox is being used in the Android platform build, which includes CTS tests that set `--package-id 0x80` when running aapt2 link. This produces R.txt files with ids that are out of range of java integers, for example `int color blue 0x80020000`. In an R.java file, javac interprets these as negative integers, but IntFieldInitializer throws a NumberFormatException. Make IntFieldInitializer act like javac by parsing the number as a Long and then narrowing it to an int.
PiperOrigin-RevId: 544184014
Change-Id: Ida26d00a4c487830a8b35bbdf58dd9a5c5411adc
diff --git a/src/test/java/com/google/devtools/build/android/resources/RClassGeneratorTest.java b/src/test/java/com/google/devtools/build/android/resources/RClassGeneratorTest.java
index 21cabea..8e1bc9c 100644
--- a/src/test/java/com/google/devtools/build/android/resources/RClassGeneratorTest.java
+++ b/src/test/java/com/google/devtools/build/android/resources/RClassGeneratorTest.java
@@ -165,12 +165,18 @@
"int id someTextView 0x7f080000",
"int integer maxNotifications 0x7f090000",
"int string alphabet 0x7f100000",
- "int string ok 0x7f100001");
+ "int string ok 0x7f100001",
+ // aapt2 link --package-id 0x80 produces IDs that are out of range of a java integer.
+ "int string largePackageId 0x80001000");
// R.txt for the library, where the values are not the final ones (so ignore them). We only use
// this to keep the # of inner classes small (exactly the set needed by the library).
ResourceSymbols symbolsInLibrary =
createSymbolFile(
- "lib.R.txt", "int attr agility 0x1", "int id someTextView 0x1", "int string ok 0x1");
+ "lib.R.txt",
+ "int attr agility 0x1",
+ "int id someTextView 0x1",
+ "int string ok 0x1",
+ "int string largePackageId 0x1");
Path out = temp.resolve("classes");
Files.createDirectories(out);
RClassGenerator writer = RClassGenerator.with(out, symbolValues.asInitializers(), finalFields);
@@ -198,7 +204,7 @@
out,
"com.bar.R$string",
outerClass,
- ImmutableMap.of("ok", 0x7f100001),
+ ImmutableMap.of("ok", 0x7f100001, "largePackageId", 0x80001000),
ImmutableMap.<String, List<Integer>>of(),
finalFields);
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/IntFieldInitializer.java b/src/tools/android/java/com/google/devtools/build/android/resources/IntFieldInitializer.java
index 66e310f..b6a5fe3 100644
--- a/src/tools/android/java/com/google/devtools/build/android/resources/IntFieldInitializer.java
+++ b/src/tools/android/java/com/google/devtools/build/android/resources/IntFieldInitializer.java
@@ -44,7 +44,11 @@
public static FieldInitializer of(
DependencyInfo dependencyInfo, Visibility visibility, String fieldName, String value) {
- return of(dependencyInfo, visibility, fieldName, Integer.decode(value));
+ // aapt2 --package-id 0x80 (or higher) will produce R.txt values that are outside the range of
+ // Integer.decode, e.g. 0x80001000. javac interprets them as negative integers, do the same
+ // here by decoding as a Long and then performing a narrowing primitive conversion to int.
+ int intValue = Long.decode(value).intValue();
+ return of(dependencyInfo, visibility, fieldName, intValue);
}
public static IntFieldInitializer of(