summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorJosh Guilfoyle <Josh.Guilfoyle@T-Mobile.com>2009-11-19 17:43:25 -0800
committerJosh Guilfoyle <Josh.Guilfoyle@T-Mobile.com>2009-11-24 13:29:47 -0800
commit6fff487e464c7cb044ffac0e1dd73d353c82f2ee (patch)
tree2dd74850f731150b32759a1ee47c1341e72550bd /libs
parent9db3d07b9620b4269ab33f78604a36327e536ce1 (diff)
parent9effa6dbd3c7d95e243fcc694f80f2628eac95ca (diff)
downloadframeworks_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.mk2
-rw-r--r--libs/utils/AssetManager.cpp209
-rw-r--r--libs/utils/ResourceTypes.cpp233
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