AAPT2: Add option to generate static library

Difference between normal app and static library is that
the R file uses non-final fields, and the extra chunks added
by AAPT2 remain in the final APK.

Change-Id: I61416387ca9bb3c21857ff7cfab5847ac3edf57a
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index dedf8b4..3377f07 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -323,9 +323,17 @@
         Compile,
     };
 
+    enum class PackageType {
+        StandardApp,
+        StaticLibrary,
+    };
+
     // The phase to process.
     Phase phase;
 
+    // The type of package to produce.
+    PackageType packageType = PackageType::StandardApp;
+
     // Details about the app.
     AppInfo appInfo;
 
@@ -800,7 +808,11 @@
 
     // Generate the Java class file.
     if (options.generateJavaClass) {
-        JavaClassGenerator generator(outTable, {});
+        JavaClassGenerator::Options javaOptions;
+        if (options.packageType == AaptOptions::PackageType::StaticLibrary) {
+            javaOptions.useFinal = false;
+        }
+        JavaClassGenerator generator(outTable, javaOptions);
 
         for (const std::u16string& package : linkedPackages) {
             Source outPath = options.generateJavaClass.value();
@@ -852,7 +864,10 @@
 
     // Flatten the resource table.
     TableFlattener::Options flattenerOptions;
-    flattenerOptions.useExtendedChunks = false;
+    if (options.packageType == AaptOptions::PackageType::StaticLibrary) {
+        flattenerOptions.useExtendedChunks = true;
+    }
+
     if (!writeResourceTable(options, outTable, flattenerOptions, &outApk)) {
         return false;
     }
@@ -999,6 +1014,7 @@
         printCommandsAndDie();
     }
 
+    bool isStaticLib = false;
     if (options.phase == AaptOptions::Phase::Compile) {
         flag::requiredFlag("--package", "Android package name",
                 [&options](const StringPiece& arg) {
@@ -1026,6 +1042,8 @@
                 [&options](const StringPiece& arg) {
                     options.generateJavaClass = Source{ arg.toString() };
                 });
+        flag::optionalSwitch("--static-lib", "generate a static Android library", true,
+                             &isStaticLib);
     }
 
     // Common flags for all steps.
@@ -1049,6 +1067,10 @@
         flag::usageAndDie(fullCommand);
     }
 
+    if (isStaticLib) {
+        options.packageType = AaptOptions::PackageType::StaticLibrary;
+    }
+
     // Copy all the remaining arguments.
     for (const std::string& arg : flag::getArgs()) {
         options.input.push_back(Source{ arg });