From de898ff42912bd7ca1bfb099cd439562496765a4 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Wed, 29 Jan 2014 18:20:45 -0800 Subject: Shared library resource support Shared libraries can now export resources for applications to use. Exporting resources works the same way the framework exports resources, by defining the public symbols in res/values/public.xml. Building a shared library requires aapt to be invoked with the --shared-lib option. Shared libraries will be assigned a package ID of 0x00 at build-time. At runtime, all loaded shared libraries will be assigned a new package ID. Currently, shared libraries should not import other shared libraries, as those dependencies will not be loaded at runtime. At runtime, reflection is used to update the package ID of resource symbols in the shared library's R class file. The package name of the R class file is assumed to be the same as the shared library's package name declared in its manifest. This will be customizable in a future commit. See /tests/SharedLibrary/ for examples of a shared library and its client. Bug:12724178 Change-Id: I60c0cb8ab87849f8f8a1a13431562fe8603020a7 --- libs/androidfw/AssetManager.cpp | 45 ++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'libs/androidfw/AssetManager.cpp') diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index 64363d475a93..91dda75026ab 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -74,6 +74,7 @@ static const char* kAssetsRoot = "assets"; static const char* kAppZipName = NULL; //"classes.jar"; static const char* kSystemAssets = "framework/framework-res.apk"; static const char* kResourceCache = "resource-cache"; +static const char* kAndroidManifest = "AndroidManifest.xml"; static const char* kExcludeExtension = ".EXCLUDE"; @@ -205,6 +206,16 @@ bool AssetManager::addAssetPath(const String8& path, int32_t* cookie) ALOGV("In %p Asset %s path: %s", this, ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string()); + // Check that the path has an AndroidManifest.xml + Asset* manifestAsset = const_cast(this)->openNonAssetInPathLocked( + kAndroidManifest, Asset::ACCESS_BUFFER, ap); + if (manifestAsset == NULL) { + // This asset path does not contain any resources. + delete manifestAsset; + return false; + } + delete manifestAsset; + mAssetPaths.add(ap); // new paths are always added at the end @@ -461,7 +472,7 @@ Asset* AssetManager::open(const char* fileName, AccessMode mode) * The "fileName" is the partial path starting from the application * name. */ -Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode) +Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode, int32_t* outCookie) { AutoMutex _l(mLock); @@ -482,6 +493,7 @@ Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode) Asset* pAsset = openNonAssetInPathLocked( fileName, mode, mAssetPaths.itemAt(i)); if (pAsset != NULL) { + if (outCookie != NULL) *outCookie = static_cast(i + 1); return pAsset != kExcludedAsset ? pAsset : NULL; } } @@ -556,9 +568,14 @@ const ResTable* AssetManager::getResTable(bool required) const LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager"); } - if (mCacheMode != CACHE_OFF && !mCacheValid) + if (mCacheMode != CACHE_OFF && !mCacheValid) { const_cast(this)->loadFileNameCacheLocked(); + } + + mResources = new ResTable(); + updateResourceParamsLocked(); + bool onlyEmptyResources = true; const size_t N = mAssetPaths.size(); for (size_t i=0; iadd(sharedRes); + mResources->add(sharedRes); } else { ALOGV("Parsing resources for %s", ap.path.string()); - rt->add(ass, i + 1, !shared, idmap); + mResources->add(ass, i + 1, !shared, idmap); } + onlyEmptyResources = false; if (!shared) { delete ass; } + } else { + ALOGW("Installing empty resources in to table %p\n", mResources); + mResources->addEmpty(i + 1); } + if (idmap != NULL) { delete idmap; } MY_TRACE_END(); } - if (required && !rt) ALOGW("Unable to find resources file resources.arsc"); - if (!rt) { - mResources = rt = new ResTable(); + if (required && onlyEmptyResources) { + ALOGW("Unable to find resources file resources.arsc"); + delete mResources; + mResources = NULL; } - return rt; + + return mResources; } void AssetManager::updateResourceParamsLocked() const -- cgit v1.2.3-59-g8ed1b