diff options
Diffstat (limited to 'tools/aapt')
-rw-r--r-- | tools/aapt/AaptAssets.cpp | 56 | ||||
-rw-r--r-- | tools/aapt/AaptAssets.h | 3 | ||||
-rw-r--r-- | tools/aapt/Android.mk | 1 | ||||
-rw-r--r-- | tools/aapt/Bundle.h | 8 | ||||
-rw-r--r-- | tools/aapt/Command.cpp | 20 | ||||
-rw-r--r-- | tools/aapt/Main.cpp | 45 | ||||
-rw-r--r-- | tools/aapt/Main.h | 1 | ||||
-rw-r--r-- | tools/aapt/ResourceIdCache.cpp | 107 | ||||
-rw-r--r-- | tools/aapt/ResourceIdCache.h | 30 | ||||
-rw-r--r-- | tools/aapt/ResourceTable.cpp | 30 |
10 files changed, 281 insertions, 20 deletions
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index 46b8a27..5b71adc 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -183,6 +183,13 @@ AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value) return 0; } + // layout direction + if (getLayoutDirectionName(part.string(), &config)) { + *axis = AXIS_LAYOUTDIR; + *value = (config.screenLayout&ResTable_config::MASK_LAYOUTDIR); + return 0; + } + // smallest screen dp width if (getSmallestScreenWidthDpName(part.string(), &config)) { *axis = AXIS_SMALLESTSCREENWIDTHDP; @@ -309,6 +316,8 @@ AaptGroupEntry::getConfigValueForAxis(const ResTable_config& config, int axis) case AXIS_LANGUAGE: return (((uint32_t)config.country[1]) << 24) | (((uint32_t)config.country[0]) << 16) | (((uint32_t)config.language[1]) << 8) | (config.language[0]); + case AXIS_LAYOUTDIR: + return config.screenLayout&ResTable_config::MASK_LAYOUTDIR; case AXIS_SCREENLAYOUTSIZE: return config.screenLayout&ResTable_config::MASK_SCREENSIZE; case AXIS_ORIENTATION: @@ -364,7 +373,7 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType) Vector<String8> parts; String8 mcc, mnc, loc, layoutsize, layoutlong, orient, den; - String8 touch, key, keysHidden, nav, navHidden, size, vers; + String8 touch, key, keysHidden, nav, navHidden, size, layoutDir, vers; String8 uiModeType, uiModeNight, smallestwidthdp, widthdp, heightdp; const char *p = dir; @@ -452,6 +461,18 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType) //printf("not region: %s\n", part.string()); } + if (getLayoutDirectionName(part.string())) { + layoutDir = part; + + index++; + if (index == N) { + goto success; + } + part = parts[index]; + } else { + //printf("not layout direction: %s\n", part.string()); + } + if (getSmallestScreenWidthDpName(part.string())) { smallestwidthdp = part; @@ -674,6 +695,7 @@ success: this->navHidden = navHidden; this->navigation = nav; this->screenSize = size; + this->layoutDirection = layoutDir; this->version = vers; // what is this anyway? @@ -691,6 +713,8 @@ AaptGroupEntry::toString() const s += ","; s += this->locale; s += ","; + s += layoutDirection; + s += ","; s += smallestScreenWidthDp; s += ","; s += screenWidthDp; @@ -747,6 +771,12 @@ AaptGroupEntry::toDirName(const String8& resType) const } s += locale; } + if (this->layoutDirection != "") { + if (s.length() > 0) { + s += "-"; + } + s += layoutDirection; + } if (this->smallestScreenWidthDp != "") { if (s.length() > 0) { s += "-"; @@ -958,6 +988,28 @@ bool AaptGroupEntry::getLocaleName(const char* fileName, return false; } +bool AaptGroupEntry::getLayoutDirectionName(const char* name, ResTable_config* out) +{ + if (strcmp(name, kWildcardName) == 0) { + if (out) out->screenLayout = + (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR) + | ResTable_config::LAYOUTDIR_ANY; + return true; + } else if (strcmp(name, "ldltr") == 0) { + if (out) out->screenLayout = + (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR) + | ResTable_config::LAYOUTDIR_LTR; + return true; + } else if (strcmp(name, "ldrtl") == 0) { + if (out) out->screenLayout = + (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR) + | ResTable_config::LAYOUTDIR_RTL; + return true; + } + + return false; +} + bool AaptGroupEntry::getScreenLayoutSizeName(const char* name, ResTable_config* out) { @@ -1415,6 +1467,7 @@ int AaptGroupEntry::compare(const AaptGroupEntry& o) const int v = mcc.compare(o.mcc); if (v == 0) v = mnc.compare(o.mnc); if (v == 0) v = locale.compare(o.locale); + if (v == 0) v = layoutDirection.compare(o.layoutDirection); if (v == 0) v = vendor.compare(o.vendor); if (v == 0) v = smallestScreenWidthDp.compare(o.smallestScreenWidthDp); if (v == 0) v = screenWidthDp.compare(o.screenWidthDp); @@ -1447,6 +1500,7 @@ const ResTable_config& AaptGroupEntry::toParams() const getMccName(mcc.string(), ¶ms); getMncName(mnc.string(), ¶ms); getLocaleName(locale.string(), ¶ms); + getLayoutDirectionName(layoutDirection.string(), ¶ms); getSmallestScreenWidthDpName(smallestScreenWidthDp.string(), ¶ms); getScreenWidthDpName(screenWidthDp.string(), ¶ms); getScreenHeightDpName(screenHeightDp.string(), ¶ms); diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h index d5f296c..5cfa913 100644 --- a/tools/aapt/AaptAssets.h +++ b/tools/aapt/AaptAssets.h @@ -51,6 +51,7 @@ enum { AXIS_SMALLESTSCREENWIDTHDP, AXIS_SCREENWIDTHDP, AXIS_SCREENHEIGHTDP, + AXIS_LAYOUTDIR, AXIS_VERSION, AXIS_START = AXIS_MCC, @@ -95,6 +96,7 @@ public: static bool getSmallestScreenWidthDpName(const char* name, ResTable_config* out = NULL); static bool getScreenWidthDpName(const char* name, ResTable_config* out = NULL); static bool getScreenHeightDpName(const char* name, ResTable_config* out = NULL); + static bool getLayoutDirectionName(const char* name, ResTable_config* out = NULL); static bool getVersionName(const char* name, ResTable_config* out = NULL); int compare(const AaptGroupEntry& o) const; @@ -133,6 +135,7 @@ private: String8 navHidden; String8 navigation; String8 screenSize; + String8 layoutDirection; String8 version; mutable bool mParamsChanged; diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk index d9b0681..5b88669 100644 --- a/tools/aapt/Android.mk +++ b/tools/aapt/Android.mk @@ -20,6 +20,7 @@ LOCAL_SRC_FILES := \ StringPool.cpp \ XMLNode.cpp \ ResourceFilter.cpp \ + ResourceIdCache.cpp \ ResourceTable.cpp \ Images.cpp \ Resource.cpp \ diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index fde3bd6..5089b9d 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -38,6 +38,7 @@ typedef enum Command { kCommandRemove, kCommandPackage, kCommandCrunch, + kCommandSingleCrunch, } Command; /* @@ -62,6 +63,7 @@ public: mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL), mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL), mUseCrunchCache(false), mErrorOnFailedInsert(false), mOutputTextSymbols(NULL), + mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL), mArgc(0), mArgv(NULL) {} ~Bundle(void) {} @@ -176,6 +178,10 @@ public: bool getUseCrunchCache() const { return mUseCrunchCache; } const char* getOutputTextSymbols() const { return mOutputTextSymbols; } void setOutputTextSymbols(const char* val) { mOutputTextSymbols = val; } + const char* getSingleCrunchInputFile() const { return mSingleCrunchInputFile; } + void setSingleCrunchInputFile(const char* val) { mSingleCrunchInputFile = val; } + const char* getSingleCrunchOutputFile() const { return mSingleCrunchOutputFile; } + void setSingleCrunchOutputFile(const char* val) { mSingleCrunchOutputFile = val; } /* * Set and get the file specification. @@ -283,6 +289,8 @@ private: bool mUseCrunchCache; bool mErrorOnFailedInsert; const char* mOutputTextSymbols; + const char* mSingleCrunchInputFile; + const char* mSingleCrunchOutputFile; /* file specification */ int mArgc; diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index 0a5e590..c3a0930 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -7,6 +7,7 @@ #include "Bundle.h" #include "ResourceFilter.h" #include "ResourceTable.h" +#include "Images.h" #include "XMLNode.h" #include <utils/Log.h> @@ -1839,6 +1840,25 @@ int doCrunch(Bundle* bundle) return NO_ERROR; } +/* + * Do PNG Crunching on a single flag + * -i points to a single png file + * -o points to a single png output file + */ +int doSingleCrunch(Bundle* bundle) +{ + fprintf(stdout, "Crunching single PNG file: %s\n", bundle->getSingleCrunchInputFile()); + fprintf(stdout, "\tOutput file: %s\n", bundle->getSingleCrunchOutputFile()); + + String8 input(bundle->getSingleCrunchInputFile()); + String8 output(bundle->getSingleCrunchOutputFile()); + if (preProcessImageToCache(bundle, input, output) != NO_ERROR) { + // we can't return the status_t as it gets truncate to the lower 8 bits. + return 42; + } + return NO_ERROR; +} + char CONSOLE_DATA[2925] = { 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 46, 32, 32, 32, 32, 32, 32, 32, 32, 32, diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp index f398de0..32fecb2 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -85,7 +85,11 @@ void usage(void) " Add specified files to Zip-compatible archive.\n\n", gProgName); fprintf(stderr, " %s c[runch] [-v] -S resource-sources ... -C output-folder ...\n" - " Do PNG preprocessing and store the results in output folder.\n\n", gProgName); + " Do PNG preprocessing on one or several resource folders\n" + " and store the results in the output folder.\n\n", gProgName); + fprintf(stderr, + " %s s[ingleCrunch] [-v] -i input-file -o outputfile\n" + " Do PNG preprocessing on a single file.\n\n", gProgName); fprintf(stderr, " %s v[ersion]\n" " Print program version.\n\n", gProgName); @@ -203,13 +207,14 @@ int handleCommand(Bundle* bundle) // printf(" %d: '%s'\n", i, bundle->getFileSpecEntry(i)); switch (bundle->getCommand()) { - case kCommandVersion: return doVersion(bundle); - case kCommandList: return doList(bundle); - case kCommandDump: return doDump(bundle); - case kCommandAdd: return doAdd(bundle); - case kCommandRemove: return doRemove(bundle); - case kCommandPackage: return doPackage(bundle); - case kCommandCrunch: return doCrunch(bundle); + case kCommandVersion: return doVersion(bundle); + case kCommandList: return doList(bundle); + case kCommandDump: return doDump(bundle); + case kCommandAdd: return doAdd(bundle); + case kCommandRemove: return doRemove(bundle); + case kCommandPackage: return doPackage(bundle); + case kCommandCrunch: return doCrunch(bundle); + case kCommandSingleCrunch: return doSingleCrunch(bundle); default: fprintf(stderr, "%s: requested command not yet supported\n", gProgName); return 1; @@ -249,6 +254,8 @@ int main(int argc, char* const argv[]) bundle.setCommand(kCommandPackage); else if (argv[1][0] == 'c') bundle.setCommand(kCommandCrunch); + else if (argv[1][0] == 's') + bundle.setCommand(kCommandSingleCrunch); else { fprintf(stderr, "ERROR: Unknown command '%s'\n", argv[1]); wantUsage = true; @@ -427,6 +434,28 @@ int main(int argc, char* const argv[]) convertPath(argv[0]); bundle.setCrunchedOutputDir(argv[0]); break; + case 'i': + argc--; + argv++; + if (!argc) { + fprintf(stderr, "ERROR: No argument supplied for '-i' option\n"); + wantUsage = true; + goto bail; + } + convertPath(argv[0]); + bundle.setSingleCrunchInputFile(argv[0]); + break; + case 'o': + argc--; + argv++; + if (!argc) { + fprintf(stderr, "ERROR: No argument supplied for '-o' option\n"); + wantUsage = true; + goto bail; + } + convertPath(argv[0]); + bundle.setSingleCrunchOutputFile(argv[0]); + break; case '0': argc--; argv++; diff --git a/tools/aapt/Main.h b/tools/aapt/Main.h index d20c601..a6b39ac 100644 --- a/tools/aapt/Main.h +++ b/tools/aapt/Main.h @@ -29,6 +29,7 @@ extern int doAdd(Bundle* bundle); extern int doRemove(Bundle* bundle); extern int doPackage(Bundle* bundle); extern int doCrunch(Bundle* bundle); +extern int doSingleCrunch(Bundle* bundle); extern int calcPercent(long uncompressedLen, long compressedLen); diff --git a/tools/aapt/ResourceIdCache.cpp b/tools/aapt/ResourceIdCache.cpp new file mode 100644 index 0000000..e03f4f6 --- /dev/null +++ b/tools/aapt/ResourceIdCache.cpp @@ -0,0 +1,107 @@ +// +// Copyright 2012 The Android Open Source Project +// +// Manage a resource ID cache. + +#define LOG_TAG "ResourceIdCache" + +#include <utils/String16.h> +#include <utils/Log.h> +#include "ResourceIdCache.h" +#include <map> +using namespace std; + + +static size_t mHits = 0; +static size_t mMisses = 0; +static size_t mCollisions = 0; + +static const size_t MAX_CACHE_ENTRIES = 2048; +static const android::String16 TRUE16("1"); +static const android::String16 FALSE16("0"); + +struct CacheEntry { + // concatenation of the relevant strings into a single instance + android::String16 hashedName; + uint32_t id; + + CacheEntry() {} + CacheEntry(const android::String16& name, uint32_t resId) : hashedName(name), id(resId) { } +}; + +static map< uint32_t, CacheEntry > mIdMap; + + +// djb2; reasonable choice for strings when collisions aren't particularly important +static inline uint32_t hashround(uint32_t hash, int c) { + return ((hash << 5) + hash) + c; /* hash * 33 + c */ +} + +static uint32_t hash(const android::String16& hashableString) { + uint32_t hash = 5381; + const char16_t* str = hashableString.string(); + while (int c = *str++) hash = hashround(hash, c); + return hash; +} + +namespace android { + +static inline String16 makeHashableName(const android::String16& package, + const android::String16& type, + const android::String16& name, + bool onlyPublic) { + String16 hashable = String16(name); + hashable += type; + hashable += package; + hashable += (onlyPublic ? TRUE16 : FALSE16); + return hashable; +} + +uint32_t ResourceIdCache::lookup(const android::String16& package, + const android::String16& type, + const android::String16& name, + bool onlyPublic) { + const String16 hashedName = makeHashableName(package, type, name, onlyPublic); + const uint32_t hashcode = hash(hashedName); + map<uint32_t, CacheEntry>::iterator item = mIdMap.find(hashcode); + if (item == mIdMap.end()) { + // cache miss + mMisses++; + return 0; + } + + // legit match? + if (hashedName == (*item).second.hashedName) { + mHits++; + return (*item).second.id; + } + + // collision + mCollisions++; + mIdMap.erase(hashcode); + return 0; +} + +// returns the resource ID being stored, for callsite convenience +uint32_t ResourceIdCache::store(const android::String16& package, + const android::String16& type, + const android::String16& name, + bool onlyPublic, + uint32_t resId) { + if (mIdMap.size() < MAX_CACHE_ENTRIES) { + const String16 hashedName = makeHashableName(package, type, name, onlyPublic); + const uint32_t hashcode = hash(hashedName); + mIdMap[hashcode] = CacheEntry(hashedName, resId); + } + return resId; +} + +void ResourceIdCache::dump() { + printf("ResourceIdCache dump:\n"); + printf("Size: %ld\n", mIdMap.size()); + printf("Hits: %ld\n", mHits); + printf("Misses: %ld\n", mMisses); + printf("(Collisions: %ld)\n", mCollisions); +} + +} diff --git a/tools/aapt/ResourceIdCache.h b/tools/aapt/ResourceIdCache.h new file mode 100644 index 0000000..65f7781 --- /dev/null +++ b/tools/aapt/ResourceIdCache.h @@ -0,0 +1,30 @@ +// +// Copyright 2012 The Android Open Source Project +// +// Manage a resource ID cache. + +#ifndef RESOURCE_ID_CACHE_H +#define RESOURCE_ID_CACHE_H + +namespace android { +class android::String16; + +class ResourceIdCache { +public: + static uint32_t lookup(const android::String16& package, + const android::String16& type, + const android::String16& name, + bool onlyPublic); + + static uint32_t store(const android::String16& package, + const android::String16& type, + const android::String16& name, + bool onlyPublic, + uint32_t resId); + + static void dump(void); +}; + +} + +#endif diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index d98fe65..52ebaf0 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -8,6 +8,7 @@ #include "XMLNode.h" #include "ResourceFilter.h" +#include "ResourceIdCache.h" #include <androidfw/ResourceTypes.h> #include <utils/ByteOrder.h> @@ -1998,6 +1999,9 @@ uint32_t ResourceTable::getResId(const String16& package, const String16& name, bool onlyPublic) const { + uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic); + if (id != 0) return id; // cache hit + sp<Package> p = mPackages.valueFor(package); if (p == NULL) return 0; @@ -2016,11 +2020,10 @@ uint32_t ResourceTable::getResId(const String16& package, } if (Res_INTERNALID(rid)) { - return rid; + return ResourceIdCache::store(package, type, name, onlyPublic, rid); } - return Res_MAKEID(p->getAssignedId()-1, - Res_GETTYPE(rid), - Res_GETENTRY(rid)); + return ResourceIdCache::store(package, type, name, onlyPublic, + Res_MAKEID(p->getAssignedId()-1, Res_GETTYPE(rid), Res_GETENTRY(rid))); } sp<Type> t = p->getTypes().valueFor(type); @@ -2029,7 +2032,9 @@ uint32_t ResourceTable::getResId(const String16& package, if (c == NULL) return 0; int32_t ei = c->getEntryIndex(); if (ei < 0) return 0; - return getResId(p, t, ei); + + return ResourceIdCache::store(package, type, name, onlyPublic, + getResId(p, t, ei)); } uint32_t ResourceTable::getResId(const String16& ref, @@ -2811,7 +2816,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c " "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " - "sw%ddp w%ddp h%ddp\n", + "sw%ddp w%ddp h%ddp dir:%d\n", ti+1, config.mcc, config.mnc, config.language[0] ? config.language[0] : '-', @@ -2829,7 +2834,8 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) config.screenHeight, config.smallestScreenWidthDp, config.screenWidthDp, - config.screenHeightDp)); + config.screenHeightDp, + config.layoutDirection)); if (filterable && !filter.match(config)) { continue; @@ -2853,7 +2859,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) tHeader->config = config; NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c " "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " - "sw%ddp w%ddp h%ddp\n", + "sw%ddp w%ddp h%ddp dir:%d\n", ti+1, tHeader->config.mcc, tHeader->config.mnc, tHeader->config.language[0] ? tHeader->config.language[0] : '-', @@ -2871,7 +2877,8 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) tHeader->config.screenHeight, tHeader->config.smallestScreenWidthDp, tHeader->config.screenWidthDp, - tHeader->config.screenHeightDp)); + tHeader->config.screenHeightDp, + tHeader->config.layoutDirection)); tHeader->config.swapHtoD(); // Build the entries inside of this type. @@ -3489,7 +3496,7 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, if (config != NULL) { NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c " "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " - "sw%ddp w%ddp h%ddp\n", + "sw%ddp w%ddp h%ddp dir:%d\n", sourcePos.file.string(), sourcePos.line, config->mcc, config->mnc, config->language[0] ? config->language[0] : '-', @@ -3506,7 +3513,8 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, config->screenHeight, config->smallestScreenWidthDp, config->screenWidthDp, - config->screenHeightDp)); + config->screenHeightDp, + config->layoutDirection)); } else { NOISY(printf("New entry at %s:%d: NULL config\n", sourcePos.file.string(), sourcePos.line)); |