From 094e8965da798efa6625ccfc32aa2909e206de9c Mon Sep 17 00:00:00 2001 From: Jeff Hamilton Date: Wed, 6 Jan 2010 15:46:38 -0600 Subject: [PATCH] Add the --rename-manifest-package option to aapt. It allows you to force override the manifest package listed in the AndroidManifest.xml when creating an APK file. Change-Id: I7eac7943c4e56610b65728ae54773a273634fd9d --- Bundle.h | 5 +++- Main.cpp | 9 +++++++ Resource.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++----- StringPool.cpp | 2 +- XMLNode.cpp | 13 ++++++++++ XMLNode.h | 2 ++ 6 files changed, 91 insertions(+), 8 deletions(-) diff --git a/Bundle.h b/Bundle.h index c53f7f1..cbb5203 100644 --- a/Bundle.h +++ b/Bundle.h @@ -38,7 +38,7 @@ public: mUpdate(false), mExtending(false), mRequireLocalization(false), mPseudolocalize(false), mUTF8(false), mEncodingSpecified(false), mValues(false), - mCompressionMethod(0), mOutputAPKFile(NULL), + mCompressionMethod(0), mOutputAPKFile(NULL), mManifestPackageNameOverride(NULL), mAssetSourceDir(NULL), mProguardFile(NULL), mAndroidManifestFile(NULL), mPublicOutputFile(NULL), mRClassDir(NULL), mResourceIntermediatesDir(NULL), @@ -88,6 +88,8 @@ public: void setJunkPath(bool val) { mJunkPath = val; } const char* getOutputAPKFile() const { return mOutputAPKFile; } void setOutputAPKFile(const char* val) { mOutputAPKFile = val; } + const char* getManifestPackageNameOverride() const { return mManifestPackageNameOverride; } + void setManifestPackageNameOverride(const char * val) { mManifestPackageNameOverride = val; } /* * Input options. @@ -178,6 +180,7 @@ private: int mCompressionMethod; bool mJunkPath; const char* mOutputAPKFile; + const char* mManifestPackageNameOverride; const char* mAssetSourceDir; const char* mProguardFile; const char* mAndroidManifestFile; diff --git a/Main.cpp b/Main.cpp index 1e6b52e..6675ac2 100644 --- a/Main.cpp +++ b/Main.cpp @@ -436,6 +436,15 @@ int main(int argc, char* const argv[]) } else if (strcmp(cp, "-utf16") == 0) { bundle.setEncodingSpecified(true); bundle.setUTF8(false); + } else if (strcmp(cp, "-rename-manifest-package") == 0) { + argc--; + argv++; + if (!argc) { + fprintf(stderr, "ERROR: No argument supplied for '--rename-manifest-package' option\n"); + wantUsage = true; + goto bail; + } + bundle.setManifestPackageNameOverride(argv[0]); } else { fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp); wantUsage = true; diff --git a/Resource.cpp b/Resource.cpp index d53c472..0d2ea60 100644 --- a/Resource.cpp +++ b/Resource.cpp @@ -489,11 +489,11 @@ static bool applyFileOverlay(Bundle *bundle, DefaultKeyedVector > baseFiles = baseGroup->getFiles(); for (size_t i=0; i < baseFiles.size(); i++) { - printf("baseFile %d has flavor %s\n", i, + printf("baseFile %ld has flavor %s\n", i, baseFiles.keyAt(i).toString().string()); } for (size_t i=0; i < overlayFiles.size(); i++) { - printf("overlayFile %d has flavor %s\n", i, + printf("overlayFile %ld has flavor %s\n", i, overlayFiles.keyAt(i).toString().string()); } } @@ -507,7 +507,7 @@ static bool applyFileOverlay(Bundle *bundle, keyAt(overlayGroupIndex)); if(baseFileIndex < UNKNOWN_ERROR) { if (bundle->getVerbose()) { - printf("found a match (%d) for overlay file %s, for flavor %s\n", + printf("found a match (%ld) for overlay file %s, for flavor %s\n", baseFileIndex, overlayGroup->getLeaf().string(), overlayFiles.keyAt(overlayGroupIndex).toString().string()); @@ -562,6 +562,33 @@ void addTagAttribute(const sp& node, const char* ns8, node->addAttribute(ns, attr, String16(value)); } +static void fullyQualifyClassName(String8& package, sp node) { + XMLNode::attribute_entry* attr = node->editAttribute( + String16("http://schemas.android.com/apk/res/android"), String16("name")); + if (attr != NULL) { + String8 name(attr->string); + + // asdf --> package.asdf + // .asdf .a.b --> package.asdf package.a.b + // asdf.adsf --> asdf.asdf + String8 className; + const char* p = name.string(); + const char* q = strchr(p, '.'); + if (p == q) { + className += package; + className += name; + } else if (q == NULL) { + className += package; + className += "."; + className += name; + } else { + className += name; + } + NOISY(printf("Qualifying class '%s' to '%s'", name.string(), className.string())); + attr->string.setTo(String16(className)); + } +} + status_t massageManifest(Bundle* bundle, sp root) { root = root->searchElement(String16(), String16("manifest")); @@ -591,7 +618,36 @@ status_t massageManifest(Bundle* bundle, sp root) addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion", bundle->getMaxSdkVersion()); } - + + // Deal with manifest package name overrides + const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride(); + if (manifestPackageNameOverride != NULL) { + // Update the actual package name + XMLNode::attribute_entry* attr = root->editAttribute(String16(), String16("package")); + if (attr == NULL) { + fprintf(stderr, "package name is required with --rename-manifest-package.\n"); + return UNKNOWN_ERROR; + } + String8 origPackage(attr->string); + attr->string.setTo(String16(manifestPackageNameOverride)); + NOISY(printf("Overriding package '%s' to be '%s'\n", origPackage.string(), manifestPackageNameOverride)); + + // Make class names fully qualified + sp application = root->getChildElement(String16(), String16("application")); + if (application != NULL) { + fullyQualifyClassName(origPackage, application); + + Vector >& children = const_cast >&>(application->getChildren()); + for (size_t i = 0; i < children.size(); i++) { + sp child = children.editItemAt(i); + String8 tag(child->getElementName()); + if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") { + fullyQualifyClassName(origPackage, child); + } + } + } + } + return NO_ERROR; } @@ -1173,14 +1229,14 @@ status_t buildResources(Bundle* bundle, const sp& assets) table.writePublicDefinitions(String16(assets->getPackage()), fp); fclose(fp); } - +#if 0 NOISY( ResTable rt; rt.add(resFile->getData(), resFile->getSize(), NULL); printf("Generated resources:\n"); rt.print(); ) - +#endif // These resources are now considered to be a part of the included // resources, for others to reference. err = assets->addIncludedResources(resFile); diff --git a/StringPool.cpp b/StringPool.cpp index ec58591..51afc0a 100644 --- a/StringPool.cpp +++ b/StringPool.cpp @@ -25,7 +25,7 @@ void printStringPool(const ResStringPool* pool) const size_t NS = pool->size(); for (size_t s=0; sstringAt(s, &len)).string()); } } diff --git a/XMLNode.cpp b/XMLNode.cpp index 036dde4..4c59288 100644 --- a/XMLNode.cpp +++ b/XMLNode.cpp @@ -555,6 +555,19 @@ const XMLNode::attribute_entry* XMLNode::getAttribute(const String16& ns, return NULL; } +XMLNode::attribute_entry* XMLNode::editAttribute(const String16& ns, + const String16& name) +{ + for (size_t i=0; ins == ns && ae->name == name) { + return ae; + } + } + + return NULL; +} + const String16& XMLNode::getCData() const { return mChars; diff --git a/XMLNode.h b/XMLNode.h index dc92fa7..e9a263b 100644 --- a/XMLNode.h +++ b/XMLNode.h @@ -95,6 +95,8 @@ public: const attribute_entry* getAttribute(const String16& ns, const String16& name) const; + attribute_entry* editAttribute(const String16& ns, const String16& name); + const String16& getCData() const; const String16& getComment() const; -- 2.45.2