diff options
author | Josh Guilfoyle <Josh.Guilfoyle@T-Mobile.com> | 2009-11-19 17:43:25 -0800 |
---|---|---|
committer | Josh Guilfoyle <Josh.Guilfoyle@T-Mobile.com> | 2009-11-24 13:29:47 -0800 |
commit | 6fff487e464c7cb044ffac0e1dd73d353c82f2ee (patch) | |
tree | 2dd74850f731150b32759a1ee47c1341e72550bd /libs | |
parent | 9db3d07b9620b4269ab33f78604a36327e536ce1 (diff) | |
parent | 9effa6dbd3c7d95e243fcc694f80f2628eac95ca (diff) | |
download | frameworks_base-6fff487e464c7cb044ffac0e1dd73d353c82f2ee.zip frameworks_base-6fff487e464c7cb044ffac0e1dd73d353c82f2ee.tar.gz frameworks_base-6fff487e464c7cb044ffac0e1dd73d353c82f2ee.tar.bz2 |
Merge branch 'themes-1.5r2' into themes-eclair
Conflicts:
api/current.xml
core/java/android/app/ActivityThread.java
core/java/android/app/ApplicationContext.java
core/java/android/app/Dialog.java
core/java/android/app/SearchDialog.java
core/java/android/content/Context.java
core/java/android/content/Intent.java
core/java/android/content/pm/PackageInfo.java
core/java/android/content/pm/PackageParser.java
core/java/android/content/res/Configuration.java
core/java/android/content/res/Resources.java
core/java/android/widget/RemoteViews.java
core/java/android/widget/TabWidget.java
core/java/com/android/internal/os/ZygoteInit.java
core/jni/android_util_AssetManager.cpp
core/res/AndroidManifest.xml
core/res/res/layout/search_dropdown_item_2line.xml
core/res/res/layout/select_dialog_item.xml
core/res/res/layout/select_dialog_multichoice.xml
core/res/res/layout/select_dialog_singlechoice.xml
core/res/res/layout/tab_indicator.xml
core/res/res/values/attrs.xml
core/res/res/values/public.xml
core/res/res/values/strings.xml
core/res/res/values/themes.xml
libs/utils/Android.mk
libs/utils/AssetManager.cpp
media/java/android/media/RingtoneManager.java
services/java/com/android/server/PackageManagerService.java
services/java/com/android/server/SystemServer.java
services/java/com/android/server/am/ActivityManagerService.java
services/java/com/android/server/status/StatusBarService.java
tools/aapt/Main.cpp
Diffstat (limited to 'libs')
-rw-r--r-- | libs/utils/Android.mk | 2 | ||||
-rw-r--r-- | libs/utils/AssetManager.cpp | 209 | ||||
-rw-r--r-- | libs/utils/ResourceTypes.cpp | 233 |
3 files changed, 370 insertions, 74 deletions
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk index 59409a2..1e3c190 100644 --- a/libs/utils/Android.mk +++ b/libs/utils/Android.mk @@ -41,6 +41,8 @@ commonSources:= \ ZipFileCRO.cpp \ ZipFileRO.cpp \ ZipUtils.cpp \ + ../../tools/aapt/ZipFile.cpp \ + ../../tools/aapt/ZipEntry.cpp \ misc.cpp diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp index 5a05e6a..058c76c 100644 --- a/libs/utils/AssetManager.cpp +++ b/libs/utils/AssetManager.cpp @@ -122,7 +122,7 @@ bool AssetManager::addAssetPath(const String8& path, void** cookie) return true; } } - + LOGV("In %p Asset %s path: %s", this, ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string()); @@ -185,7 +185,7 @@ void AssetManager::setLocaleLocked(const char* locale) delete[] mLocale; } mLocale = strdupNew(locale); - + updateResourceParamsLocked(); } @@ -392,79 +392,87 @@ const ResTable* AssetManager::getResTable(bool required) const if (mCacheMode != CACHE_OFF && !mCacheValid) const_cast<AssetManager*>(this)->loadFileNameCacheLocked(); - const size_t N = mAssetPaths.size(); - for (size_t i=0; i<N; i++) { - Asset* ass = NULL; - ResTable* sharedRes = NULL; - bool shared = true; - const asset_path& ap = mAssetPaths.itemAt(i); - LOGV("Looking for resource asset in '%s'\n", ap.path.string()); - if (ap.type != kFileTypeDirectory) { - if (i == 0) { - // The first item is typically the framework resources, - // which we want to avoid parsing every time. - sharedRes = const_cast<AssetManager*>(this)-> - mZipSet.getZipResourceTable(ap.path); - } - if (sharedRes == NULL) { + mResources = rt = new ResTable(); + + if (rt) { + const size_t N = mAssetPaths.size(); + for (size_t i=0; i<N; i++) { + const asset_path& ap = mAssetPaths.itemAt(i); + updateResTableFromAssetPath(rt, ap, (void*)(i+1)); + } + } + + if (required && !rt) LOGW("Unable to find resources file resources.arsc"); + if (!rt) { + mResources = rt = new ResTable(); + } + + return rt; +} + +void AssetManager::updateResTableFromAssetPath(ResTable *rt, const asset_path& ap, void *cookie) const +{ + Asset* ass = NULL; + ResTable* sharedRes = NULL; + bool shared = true; + size_t cookiePos = (size_t)cookie; + LOGV("Looking for resource asset in '%s'\n", ap.path.string()); + if (ap.type != kFileTypeDirectory) { + if (cookiePos == 1) { + // The first item is typically the framework resources, + // which we want to avoid parsing every time. + sharedRes = const_cast<AssetManager*>(this)-> + mZipSet.getZipResourceTable(ap.path); + } + if (sharedRes == NULL) { + ass = const_cast<AssetManager*>(this)-> + mZipSet.getZipResourceTableAsset(ap.path); + if (ass == NULL) { + LOGV("loading resource table %s\n", ap.path.string()); ass = const_cast<AssetManager*>(this)-> - mZipSet.getZipResourceTableAsset(ap.path); - if (ass == NULL) { - LOGV("loading resource table %s\n", ap.path.string()); + openNonAssetInPathLocked("resources.arsc", + Asset::ACCESS_BUFFER, + ap); + if (ass != NULL && ass != kExcludedAsset) { ass = const_cast<AssetManager*>(this)-> - openNonAssetInPathLocked("resources.arsc", - Asset::ACCESS_BUFFER, - ap); - if (ass != NULL && ass != kExcludedAsset) { - ass = const_cast<AssetManager*>(this)-> - mZipSet.setZipResourceTableAsset(ap.path, ass); - } - } - - if (i == 0 && ass != NULL) { - // If this is the first resource table in the asset - // manager, then we are going to cache it so that we - // can quickly copy it out for others. - LOGV("Creating shared resources for %s", ap.path.string()); - sharedRes = new ResTable(); - sharedRes->add(ass, (void*)(i+1), false); - sharedRes = const_cast<AssetManager*>(this)-> - mZipSet.setZipResourceTable(ap.path, sharedRes); + mZipSet.setZipResourceTableAsset(ap.path, ass); } } - } else { - LOGV("loading resource table %s\n", ap.path.string()); - Asset* ass = const_cast<AssetManager*>(this)-> - openNonAssetInPathLocked("resources.arsc", - Asset::ACCESS_BUFFER, - ap); - shared = false; - } - if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) { - if (rt == NULL) { - mResources = rt = new ResTable(); - updateResourceParamsLocked(); - } - LOGV("Installing resource asset %p in to table %p\n", ass, mResources); - if (sharedRes != NULL) { - LOGV("Copying existing resources for %s", ap.path.string()); - rt->add(sharedRes); - } else { - LOGV("Parsing resources for %s", ap.path.string()); - rt->add(ass, (void*)(i+1), !shared); - } - if (!shared) { - delete ass; + if (cookiePos == 0 && ass != NULL) { + // If this is the first resource table in the asset + // manager, then we are going to cache it so that we + // can quickly copy it out for others. + LOGV("Creating shared resources for %s", ap.path.string()); + sharedRes = new ResTable(); + sharedRes->add(ass, cookie, false); + sharedRes = const_cast<AssetManager*>(this)-> + mZipSet.setZipResourceTable(ap.path, sharedRes); } } + } else { + LOGV("loading resource table %s\n", ap.path.string()); + Asset* ass = const_cast<AssetManager*>(this)-> + openNonAssetInPathLocked("resources.arsc", + Asset::ACCESS_BUFFER, + ap); + shared = false; } + if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) { + updateResourceParamsLocked(); + LOGV("Installing resource asset %p in to table %p\n", ass, mResources); + if (sharedRes != NULL) { + LOGV("Copying existing resources for %s", ap.path.string()); + rt->add(sharedRes); + } else { + LOGV("Parsing resources for %s", ap.path.string()); + rt->add(ass, cookie, !shared); + } - if (required && !rt) LOGW("Unable to find resources file resources.arsc"); - if (!rt) { - mResources = rt = new ResTable(); + if (!shared) { + delete ass; + } } - return rt; } void AssetManager::updateResourceParamsLocked() const @@ -617,7 +625,7 @@ Asset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode m /* look at the filesystem on disk */ String8 path(createPathNameLocked(ap, locale, vendor)); path.appendPath(fileName); - + String8 excludeName(path); excludeName.append(kExcludeExtension); if (::getFileType(excludeName.string()) != kFileTypeNonexistent) { @@ -625,28 +633,28 @@ Asset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode m //printf("+++ excluding '%s'\n", (const char*) excludeName); return kExcludedAsset; } - + pAsset = openAssetFromFileLocked(path, mode); - + if (pAsset == NULL) { /* try again, this time with ".gz" */ path.append(".gz"); pAsset = openAssetFromFileLocked(path, mode); } - + if (pAsset != NULL) pAsset->setAssetSource(path); } else { /* find in cache */ String8 path(createPathNameLocked(ap, locale, vendor)); path.appendPath(fileName); - + AssetDir::FileInfo tmpInfo; bool found = false; - + String8 excludeName(path); excludeName.append(kExcludeExtension); - + if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) { /* go no farther */ //printf("+++ Excluding '%s'\n", (const char*) excludeName); @@ -1465,7 +1473,7 @@ bool AssetManager::fncScanAndMergeDirLocked( // XXX This is broken -- the filename cache needs to hold the base // asset path separately from its filename. - + partialPath = createPathNameLocked(ap, locale, vendor); if (dirName[0] != '\0') { partialPath.appendPath(dirName); @@ -1759,3 +1767,58 @@ int AssetManager::ZipSet::getIndex(const String8& zip) const return mZipPath.size()-1; } +bool AssetManager::updateWithAssetPath(const String8& path, void** cookie) +{ + bool res = addAssetPath(path, cookie); + ResTable* rt = mResources; + if (res && rt != NULL && ((size_t)*cookie == mAssetPaths.size())) { + AutoMutex _l(mLock); + const asset_path& ap = mAssetPaths.itemAt((size_t)*cookie - 1); + updateResTableFromAssetPath(rt, ap, *cookie); + } + return res; +} + +bool AssetManager::removeAssetPath(const String8 &packageName, const String8 &assetPath) +{ + AutoMutex _l(mLock); + + String8 realPath(assetPath); + if (kAppZipName) { + realPath.appendPath(kAppZipName); + } + + // Check if the path exists. + size_t cookie = 0; + for (size_t i = 0; i < mAssetPaths.size(); i++) { + if (strcmp(mAssetPaths[i].path, realPath) == 0) { + mAssetPaths.removeAt(i); + cookie = i + 1; + break; + } + } + + if (cookie == 0) { + return false; + } + + ResTable* rt = mResources; + if (rt == NULL) { + LOGV("ResTable must not be NULL"); + return false; + } + + rt->removeAssetsByCookie(packageName, (void *)cookie); + + return true; +} + +void AssetManager::dumpRes() +{ + ResTable* rt = mResources; + if (rt == NULL) { + fprintf(stderr, "ResTable must not be NULL"); + return; + } + rt->dump(); +} diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index 872b2bc..5725ffa 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -62,6 +62,8 @@ namespace android { #endif #endif +#define PACKAGE_RESOURCE_ID_TO_DUMP 10 + static void printToLogFunc(void* cookie, const char* txt) { LOGV("%s", txt); @@ -1304,6 +1306,29 @@ ResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi) return newpi; } +void ResTable::Theme::setAttributeValue(uint32_t attrID, uint32_t value) +{ + const ssize_t p = mTable.getResourcePackageIndex(attrID); + const uint32_t t = Res_GETTYPE(attrID); + const uint32_t e = Res_GETENTRY(attrID); + + TABLE_NOISY(LOGV("Looking up attr 0x%08x in theme %p", attrID, this)); + + if (p >= 0) { + const package_info* const pi = mPackages[p]; + if (pi != NULL) { + if (t < pi->numTypes) { + const type_info& ti = pi->types[t]; + if (e < ti.numEntries) { + theme_entry& te = ti.entries[e]; + te.value.data = value; + te.value.dataType = Res_value::TYPE_FIRST_INT; + } + } + } + } +} + status_t ResTable::Theme::applyStyle(uint32_t resID, bool force) { const bag_entry* bag; @@ -3889,9 +3914,61 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, return NO_ERROR; } -#ifndef HAVE_ANDROID_OS +void ResTable::removeAssetsByCookie(const String8 &packageName, void* cookie) +{ + mError = NO_ERROR; + + size_t N = mHeaders.size(); + for (size_t i = 0; i < N; i++) { + Header* header = mHeaders[i]; + if ((size_t)header->cookie == (size_t)cookie) { + if (header->ownedData != NULL) { + free(header->ownedData); + } + mHeaders.removeAt(i); + break; + } + } + size_t pgCount = mPackageGroups.size(); + for (size_t pgIndex = 0; pgIndex < pgCount; pgIndex++) { + PackageGroup* pg = mPackageGroups[pgIndex]; + + size_t pkgCount = pg->packages.size(); + size_t index = pkgCount; + for (size_t pkgIndex = 0; pkgIndex < pkgCount; pkgIndex++) { + const Package* pkg = pg->packages[pkgIndex]; + if (String8(String16(pkg->package->name)).compare(packageName) == 0) { + index = pkgIndex; + LOGV("Delete Package %d id=%d name=%s\n", + (int)pkgIndex, pkg->package->id, + String8(String16(pkg->package->name)).string()); + break; + } + } + if (index < pkgCount) { + const Package* pkg = pg->packages[index]; + uint32_t id = dtohl(pkg->package->id); + if (id != 0 && id < 256) { + mPackageMap[id] = 0; + } + pg->packages.removeAt(index); + delete pkg; + if (pkgCount == 1) { + LOGV("Delete Package Group %d id=%d packageCount=%d name=%s\n", + (int)pgIndex, pg->id, (int)pg->packages.size(), + String8(pg->name).string()); + mPackageGroups.removeAt(pgIndex); + } + delete pg; + return; + } + } +} + #define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string()) +#ifndef HAVE_ANDROID_OS + #define CHAR16_ARRAY_EQ(constant, var, len) \ ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len)))) @@ -4165,4 +4242,158 @@ void ResTable::print(bool inclValues) const #endif // HAVE_ANDROID_OS +void ResTable::dump() const +{ + LOGI("mError=0x%x (%s)\n", mError, strerror(mError)); +#if 0 + LOGI("mParams=%c%c-%c%c,\n", + mParams.language[0], mParams.language[1], + mParams.country[0], mParams.country[1]); +#endif + size_t pgCount = mPackageGroups.size(); + LOGI("Package Groups (%d)\n", (int)pgCount); + for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) { + const PackageGroup* pg = mPackageGroups[pgIndex]; + LOGI("Package Group %d id=%d packageCount=%d name=%s\n", + (int)pgIndex, pg->id, (int)pg->packages.size(), + String8(pg->name).string()); + + size_t pkgCount = pg->packages.size(); + for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) { + const Package* pkg = pg->packages[pkgIndex]; + if (pkg->package->id != PACKAGE_RESOURCE_ID_TO_DUMP) continue; // HACK! + size_t count = 0; + size_t typeCount = pkg->types.size(); + LOGI(" Package %d id=%d name=%s typeCount=%d\n", (int)pkgIndex, + pkg->package->id, String8(String16(pkg->package->name)).string(), + (int)typeCount); + for (size_t typeIndex=0; typeIndex<typeCount&&count<10; typeIndex++) { + const Type* typeConfigs = pkg->getType(typeIndex); + if (typeConfigs == NULL) { + LOGI(" type %d NULL\n", (int)typeIndex); + continue; + } + const size_t NTC = typeConfigs->configs.size(); + LOGI(" type %d configCount=%d entryCount=%d\n", + (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount); + if (typeConfigs->typeSpecFlags != NULL) { + for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount&&count<10; entryIndex++) { + uint32_t resID = (0xff000000 & ((pkg->package->id)<<24)) + | (0x00ff0000 & ((typeIndex+1)<<16)) + | (0x0000ffff & (entryIndex)); + resource_name resName; + this->getResourceName(resID, &resName); + count++; + LOGI(" spec resource 0x%08x %s:%s/%s: flags=0x%08x\n", + resID, + CHAR16_TO_CSTR(resName.package, resName.packageLen), + CHAR16_TO_CSTR(resName.type, resName.typeLen), + CHAR16_TO_CSTR(resName.name, resName.nameLen), + dtohl(typeConfigs->typeSpecFlags[entryIndex])); + } + } + for (size_t configIndex=0; configIndex<NTC&&count<10; configIndex++) { + const ResTable_type* type = typeConfigs->configs[configIndex]; + if ((((uint64_t)type)&0x3) != 0) { + LOGI(" NON-INTEGER ResTable_type ADDRESS: %p\n", type); + continue; + } + count++; + LOGI(" config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d\n", + (int)configIndex, + type->config.language[0] ? type->config.language[0] : '-', + type->config.language[1] ? type->config.language[1] : '-', + type->config.country[0] ? type->config.country[0] : '-', + type->config.country[1] ? type->config.country[1] : '-', + type->config.orientation, + type->config.touchscreen, + dtohs(type->config.density), + type->config.keyboard, + type->config.inputFlags, + type->config.navigation, + dtohs(type->config.screenWidth), + dtohs(type->config.screenHeight)); + size_t entryCount = dtohl(type->entryCount); + uint32_t entriesStart = dtohl(type->entriesStart); + if ((entriesStart&0x3) != 0) { + LOGI(" NON-INTEGER ResTable_type entriesStart OFFSET: %p\n", (void*)entriesStart); + continue; + } + uint32_t typeSize = dtohl(type->header.size); + if ((typeSize&0x3) != 0) { + LOGI(" NON-INTEGER ResTable_type header.size: %p\n", (void*)typeSize); + continue; + } + for (size_t entryIndex=0; entryIndex<entryCount&&count<10; entryIndex++) { + const uint8_t* const end = ((const uint8_t*)type) + + dtohl(type->header.size); + const uint32_t* const eindex = (const uint32_t*) + (((const uint8_t*)type) + dtohs(type->header.headerSize)); + uint32_t thisOffset = dtohl(eindex[entryIndex]); + if (thisOffset == ResTable_type::NO_ENTRY) { + continue; + } + + uint32_t resID = (0xff000000 & ((pkg->package->id)<<24)) + | (0x00ff0000 & ((typeIndex+1)<<16)) + | (0x0000ffff & (entryIndex)); + resource_name resName; + this->getResourceName(resID, &resName); + count++; + LOGI(" resource 0x%08x %s:%s/%s: ", resID, + CHAR16_TO_CSTR(resName.package, resName.packageLen), + CHAR16_TO_CSTR(resName.type, resName.typeLen), + CHAR16_TO_CSTR(resName.name, resName.nameLen)); + if ((thisOffset&0x3) != 0) { + LOGI("NON-INTEGER OFFSET: %p\n", (void*)thisOffset); + continue; + } + if ((thisOffset+sizeof(ResTable_entry)) > typeSize) { + LOGI("OFFSET OUT OF BOUNDS: %p+%p (size is %p)\n", + (void*)entriesStart, (void*)thisOffset, + (void*)typeSize); + continue; + } + + const ResTable_entry* ent = (const ResTable_entry*) + (((const uint8_t*)type) + entriesStart + thisOffset); + if (((entriesStart + thisOffset)&0x3) != 0) { + LOGI("NON-INTEGER ResTable_entry OFFSET: %p\n", + (void*)(entriesStart + thisOffset)); + continue; + } + if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) { + LOGI("<bag>"); + } else { + uint16_t esize = dtohs(ent->size); + if ((esize&0x3) != 0) { + LOGI("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize); + continue; + } + if ((thisOffset+esize) > typeSize) { + LOGI("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n", + (void*)entriesStart, (void*)thisOffset, + (void*)esize, (void*)typeSize); + continue; + } + + const Res_value* value = (const Res_value*) + (((const uint8_t*)ent) + esize); + count++; + LOGI("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)", + (int)value->dataType, (int)dtohl(value->data), + (int)dtohs(value->size), (int)value->res0); + } + + if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) { + LOGI(" (PUBLIC)"); + } + LOGI("\n"); + } + } + } + } + } +} + } // namespace android |