diff options
author | Adam Lesinski <adamlesinski@google.com> | 2014-08-15 14:47:28 -0700 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2014-08-25 20:04:07 -0700 |
commit | 1e466385d4a4f1acee080fa0fdf16cc8fd8ce7ca (patch) | |
tree | 431c15e17f780767289dc5d3362d5d6d53ee3c18 /tools/aapt | |
parent | 5b8e5a7d4c930b42e1a3c2b3e67144b89d37efa2 (diff) | |
download | frameworks_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.cpp | 12 | ||||
-rw-r--r-- | tools/aapt/IndentPrinter.h | 63 | ||||
-rw-r--r-- | tools/aapt/Main.h | 3 | ||||
-rw-r--r-- | tools/aapt/Resource.cpp | 134 |
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; |