summaryrefslogtreecommitdiffstats
path: root/tools/aapt
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2014-08-15 14:47:28 -0700
committerAdam Lesinski <adamlesinski@google.com>2014-08-25 20:04:07 -0700
commit1e466385d4a4f1acee080fa0fdf16cc8fd8ce7ca (patch)
tree431c15e17f780767289dc5d3362d5d6d53ee3c18 /tools/aapt
parent5b8e5a7d4c930b42e1a3c2b3e67144b89d37efa2 (diff)
downloadframeworks_base-1e466385d4a4f1acee080fa0fdf16cc8fd8ce7ca.zip
frameworks_base-1e466385d4a4f1acee080fa0fdf16cc8fd8ce7ca.tar.gz
frameworks_base-1e466385d4a4f1acee080fa0fdf16cc8fd8ce7ca.tar.bz2
Have R classes generate their own reference rewrite logic
Change-Id: I0e5b8311fc3479d966a49f9acf0d4c32a6a024d3
Diffstat (limited to 'tools/aapt')
-rw-r--r--tools/aapt/Command.cpp12
-rw-r--r--tools/aapt/IndentPrinter.h63
-rw-r--r--tools/aapt/Main.h3
-rw-r--r--tools/aapt/Resource.cpp134
4 files changed, 194 insertions, 18 deletions
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index b394671..a0f0a08 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -2488,10 +2488,12 @@ int doPackage(Bundle* bundle)
if (bundle->getCustomPackage() == NULL) {
// Write the R.java file into the appropriate class directory
// e.g. gen/com/foo/app/R.java
- err = writeResourceSymbols(bundle, assets, assets->getPackage(), true);
+ err = writeResourceSymbols(bundle, assets, assets->getPackage(), true,
+ bundle->getBuildSharedLibrary());
} else {
const String8 customPkg(bundle->getCustomPackage());
- err = writeResourceSymbols(bundle, assets, customPkg, true);
+ err = writeResourceSymbols(bundle, assets, customPkg, true,
+ bundle->getBuildSharedLibrary());
}
if (err < 0) {
goto bail;
@@ -2505,7 +2507,7 @@ int doPackage(Bundle* bundle)
char* packageString = strtok(libs.lockBuffer(libs.length()), ":");
while (packageString != NULL) {
// Write the R.java file out with the correct package name
- err = writeResourceSymbols(bundle, assets, String8(packageString), true);
+ err = writeResourceSymbols(bundle, assets, String8(packageString), true, false);
if (err < 0) {
goto bail;
}
@@ -2514,11 +2516,11 @@ int doPackage(Bundle* bundle)
libs.unlockBuffer();
}
} else {
- err = writeResourceSymbols(bundle, assets, assets->getPackage(), false);
+ err = writeResourceSymbols(bundle, assets, assets->getPackage(), false, false);
if (err < 0) {
goto bail;
}
- err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true);
+ err = writeResourceSymbols(bundle, assets, assets->getSymbolsPrivatePackage(), true, false);
if (err < 0) {
goto bail;
}
diff --git a/tools/aapt/IndentPrinter.h b/tools/aapt/IndentPrinter.h
new file mode 100644
index 0000000..6fc94bc
--- /dev/null
+++ b/tools/aapt/IndentPrinter.h
@@ -0,0 +1,63 @@
+#ifndef __INDENT_PRINTER_H
+#define __INDENT_PRINTER_H
+
+class IndentPrinter {
+public:
+ IndentPrinter(FILE* stream, int indentSize=2)
+ : mStream(stream)
+ , mIndentSize(indentSize)
+ , mIndent(0)
+ , mNeedsIndent(true) {
+ }
+
+ void indent(int amount = 1) {
+ mIndent += amount;
+ if (mIndent < 0) {
+ mIndent = 0;
+ }
+ }
+
+ void print(const char* fmt, ...) {
+ doIndent();
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(mStream, fmt, args);
+ va_end(args);
+ }
+
+ void println(const char* fmt, ...) {
+ doIndent();
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(mStream, fmt, args);
+ va_end(args);
+ fputs("\n", mStream);
+ mNeedsIndent = true;
+ }
+
+ void println() {
+ doIndent();
+ fputs("\n", mStream);
+ mNeedsIndent = true;
+ }
+
+private:
+ void doIndent() {
+ if (mNeedsIndent) {
+ int numSpaces = mIndent * mIndentSize;
+ while (numSpaces > 0) {
+ fputs(" ", mStream);
+ numSpaces--;
+ }
+ mNeedsIndent = false;
+ }
+ }
+
+ FILE* mStream;
+ const int mIndentSize;
+ int mIndent;
+ bool mNeedsIndent;
+};
+
+#endif // __INDENT_PRINTER_H
+
diff --git a/tools/aapt/Main.h b/tools/aapt/Main.h
index 34c4496..dd40b20 100644
--- a/tools/aapt/Main.h
+++ b/tools/aapt/Main.h
@@ -49,7 +49,8 @@ extern android::status_t buildResources(Bundle* bundle,
const sp<AaptAssets>& assets, sp<ApkBuilder>& builder);
extern android::status_t writeResourceSymbols(Bundle* bundle,
- const sp<AaptAssets>& assets, const String8& pkgName, bool includePrivate);
+ const sp<AaptAssets>& assets, const String8& pkgName,
+ bool includePrivate, bool emitCallback);
extern android::status_t writeProguardFile(Bundle* bundle, const sp<AaptAssets>& assets);
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 1d93b89..7979a1d 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -3,18 +3,17 @@
//
// Build resource files from raw assets.
//
-#include "Main.h"
#include "AaptAssets.h"
-#include "StringPool.h"
-#include "XMLNode.h"
-#include "ResourceTable.h"
-#include "Images.h"
-
+#include "CacheUpdater.h"
#include "CrunchCache.h"
#include "FileFinder.h"
-#include "CacheUpdater.h"
-
+#include "Images.h"
+#include "IndentPrinter.h"
+#include "Main.h"
+#include "ResourceTable.h"
+#include "StringPool.h"
#include "WorkQueue.h"
+#include "XMLNode.h"
#if HAVE_PRINTF_ZD
# define ZD "%zd"
@@ -1801,6 +1800,112 @@ static String16 getAttributeComment(const sp<AaptAssets>& assets,
return String16();
}
+static void writeResourceLoadedCallback(FILE* fp, int indent) {
+ IndentPrinter p(fp, 4);
+ p.indent(indent);
+ p.println("private static void rewriteIntArrayField(java.lang.reflect.Field field, int packageId) throws IllegalAccessException {");
+ {
+ p.indent();
+ p.println("int requiredModifiers = java.lang.reflect.Modifier.STATIC | java.lang.reflect.Modifier.PUBLIC;");
+ p.println("if ((field.getModifiers() & requiredModifiers) != requiredModifiers) {");
+ {
+ p.indent();
+ p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not rewritable\");");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.println("if (field.getType() != int[].class) {");
+ {
+ p.indent();
+ p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not an int array\");");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.println("int[] array = (int[]) field.get(null);");
+ p.println("for (int i = 0; i < array.length; i++) {");
+ {
+ p.indent();
+ p.println("array[i] = (array[i] & 0x00ffffff) | (packageId << 24);");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.println();
+ p.println("private static void rewriteIntField(java.lang.reflect.Field field, int packageId) throws IllegalAccessException {");
+ {
+ p.indent();
+ p.println("int requiredModifiers = java.lang.reflect.Modifier.STATIC | java.lang.reflect.Modifier.PUBLIC;");
+ p.println("int bannedModifiers = java.lang.reflect.Modifier.FINAL;");
+ p.println("int mod = field.getModifiers();");
+ p.println("if ((mod & requiredModifiers) != requiredModifiers || (mod & bannedModifiers) != 0) {");
+ {
+ p.indent();
+ p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not rewritable\");");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.println("if (field.getType() != int.class && field.getType() != Integer.class) {");
+ {
+ p.indent();
+ p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not an int\");");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.println("int resId = field.getInt(null);");
+ p.println("field.setInt(null, (resId & 0x00ffffff) | (packageId << 24));");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.println();
+ p.println("public static void onResourcesLoaded(int assignedPackageId) throws Exception {");
+ {
+ p.indent();
+ p.println("Class<?>[] declaredClasses = R.class.getDeclaredClasses();");
+ p.println("for (Class<?> clazz : declaredClasses) {");
+ {
+ p.indent();
+ p.println("if (clazz.getSimpleName().equals(\"styleable\")) {");
+ {
+ p.indent();
+ p.println("for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {");
+ {
+ p.indent();
+ p.println("if (field.getType() == int[].class) {");
+ {
+ p.indent();
+ p.println("rewriteIntArrayField(field, assignedPackageId);");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.indent(-1);
+ }
+ p.println("} else {");
+ {
+ p.indent();
+ p.println("for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {");
+ {
+ p.indent();
+ p.println("rewriteIntField(field, assignedPackageId);");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.indent(-1);
+ }
+ p.println("}");
+ p.println();
+}
+
static status_t writeLayoutClasses(
FILE* fp, const sp<AaptAssets>& assets,
const sp<AaptSymbols>& symbols, int indent, bool includePrivate, bool nonConstantId)
@@ -2138,7 +2243,7 @@ static status_t writeTextLayoutClasses(
static status_t writeSymbolClass(
FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
const sp<AaptSymbols>& symbols, const String8& className, int indent,
- bool nonConstantId)
+ bool nonConstantId, bool emitCallback)
{
fprintf(fp, "%spublic %sfinal class %s {\n",
getIndentSpace(indent),
@@ -2238,7 +2343,8 @@ static status_t writeSymbolClass(
if (nclassName == "styleable") {
styleableSymbols = nsymbols;
} else {
- err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName, indent, nonConstantId);
+ err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName,
+ indent, nonConstantId, false);
}
if (err != NO_ERROR) {
return err;
@@ -2252,6 +2358,10 @@ static status_t writeSymbolClass(
}
}
+ if (emitCallback) {
+ writeResourceLoadedCallback(fp, indent);
+ }
+
indent--;
fprintf(fp, "%s}\n", getIndentSpace(indent));
return NO_ERROR;
@@ -2299,7 +2409,7 @@ static status_t writeTextSymbolClass(
}
status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets,
- const String8& package, bool includePrivate)
+ const String8& package, bool includePrivate, bool emitCallback)
{
if (!bundle->getRClassDir()) {
return NO_ERROR;
@@ -2355,7 +2465,7 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets,
"package %s;\n\n", package.string());
status_t err = writeSymbolClass(fp, assets, includePrivate, symbols,
- className, 0, bundle->getNonConstantId());
+ className, 0, bundle->getNonConstantId(), emitCallback);
fclose(fp);
if (err != NO_ERROR) {
return err;