AssetManager.cpp revision 91447d88f2bdf9c2bf8d1a53570efef6172fba74
116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Copyright (C) 2006 The Android Open Source Project 316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * you may not use this file except in compliance with the License. 616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * You may obtain a copy of the License at 716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 1016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Unless required by applicable law or agreed to in writing, software 1116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 1216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * See the License for the specific language governing permissions and 1416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * limitations under the License. 1516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 1616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 1716c4d154dca43c662571129af31b27433b919a32Adam Lesinski// 1816c4d154dca43c662571129af31b27433b919a32Adam Lesinski// Provide access to read-only assets. 1916c4d154dca43c662571129af31b27433b919a32Adam Lesinski// 2016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 2116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define LOG_TAG "asset" 2216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define ATRACE_TAG ATRACE_TAG_RESOURCES 2316c4d154dca43c662571129af31b27433b919a32Adam Lesinski//#define LOG_NDEBUG 0 2416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 2516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <androidfw/Asset.h> 2616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <androidfw/AssetDir.h> 2716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <androidfw/AssetManager.h> 2816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <androidfw/misc.h> 2916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <androidfw/ResourceTypes.h> 3016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <androidfw/ZipFileRO.h> 3116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/Atomic.h> 3216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/Log.h> 3316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/String8.h> 3416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/String8.h> 3516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/threads.h> 3616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/Timers.h> 3716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifdef HAVE_ANDROID_OS 3816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <cutils/trace.h> 3916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 4016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 4116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <assert.h> 4216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <dirent.h> 4316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <errno.h> 4416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <fcntl.h> 4516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <strings.h> 4616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <sys/stat.h> 4716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <unistd.h> 4816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 4916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifndef TEMP_FAILURE_RETRY 5016c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* Used to retry syscalls that can return EINTR. */ 5116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define TEMP_FAILURE_RETRY(exp) ({ \ 5216c4d154dca43c662571129af31b27433b919a32Adam Lesinski typeof (exp) _rc; \ 5316c4d154dca43c662571129af31b27433b919a32Adam Lesinski do { \ 5416c4d154dca43c662571129af31b27433b919a32Adam Lesinski _rc = (exp); \ 5516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } while (_rc == -1 && errno == EINTR); \ 5616c4d154dca43c662571129af31b27433b919a32Adam Lesinski _rc; }) 5716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 5816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 5916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifdef HAVE_ANDROID_OS 6016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define MY_TRACE_BEGIN(x) ATRACE_BEGIN(x) 6116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define MY_TRACE_END() ATRACE_END() 6216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#else 6316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define MY_TRACE_BEGIN(x) 6416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define MY_TRACE_END() 6516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 6616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 6716c4d154dca43c662571129af31b27433b919a32Adam Lesinskiusing namespace android; 6816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 6916c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 7016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Names for default app, locale, and vendor. We might want to change 7116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * these to be an actual locale, e.g. always use en-US as the default. 7216c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 7316c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatic const char* kDefaultLocale = "default"; 7416c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatic const char* kDefaultVendor = "default"; 7516c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatic const char* kAssetsRoot = "assets"; 7616c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatic const char* kAppZipName = NULL; //"classes.jar"; 7716c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatic const char* kSystemAssets = "framework/framework-res.apk"; 7816c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatic const char* kIdmapCacheDir = "resource-cache"; 7916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 8016c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatic const char* kExcludeExtension = ".EXCLUDE"; 8116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 8216c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatic Asset* const kExcludedAsset = (Asset*) 0xd000000d; 8316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 8416c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatic volatile int32_t gCount = 0; 8516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 8616c4d154dca43c662571129af31b27433b919a32Adam Lesinskinamespace { 8716c4d154dca43c662571129af31b27433b919a32Adam Lesinski // Transform string /a/b/c.apk to /data/resource-cache/a@b@c.apk@idmap 8816c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 idmapPathForPackagePath(const String8& pkgPath) 8916c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 9016c4d154dca43c662571129af31b27433b919a32Adam Lesinski const char* root = getenv("ANDROID_DATA"); 9116c4d154dca43c662571129af31b27433b919a32Adam Lesinski LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_DATA not set"); 9216c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 path(root); 9316c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath(kIdmapCacheDir); 9416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 9516c4d154dca43c662571129af31b27433b919a32Adam Lesinski char buf[256]; // 256 chars should be enough for anyone... 9616c4d154dca43c662571129af31b27433b919a32Adam Lesinski strncpy(buf, pkgPath.string(), 255); 9716c4d154dca43c662571129af31b27433b919a32Adam Lesinski buf[255] = '\0'; 9816c4d154dca43c662571129af31b27433b919a32Adam Lesinski char* filename = buf; 9916c4d154dca43c662571129af31b27433b919a32Adam Lesinski while (*filename && *filename == '/') { 10016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ++filename; 10116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 10216c4d154dca43c662571129af31b27433b919a32Adam Lesinski char* p = filename; 10316c4d154dca43c662571129af31b27433b919a32Adam Lesinski while (*p) { 10416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (*p == '/') { 10516c4d154dca43c662571129af31b27433b919a32Adam Lesinski *p = '@'; 10616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 10716c4d154dca43c662571129af31b27433b919a32Adam Lesinski ++p; 10816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 10916c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath(filename); 11016c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.append("@idmap"); 11116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 11216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return path; 11316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 11416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 11516c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 11616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Like strdup(), but uses C++ "new" operator instead of malloc. 11716c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 11816c4d154dca43c662571129af31b27433b919a32Adam Lesinski static char* strdupNew(const char* str) 11916c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 12016c4d154dca43c662571129af31b27433b919a32Adam Lesinski char* newStr; 12116c4d154dca43c662571129af31b27433b919a32Adam Lesinski int len; 12216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 12316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (str == NULL) 12416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return NULL; 12516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 12616c4d154dca43c662571129af31b27433b919a32Adam Lesinski len = strlen(str); 12716c4d154dca43c662571129af31b27433b919a32Adam Lesinski newStr = new char[len+1]; 12816c4d154dca43c662571129af31b27433b919a32Adam Lesinski memcpy(newStr, str, len+1); 12916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 13016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return newStr; 13116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 13216c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 13316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 13416c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 13516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * =========================================================================== 13616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * AssetManager 13716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * =========================================================================== 13816c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 13916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 14016c4d154dca43c662571129af31b27433b919a32Adam Lesinskiint32_t AssetManager::getGlobalCount() 14116c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 14216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return gCount; 14316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 14416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 14516c4d154dca43c662571129af31b27433b919a32Adam LesinskiAssetManager::AssetManager(CacheMode cacheMode) 14616c4d154dca43c662571129af31b27433b919a32Adam Lesinski : mLocale(NULL), mVendor(NULL), 14716c4d154dca43c662571129af31b27433b919a32Adam Lesinski mResources(NULL), mConfig(new ResTable_config), 14816c4d154dca43c662571129af31b27433b919a32Adam Lesinski mCacheMode(cacheMode), mCacheValid(false) 14916c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 15016c4d154dca43c662571129af31b27433b919a32Adam Lesinski int count = android_atomic_inc(&gCount)+1; 15116c4d154dca43c662571129af31b27433b919a32Adam Lesinski //ALOGI("Creating AssetManager %p #%d\n", this, count); 15216c4d154dca43c662571129af31b27433b919a32Adam Lesinski memset(mConfig, 0, sizeof(ResTable_config)); 15316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 15416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 15516c4d154dca43c662571129af31b27433b919a32Adam LesinskiAssetManager::~AssetManager(void) 15616c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 15716c4d154dca43c662571129af31b27433b919a32Adam Lesinski int count = android_atomic_dec(&gCount); 15816c4d154dca43c662571129af31b27433b919a32Adam Lesinski //ALOGI("Destroying AssetManager in %p #%d\n", this, count); 15916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 16016c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete mConfig; 16116c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete mResources; 16216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 16316c4d154dca43c662571129af31b27433b919a32Adam Lesinski // don't have a String class yet, so make sure we clean up 16416c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete[] mLocale; 16516c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete[] mVendor; 16616c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 16716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 168a0c6260705c841f501282e0e337970ca9a00e064Narayan Kamathbool AssetManager::addAssetPath(const String8& path, int32_t* cookie) 16916c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 17016c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 17116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 17216c4d154dca43c662571129af31b27433b919a32Adam Lesinski asset_path ap; 17316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 17416c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 realPath(path); 17516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (kAppZipName) { 17616c4d154dca43c662571129af31b27433b919a32Adam Lesinski realPath.appendPath(kAppZipName); 17716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 17816c4d154dca43c662571129af31b27433b919a32Adam Lesinski ap.type = ::getFileType(realPath.string()); 17916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ap.type == kFileTypeRegular) { 18016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ap.path = realPath; 18116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 18216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ap.path = path; 18316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ap.type = ::getFileType(path.string()); 18416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ap.type != kFileTypeDirectory && ap.type != kFileTypeRegular) { 18516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("Asset path %s is neither a directory nor file (type=%d).", 18616c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.string(), (int)ap.type); 18716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 18816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 18916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 19016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 19116c4d154dca43c662571129af31b27433b919a32Adam Lesinski // Skip if we have it already. 19216c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (size_t i=0; i<mAssetPaths.size(); i++) { 19316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mAssetPaths[i].path == ap.path) { 19416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (cookie) { 195a0c6260705c841f501282e0e337970ca9a00e064Narayan Kamath *cookie = static_cast<int32_t>(i+1); 19616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 19716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return true; 19816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 19916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 20016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 20116c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("In %p Asset %s path: %s", this, 20216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string()); 20316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 20416c4d154dca43c662571129af31b27433b919a32Adam Lesinski mAssetPaths.add(ap); 20516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 20616c4d154dca43c662571129af31b27433b919a32Adam Lesinski // new paths are always added at the end 20716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (cookie) { 208a0c6260705c841f501282e0e337970ca9a00e064Narayan Kamath *cookie = static_cast<int32_t>(mAssetPaths.size()); 20916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 21016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 21116c4d154dca43c662571129af31b27433b919a32Adam Lesinski // add overlay packages for /system/framework; apps are handled by the 21216c4d154dca43c662571129af31b27433b919a32Adam Lesinski // (Java) package manager 21316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (strncmp(path.string(), "/system/framework/", 18) == 0) { 21416c4d154dca43c662571129af31b27433b919a32Adam Lesinski // When there is an environment variable for /vendor, this 21516c4d154dca43c662571129af31b27433b919a32Adam Lesinski // should be changed to something similar to how ANDROID_ROOT 21616c4d154dca43c662571129af31b27433b919a32Adam Lesinski // and ANDROID_DATA are used in this file. 21716c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 overlayPath("/vendor/overlay/framework/"); 21816c4d154dca43c662571129af31b27433b919a32Adam Lesinski overlayPath.append(path.getPathLeaf()); 21916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (TEMP_FAILURE_RETRY(access(overlayPath.string(), R_OK)) == 0) { 22016c4d154dca43c662571129af31b27433b919a32Adam Lesinski asset_path oap; 22116c4d154dca43c662571129af31b27433b919a32Adam Lesinski oap.path = overlayPath; 22216c4d154dca43c662571129af31b27433b919a32Adam Lesinski oap.type = ::getFileType(overlayPath.string()); 22316c4d154dca43c662571129af31b27433b919a32Adam Lesinski bool addOverlay = (oap.type == kFileTypeRegular); // only .apks supported as overlay 22416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (addOverlay) { 22516c4d154dca43c662571129af31b27433b919a32Adam Lesinski oap.idmap = idmapPathForPackagePath(overlayPath); 22616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 22716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (isIdmapStaleLocked(ap.path, oap.path, oap.idmap)) { 22816c4d154dca43c662571129af31b27433b919a32Adam Lesinski addOverlay = createIdmapFileLocked(ap.path, oap.path, oap.idmap); 22916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 23016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 23116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (addOverlay) { 23216c4d154dca43c662571129af31b27433b919a32Adam Lesinski mAssetPaths.add(oap); 23316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 23416c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to add overlay package %s\n", overlayPath.string()); 23516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 23616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 23716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 23816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 23916c4d154dca43c662571129af31b27433b919a32Adam Lesinski return true; 24016c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 24116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 24216c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool AssetManager::isIdmapStaleLocked(const String8& originalPath, const String8& overlayPath, 24316c4d154dca43c662571129af31b27433b919a32Adam Lesinski const String8& idmapPath) 24416c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 24516c4d154dca43c662571129af31b27433b919a32Adam Lesinski struct stat st; 24616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (TEMP_FAILURE_RETRY(stat(idmapPath.string(), &st)) == -1) { 24716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (errno == ENOENT) { 24816c4d154dca43c662571129af31b27433b919a32Adam Lesinski return true; // non-existing idmap is always stale 24916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 25016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to stat file %s: %s\n", idmapPath.string(), strerror(errno)); 25116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 25216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 25316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 25416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (st.st_size < ResTable::IDMAP_HEADER_SIZE_BYTES) { 25516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("file %s has unexpectedly small size=%zd\n", idmapPath.string(), (size_t)st.st_size); 25616c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 25716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 25816c4d154dca43c662571129af31b27433b919a32Adam Lesinski int fd = TEMP_FAILURE_RETRY(::open(idmapPath.string(), O_RDONLY)); 25916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fd == -1) { 26016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to open file %s: %s\n", idmapPath.string(), strerror(errno)); 26116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 26216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 26316c4d154dca43c662571129af31b27433b919a32Adam Lesinski char buf[ResTable::IDMAP_HEADER_SIZE_BYTES]; 26416c4d154dca43c662571129af31b27433b919a32Adam Lesinski ssize_t bytesLeft = ResTable::IDMAP_HEADER_SIZE_BYTES; 26516c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (;;) { 26616c4d154dca43c662571129af31b27433b919a32Adam Lesinski ssize_t r = TEMP_FAILURE_RETRY(read(fd, buf + ResTable::IDMAP_HEADER_SIZE_BYTES - bytesLeft, 26716c4d154dca43c662571129af31b27433b919a32Adam Lesinski bytesLeft)); 26816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (r < 0) { 26916c4d154dca43c662571129af31b27433b919a32Adam Lesinski TEMP_FAILURE_RETRY(close(fd)); 27016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 27116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 27216c4d154dca43c662571129af31b27433b919a32Adam Lesinski bytesLeft -= r; 27316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (bytesLeft == 0) { 27416c4d154dca43c662571129af31b27433b919a32Adam Lesinski break; 27516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 27616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 27716c4d154dca43c662571129af31b27433b919a32Adam Lesinski TEMP_FAILURE_RETRY(close(fd)); 27816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 27916c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t cachedOriginalCrc, cachedOverlayCrc; 28016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!ResTable::getIdmapInfo(buf, ResTable::IDMAP_HEADER_SIZE_BYTES, 28116c4d154dca43c662571129af31b27433b919a32Adam Lesinski &cachedOriginalCrc, &cachedOverlayCrc)) { 28216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 28316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 28416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 28516c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t actualOriginalCrc, actualOverlayCrc; 28616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &actualOriginalCrc)) { 28716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 28816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 28916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!getZipEntryCrcLocked(overlayPath, "resources.arsc", &actualOverlayCrc)) { 29016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 29116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 29216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return cachedOriginalCrc != actualOriginalCrc || cachedOverlayCrc != actualOverlayCrc; 29316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 29416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 29516c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool AssetManager::getZipEntryCrcLocked(const String8& zipPath, const char* entryFilename, 29616c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t* pCrc) 29716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 29816c4d154dca43c662571129af31b27433b919a32Adam Lesinski asset_path ap; 29916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ap.path = zipPath; 30016c4d154dca43c662571129af31b27433b919a32Adam Lesinski const ZipFileRO* zip = getZipFileLocked(ap); 30116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (zip == NULL) { 30216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 30316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 30416c4d154dca43c662571129af31b27433b919a32Adam Lesinski const ZipEntryRO entry = zip->findEntryByName(entryFilename); 30516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (entry == NULL) { 30616c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 30716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 308560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath 309560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath const bool gotInfo = zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, (long*)pCrc); 310560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath zip->releaseEntry(entry); 311560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath 312560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath return gotInfo; 31316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 31416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 31516c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool AssetManager::createIdmapFileLocked(const String8& originalPath, const String8& overlayPath, 31616c4d154dca43c662571129af31b27433b919a32Adam Lesinski const String8& idmapPath) 31716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 31816c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGD("%s: originalPath=%s overlayPath=%s idmapPath=%s\n", 31916c4d154dca43c662571129af31b27433b919a32Adam Lesinski __FUNCTION__, originalPath.string(), overlayPath.string(), idmapPath.string()); 32016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ResTable tables[2]; 32116c4d154dca43c662571129af31b27433b919a32Adam Lesinski const String8* paths[2] = { &originalPath, &overlayPath }; 32216c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t originalCrc, overlayCrc; 32316c4d154dca43c662571129af31b27433b919a32Adam Lesinski bool retval = false; 32416c4d154dca43c662571129af31b27433b919a32Adam Lesinski ssize_t offset = 0; 32516c4d154dca43c662571129af31b27433b919a32Adam Lesinski int fd = 0; 32616c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t* data = NULL; 32716c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t size; 32816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 32916c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (int i = 0; i < 2; ++i) { 33016c4d154dca43c662571129af31b27433b919a32Adam Lesinski asset_path ap; 33116c4d154dca43c662571129af31b27433b919a32Adam Lesinski ap.type = kFileTypeRegular; 33216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ap.path = *paths[i]; 33316c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* ass = openNonAssetInPathLocked("resources.arsc", Asset::ACCESS_BUFFER, ap); 33416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ass == NULL) { 33516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to find resources.arsc in %s\n", ap.path.string()); 33616c4d154dca43c662571129af31b27433b919a32Adam Lesinski goto error; 33716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 33800b314436f4fdfada4bbf1e79ec12e9fa38aeaf1Narayan Kamath tables[i].add(ass, 1, false /* copyData */, NULL /* idMap */); 33916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 34016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 34116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &originalCrc)) { 34216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to retrieve crc for resources.arsc in %s\n", originalPath.string()); 34316c4d154dca43c662571129af31b27433b919a32Adam Lesinski goto error; 34416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 34516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!getZipEntryCrcLocked(overlayPath, "resources.arsc", &overlayCrc)) { 34616c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to retrieve crc for resources.arsc in %s\n", overlayPath.string()); 34716c4d154dca43c662571129af31b27433b919a32Adam Lesinski goto error; 34816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 34916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 35016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (tables[0].createIdmap(tables[1], originalCrc, overlayCrc, 35116c4d154dca43c662571129af31b27433b919a32Adam Lesinski (void**)&data, &size) != NO_ERROR) { 35216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to generate idmap data for file %s\n", idmapPath.string()); 35316c4d154dca43c662571129af31b27433b919a32Adam Lesinski goto error; 35416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 35516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 35616c4d154dca43c662571129af31b27433b919a32Adam Lesinski // This should be abstracted (eg replaced by a stand-alone 35716c4d154dca43c662571129af31b27433b919a32Adam Lesinski // application like dexopt, triggered by something equivalent to 35816c4d154dca43c662571129af31b27433b919a32Adam Lesinski // installd). 35916c4d154dca43c662571129af31b27433b919a32Adam Lesinski fd = TEMP_FAILURE_RETRY(::open(idmapPath.string(), O_WRONLY | O_CREAT | O_TRUNC, 0644)); 36016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fd == -1) { 36116c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to write idmap file %s (open: %s)\n", idmapPath.string(), strerror(errno)); 36216c4d154dca43c662571129af31b27433b919a32Adam Lesinski goto error_free; 36316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 36416c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (;;) { 36516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ssize_t written = TEMP_FAILURE_RETRY(write(fd, data + offset, size)); 36616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (written < 0) { 36716c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to write idmap file %s (write: %s)\n", idmapPath.string(), 36816c4d154dca43c662571129af31b27433b919a32Adam Lesinski strerror(errno)); 36916c4d154dca43c662571129af31b27433b919a32Adam Lesinski goto error_close; 37016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 37116c4d154dca43c662571129af31b27433b919a32Adam Lesinski size -= (size_t)written; 37216c4d154dca43c662571129af31b27433b919a32Adam Lesinski offset += written; 37316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (size == 0) { 37416c4d154dca43c662571129af31b27433b919a32Adam Lesinski break; 37516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 37616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 37716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 37816c4d154dca43c662571129af31b27433b919a32Adam Lesinski retval = true; 37916c4d154dca43c662571129af31b27433b919a32Adam Lesinskierror_close: 38016c4d154dca43c662571129af31b27433b919a32Adam Lesinski TEMP_FAILURE_RETRY(close(fd)); 38116c4d154dca43c662571129af31b27433b919a32Adam Lesinskierror_free: 38216c4d154dca43c662571129af31b27433b919a32Adam Lesinski free(data); 38316c4d154dca43c662571129af31b27433b919a32Adam Lesinskierror: 38416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return retval; 38516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 38616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 38716c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool AssetManager::addDefaultAssets() 38816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 38916c4d154dca43c662571129af31b27433b919a32Adam Lesinski const char* root = getenv("ANDROID_ROOT"); 39016c4d154dca43c662571129af31b27433b919a32Adam Lesinski LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set"); 39116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 39216c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 path(root); 39316c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath(kSystemAssets); 39416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 39516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return addAssetPath(path, NULL); 39616c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 39716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 398a0c6260705c841f501282e0e337970ca9a00e064Narayan Kamathint32_t AssetManager::nextAssetPath(const int32_t cookie) const 39916c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 40016c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 401a0c6260705c841f501282e0e337970ca9a00e064Narayan Kamath const size_t next = static_cast<size_t>(cookie) + 1; 402a0c6260705c841f501282e0e337970ca9a00e064Narayan Kamath return next > mAssetPaths.size() ? -1 : next; 40316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 40416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 405a0c6260705c841f501282e0e337970ca9a00e064Narayan KamathString8 AssetManager::getAssetPath(const int32_t cookie) const 40616c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 40716c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 408a0c6260705c841f501282e0e337970ca9a00e064Narayan Kamath const size_t which = static_cast<size_t>(cookie) - 1; 40916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (which < mAssetPaths.size()) { 41016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mAssetPaths[which].path; 41116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 41216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return String8(); 41316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 41416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 41516c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 41616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Set the current locale. Use NULL to indicate no locale. 41716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 41816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Close and reopen Zip archives as appropriate, and reset cached 41916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * information in the locale-specific sections of the tree. 42016c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 42116c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::setLocale(const char* locale) 42216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 42316c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 42416c4d154dca43c662571129af31b27433b919a32Adam Lesinski setLocaleLocked(locale); 42516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 42616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 42716c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::setLocaleLocked(const char* locale) 42816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 42916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mLocale != NULL) { 43016c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* previously set, purge cached data */ 43116c4d154dca43c662571129af31b27433b919a32Adam Lesinski purgeFileNameCacheLocked(); 43216c4d154dca43c662571129af31b27433b919a32Adam Lesinski //mZipSet.purgeLocale(); 43316c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete[] mLocale; 43416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 43516c4d154dca43c662571129af31b27433b919a32Adam Lesinski mLocale = strdupNew(locale); 43616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 43716c4d154dca43c662571129af31b27433b919a32Adam Lesinski updateResourceParamsLocked(); 43816c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 43916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 44016c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 44116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Set the current vendor. Use NULL to indicate no vendor. 44216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 44316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Close and reopen Zip archives as appropriate, and reset cached 44416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * information in the vendor-specific sections of the tree. 44516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 44616c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::setVendor(const char* vendor) 44716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 44816c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 44916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 45016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mVendor != NULL) { 45116c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* previously set, purge cached data */ 45216c4d154dca43c662571129af31b27433b919a32Adam Lesinski purgeFileNameCacheLocked(); 45316c4d154dca43c662571129af31b27433b919a32Adam Lesinski //mZipSet.purgeVendor(); 45416c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete[] mVendor; 45516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 45616c4d154dca43c662571129af31b27433b919a32Adam Lesinski mVendor = strdupNew(vendor); 45716c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 45816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 45916c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::setConfiguration(const ResTable_config& config, const char* locale) 46016c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 46116c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 46216c4d154dca43c662571129af31b27433b919a32Adam Lesinski *mConfig = config; 46316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (locale) { 46416c4d154dca43c662571129af31b27433b919a32Adam Lesinski setLocaleLocked(locale); 46516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else if (config.language[0] != 0) { 46691447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath char spec[RESTABLE_MAX_LOCALE_LEN]; 46791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath config.getBcp47Locale(spec); 46816c4d154dca43c662571129af31b27433b919a32Adam Lesinski setLocaleLocked(spec); 46916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 47016c4d154dca43c662571129af31b27433b919a32Adam Lesinski updateResourceParamsLocked(); 47116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 47216c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 47316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 47416c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::getConfiguration(ResTable_config* outConfig) const 47516c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 47616c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 47716c4d154dca43c662571129af31b27433b919a32Adam Lesinski *outConfig = *mConfig; 47816c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 47916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 48016c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 48116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Open an asset. 48216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 48316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * The data could be; 48416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * - In a file on disk (assetBase + fileName). 48516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * - In a compressed file on disk (assetBase + fileName.gz). 48616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * - In a Zip archive, uncompressed or compressed. 48716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 48816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * It can be in a number of different directories and Zip archives. 48916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * The search order is: 49016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * - [appname] 49116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * - locale + vendor 49216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * - "default" + vendor 49316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * - locale + "default" 49416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * - "default + "default" 49516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * - "common" 49616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * - (same as above) 49716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 49816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * To find a particular file, we have to try up to eight paths with 49916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * all three forms of data. 50016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 50116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * We should probably reject requests for "illegal" filenames, e.g. those 50216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * with illegal characters or "../" backward relative paths. 50316c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 50416c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::open(const char* fileName, AccessMode mode) 50516c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 50616c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 50716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 50816c4d154dca43c662571129af31b27433b919a32Adam Lesinski LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager"); 50916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 51016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 51116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCacheMode != CACHE_OFF && !mCacheValid) 51216c4d154dca43c662571129af31b27433b919a32Adam Lesinski loadFileNameCacheLocked(); 51316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 51416c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 assetName(kAssetsRoot); 51516c4d154dca43c662571129af31b27433b919a32Adam Lesinski assetName.appendPath(fileName); 51616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 51716c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 51816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * For each top-level asset path, search for the asset. 51916c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 52016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 52116c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t i = mAssetPaths.size(); 52216c4d154dca43c662571129af31b27433b919a32Adam Lesinski while (i > 0) { 52316c4d154dca43c662571129af31b27433b919a32Adam Lesinski i--; 52416c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Looking for asset '%s' in '%s'\n", 52516c4d154dca43c662571129af31b27433b919a32Adam Lesinski assetName.string(), mAssetPaths.itemAt(i).path.string()); 52616c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i)); 52716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset != NULL) { 52816c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pAsset != kExcludedAsset ? pAsset : NULL; 52916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 53016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 53116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 53216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return NULL; 53316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 53416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 53516c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 53616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Open a non-asset file as if it were an asset. 53716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 53816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * The "fileName" is the partial path starting from the application 53916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * name. 54016c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 54116c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::openNonAsset(const char* fileName, AccessMode mode) 54216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 54316c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 54416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 54516c4d154dca43c662571129af31b27433b919a32Adam Lesinski LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager"); 54616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 54716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 54816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCacheMode != CACHE_OFF && !mCacheValid) 54916c4d154dca43c662571129af31b27433b919a32Adam Lesinski loadFileNameCacheLocked(); 55016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 55116c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 55216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * For each top-level asset path, search for the asset. 55316c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 55416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 55516c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t i = mAssetPaths.size(); 55616c4d154dca43c662571129af31b27433b919a32Adam Lesinski while (i > 0) { 55716c4d154dca43c662571129af31b27433b919a32Adam Lesinski i--; 55816c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string()); 55916c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* pAsset = openNonAssetInPathLocked( 56016c4d154dca43c662571129af31b27433b919a32Adam Lesinski fileName, mode, mAssetPaths.itemAt(i)); 56116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset != NULL) { 56216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pAsset != kExcludedAsset ? pAsset : NULL; 56316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 56416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 56516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 56616c4d154dca43c662571129af31b27433b919a32Adam Lesinski return NULL; 56716c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 56816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 569a0c6260705c841f501282e0e337970ca9a00e064Narayan KamathAsset* AssetManager::openNonAsset(const int32_t cookie, const char* fileName, AccessMode mode) 57016c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 571a0c6260705c841f501282e0e337970ca9a00e064Narayan Kamath const size_t which = static_cast<size_t>(cookie) - 1; 57216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 57316c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 57416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 57516c4d154dca43c662571129af31b27433b919a32Adam Lesinski LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager"); 57616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 57716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCacheMode != CACHE_OFF && !mCacheValid) 57816c4d154dca43c662571129af31b27433b919a32Adam Lesinski loadFileNameCacheLocked(); 57916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 58016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (which < mAssetPaths.size()) { 58116c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Looking for non-asset '%s' in '%s'\n", fileName, 58216c4d154dca43c662571129af31b27433b919a32Adam Lesinski mAssetPaths.itemAt(which).path.string()); 58316c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* pAsset = openNonAssetInPathLocked( 58416c4d154dca43c662571129af31b27433b919a32Adam Lesinski fileName, mode, mAssetPaths.itemAt(which)); 58516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset != NULL) { 58616c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pAsset != kExcludedAsset ? pAsset : NULL; 58716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 58816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 58916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 59016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return NULL; 59116c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 59216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 59316c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 59416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Get the type of a file in the asset namespace. 59516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 59616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * This currently only works for regular files. All others (including 59716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * directories) will return kFileTypeNonexistent. 59816c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 59916c4d154dca43c662571129af31b27433b919a32Adam LesinskiFileType AssetManager::getFileType(const char* fileName) 60016c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 60116c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* pAsset = NULL; 60216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 60316c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 60416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Open the asset. This is less efficient than simply finding the 60516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * file, but it's not too bad (we don't uncompress or mmap data until 60616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * the first read() call). 60716c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 60816c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = open(fileName, Asset::ACCESS_STREAMING); 60916c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete pAsset; 61016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 61116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset == NULL) 61216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return kFileTypeNonexistent; 61316c4d154dca43c662571129af31b27433b919a32Adam Lesinski else 61416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return kFileTypeRegular; 61516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 61616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 61716c4d154dca43c662571129af31b27433b919a32Adam Lesinskiconst ResTable* AssetManager::getResTable(bool required) const 61816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 61916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ResTable* rt = mResources; 62016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (rt) { 62116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return rt; 62216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 62316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 62416c4d154dca43c662571129af31b27433b919a32Adam Lesinski // Iterate through all asset packages, collecting resources from each. 62516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 62616c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 62716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 62816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mResources != NULL) { 62916c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mResources; 63016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 63116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 63216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (required) { 63316c4d154dca43c662571129af31b27433b919a32Adam Lesinski LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager"); 63416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 63516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 63616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCacheMode != CACHE_OFF && !mCacheValid) 63716c4d154dca43c662571129af31b27433b919a32Adam Lesinski const_cast<AssetManager*>(this)->loadFileNameCacheLocked(); 63816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 63916c4d154dca43c662571129af31b27433b919a32Adam Lesinski const size_t N = mAssetPaths.size(); 64016c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (size_t i=0; i<N; i++) { 64116c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* ass = NULL; 64216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ResTable* sharedRes = NULL; 64316c4d154dca43c662571129af31b27433b919a32Adam Lesinski bool shared = true; 64416c4d154dca43c662571129af31b27433b919a32Adam Lesinski const asset_path& ap = mAssetPaths.itemAt(i); 64516c4d154dca43c662571129af31b27433b919a32Adam Lesinski MY_TRACE_BEGIN(ap.path.string()); 64616c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* idmap = openIdmapLocked(ap); 64716c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Looking for resource asset in '%s'\n", ap.path.string()); 64816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ap.type != kFileTypeDirectory) { 64916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (i == 0) { 65016c4d154dca43c662571129af31b27433b919a32Adam Lesinski // The first item is typically the framework resources, 65116c4d154dca43c662571129af31b27433b919a32Adam Lesinski // which we want to avoid parsing every time. 65216c4d154dca43c662571129af31b27433b919a32Adam Lesinski sharedRes = const_cast<AssetManager*>(this)-> 65316c4d154dca43c662571129af31b27433b919a32Adam Lesinski mZipSet.getZipResourceTable(ap.path); 65416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 65516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (sharedRes == NULL) { 65616c4d154dca43c662571129af31b27433b919a32Adam Lesinski ass = const_cast<AssetManager*>(this)-> 65716c4d154dca43c662571129af31b27433b919a32Adam Lesinski mZipSet.getZipResourceTableAsset(ap.path); 65816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ass == NULL) { 65916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("loading resource table %s\n", ap.path.string()); 66016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ass = const_cast<AssetManager*>(this)-> 66116c4d154dca43c662571129af31b27433b919a32Adam Lesinski openNonAssetInPathLocked("resources.arsc", 66216c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset::ACCESS_BUFFER, 66316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ap); 66416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ass != NULL && ass != kExcludedAsset) { 66516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ass = const_cast<AssetManager*>(this)-> 66616c4d154dca43c662571129af31b27433b919a32Adam Lesinski mZipSet.setZipResourceTableAsset(ap.path, ass); 66716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 66816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 66916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 67016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (i == 0 && ass != NULL) { 67116c4d154dca43c662571129af31b27433b919a32Adam Lesinski // If this is the first resource table in the asset 67216c4d154dca43c662571129af31b27433b919a32Adam Lesinski // manager, then we are going to cache it so that we 67316c4d154dca43c662571129af31b27433b919a32Adam Lesinski // can quickly copy it out for others. 67416c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Creating shared resources for %s", ap.path.string()); 67516c4d154dca43c662571129af31b27433b919a32Adam Lesinski sharedRes = new ResTable(); 67600b314436f4fdfada4bbf1e79ec12e9fa38aeaf1Narayan Kamath sharedRes->add(ass, i + 1, false, idmap); 67716c4d154dca43c662571129af31b27433b919a32Adam Lesinski sharedRes = const_cast<AssetManager*>(this)-> 67816c4d154dca43c662571129af31b27433b919a32Adam Lesinski mZipSet.setZipResourceTable(ap.path, sharedRes); 67916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 68016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 68116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 68216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("loading resource table %s\n", ap.path.string()); 683e1aa223657dd1def8609b377afa86a024bfd4e14Elliott Hughes ass = const_cast<AssetManager*>(this)-> 68416c4d154dca43c662571129af31b27433b919a32Adam Lesinski openNonAssetInPathLocked("resources.arsc", 68516c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset::ACCESS_BUFFER, 68616c4d154dca43c662571129af31b27433b919a32Adam Lesinski ap); 68716c4d154dca43c662571129af31b27433b919a32Adam Lesinski shared = false; 68816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 68916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) { 69016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (rt == NULL) { 69116c4d154dca43c662571129af31b27433b919a32Adam Lesinski mResources = rt = new ResTable(); 69216c4d154dca43c662571129af31b27433b919a32Adam Lesinski updateResourceParamsLocked(); 69316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 69416c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Installing resource asset %p in to table %p\n", ass, mResources); 69516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (sharedRes != NULL) { 69616c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Copying existing resources for %s", ap.path.string()); 69716c4d154dca43c662571129af31b27433b919a32Adam Lesinski rt->add(sharedRes); 69816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 69916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Parsing resources for %s", ap.path.string()); 70000b314436f4fdfada4bbf1e79ec12e9fa38aeaf1Narayan Kamath rt->add(ass, i + 1, !shared, idmap); 70116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 70216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 70316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!shared) { 70416c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete ass; 70516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 70616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 70716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (idmap != NULL) { 70816c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete idmap; 70916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 71016c4d154dca43c662571129af31b27433b919a32Adam Lesinski MY_TRACE_END(); 71116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 71216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 71316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (required && !rt) ALOGW("Unable to find resources file resources.arsc"); 71416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!rt) { 71516c4d154dca43c662571129af31b27433b919a32Adam Lesinski mResources = rt = new ResTable(); 71616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 71716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return rt; 71816c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 71916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 72016c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::updateResourceParamsLocked() const 72116c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 72216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ResTable* res = mResources; 72316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!res) { 72416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return; 72516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 72616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 72791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath if (mLocale) { 72891447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath mConfig->setBcp47Locale(mLocale); 72991447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath } else { 73091447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath mConfig->clearLocale(); 73116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 73216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 73316c4d154dca43c662571129af31b27433b919a32Adam Lesinski res->setParameters(mConfig); 73416c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 73516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 73616c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::openIdmapLocked(const struct asset_path& ap) const 73716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 73816c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* ass = NULL; 73916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ap.idmap.size() != 0) { 74016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ass = const_cast<AssetManager*>(this)-> 74116c4d154dca43c662571129af31b27433b919a32Adam Lesinski openAssetFromFileLocked(ap.idmap, Asset::ACCESS_BUFFER); 74216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ass) { 74316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("loading idmap %s\n", ap.idmap.string()); 74416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 74516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to load idmap %s\n", ap.idmap.string()); 74616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 74716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 74816c4d154dca43c662571129af31b27433b919a32Adam Lesinski return ass; 74916c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 75016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 75116c4d154dca43c662571129af31b27433b919a32Adam Lesinskiconst ResTable& AssetManager::getResources(bool required) const 75216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 75316c4d154dca43c662571129af31b27433b919a32Adam Lesinski const ResTable* rt = getResTable(required); 75416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return *rt; 75516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 75616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 75716c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool AssetManager::isUpToDate() 75816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 75916c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 76016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mZipSet.isUpToDate(); 76116c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 76216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 76316c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::getLocales(Vector<String8>* locales) const 76416c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 76516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ResTable* res = mResources; 76616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (res != NULL) { 76716c4d154dca43c662571129af31b27433b919a32Adam Lesinski res->getLocales(locales); 76816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 76916c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 77016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 77116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 77216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Open a non-asset file as if it were an asset, searching for it in the 77316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * specified app. 77416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 77516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Pass in a NULL values for "appName" if the common app directory should 77616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * be used. 77716c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 77816c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode mode, 77916c4d154dca43c662571129af31b27433b919a32Adam Lesinski const asset_path& ap) 78016c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 78116c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* pAsset = NULL; 78216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 78316c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* look at the filesystem on disk */ 78416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ap.type == kFileTypeDirectory) { 78516c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 path(ap.path); 78616c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath(fileName); 78716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 78816c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openAssetFromFileLocked(path, mode); 78916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 79016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset == NULL) { 79116c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* try again, this time with ".gz" */ 79216c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.append(".gz"); 79316c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openAssetFromFileLocked(path, mode); 79416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 79516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 79616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset != NULL) { 79716c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("FOUND NA '%s' on disk\n", fileName); 79816c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset->setAssetSource(path); 79916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 80016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 80116c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* look inside the zip file */ 80216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 80316c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 path(fileName); 80416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 80516c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* check the appropriate Zip file */ 806560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath ZipFileRO* pZip = getZipFileLocked(ap); 80716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pZip != NULL) { 80816c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("GOT zip, checking NA '%s'\n", (const char*) path); 809560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath ZipEntryRO entry = pZip->findEntryByName(path.string()); 81016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (entry != NULL) { 81116c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("FOUND NA in Zip file for %s\n", appName ? appName : kAppCommon); 81216c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openAssetFromZipLocked(pZip, entry, mode, path); 813560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath pZip->releaseEntry(entry); 81416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 81516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 81616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 81716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset != NULL) { 81816c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* create a "source" name, for debug/display */ 81916c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset->setAssetSource( 82016c4d154dca43c662571129af31b27433b919a32Adam Lesinski createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), String8(""), 82116c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8(fileName))); 82216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 82316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 82416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 82516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pAsset; 82616c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 82716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 82816c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 82916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Open an asset, searching for it in the directory hierarchy for the 83016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * specified app. 83116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 83216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Pass in a NULL values for "appName" if the common app directory should 83316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * be used. 83416c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 83516c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::openInPathLocked(const char* fileName, AccessMode mode, 83616c4d154dca43c662571129af31b27433b919a32Adam Lesinski const asset_path& ap) 83716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 83816c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* pAsset = NULL; 83916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 84016c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 84116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Try various combinations of locale and vendor. 84216c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 84316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mLocale != NULL && mVendor != NULL) 84416c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, mVendor); 84516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset == NULL && mVendor != NULL) 84616c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, mVendor); 84716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset == NULL && mLocale != NULL) 84816c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, NULL); 84916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset == NULL) 85016c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, NULL); 85116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 85216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pAsset; 85316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 85416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 85516c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 85616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Open an asset, searching for it in the directory hierarchy for the 85716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * specified locale and vendor. 85816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 85916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * We also search in "app.jar". 86016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 86116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Pass in NULL values for "appName", "locale", and "vendor" if the 86216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * defaults should be used. 86316c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 86416c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode mode, 86516c4d154dca43c662571129af31b27433b919a32Adam Lesinski const asset_path& ap, const char* locale, const char* vendor) 86616c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 86716c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* pAsset = NULL; 86816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 86916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ap.type == kFileTypeDirectory) { 87016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCacheMode == CACHE_OFF) { 87116c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* look at the filesystem on disk */ 87216c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 path(createPathNameLocked(ap, locale, vendor)); 87316c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath(fileName); 87416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 87516c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 excludeName(path); 87616c4d154dca43c662571129af31b27433b919a32Adam Lesinski excludeName.append(kExcludeExtension); 87716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (::getFileType(excludeName.string()) != kFileTypeNonexistent) { 87816c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* say no more */ 87916c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("+++ excluding '%s'\n", (const char*) excludeName); 88016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return kExcludedAsset; 88116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 88216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 88316c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openAssetFromFileLocked(path, mode); 88416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 88516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset == NULL) { 88616c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* try again, this time with ".gz" */ 88716c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.append(".gz"); 88816c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openAssetFromFileLocked(path, mode); 88916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 89016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 89116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset != NULL) 89216c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset->setAssetSource(path); 89316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 89416c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* find in cache */ 89516c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 path(createPathNameLocked(ap, locale, vendor)); 89616c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath(fileName); 89716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 89816c4d154dca43c662571129af31b27433b919a32Adam Lesinski AssetDir::FileInfo tmpInfo; 89916c4d154dca43c662571129af31b27433b919a32Adam Lesinski bool found = false; 90016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 90116c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 excludeName(path); 90216c4d154dca43c662571129af31b27433b919a32Adam Lesinski excludeName.append(kExcludeExtension); 90316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 90416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) { 90516c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* go no farther */ 90616c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("+++ Excluding '%s'\n", (const char*) excludeName); 90716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return kExcludedAsset; 90816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 90916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 91016c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 91116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * File compression extensions (".gz") don't get stored in the 91216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * name cache, so we have to try both here. 91316c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 91416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCache.indexOf(path) != NAME_NOT_FOUND) { 91516c4d154dca43c662571129af31b27433b919a32Adam Lesinski found = true; 91616c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openAssetFromFileLocked(path, mode); 91716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset == NULL) { 91816c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* try again, this time with ".gz" */ 91916c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.append(".gz"); 92016c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openAssetFromFileLocked(path, mode); 92116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 92216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 92316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 92416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset != NULL) 92516c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset->setAssetSource(path); 92616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 92716c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 92816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Don't continue the search into the Zip files. Our cached info 92916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * said it was a file on disk; to be consistent with openDir() 93016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * we want to return the loose asset. If the cached file gets 93116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * removed, we fail. 93216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 93316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * The alternative is to update our cache when files get deleted, 93416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * or make some sort of "best effort" promise, but for now I'm 93516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * taking the hard line. 93616c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 93716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (found) { 93816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset == NULL) 93916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGD("Expected file not found: '%s'\n", path.string()); 94016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pAsset; 94116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 94216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 94316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 94416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 94516c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 94616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Either it wasn't found on disk or on the cached view of the disk. 94716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Dig through the currently-opened set of Zip files. If caching 94816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * is disabled, the Zip file may get reopened. 94916c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 95016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset == NULL && ap.type == kFileTypeRegular) { 95116c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 path; 95216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 95316c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath((locale != NULL) ? locale : kDefaultLocale); 95416c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath((vendor != NULL) ? vendor : kDefaultVendor); 95516c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath(fileName); 95616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 95716c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* check the appropriate Zip file */ 958560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath ZipFileRO* pZip = getZipFileLocked(ap); 95916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pZip != NULL) { 96016c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("GOT zip, checking '%s'\n", (const char*) path); 961560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath ZipEntryRO entry = pZip->findEntryByName(path.string()); 96216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (entry != NULL) { 96316c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("FOUND in Zip file for %s/%s-%s\n", 96416c4d154dca43c662571129af31b27433b919a32Adam Lesinski // appName, locale, vendor); 96516c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = openAssetFromZipLocked(pZip, entry, mode, path); 966560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath pZip->releaseEntry(entry); 96716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 96816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 96916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 97016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset != NULL) { 97116c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* create a "source" name, for debug/display */ 97216c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset->setAssetSource(createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), 97316c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8(""), String8(fileName))); 97416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 97516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 97616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 97716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pAsset; 97816c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 97916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 98016c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 98116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Create a "source name" for a file from a Zip archive. 98216c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 98316c4d154dca43c662571129af31b27433b919a32Adam LesinskiString8 AssetManager::createZipSourceNameLocked(const String8& zipFileName, 98416c4d154dca43c662571129af31b27433b919a32Adam Lesinski const String8& dirName, const String8& fileName) 98516c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 98616c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 sourceName("zip:"); 98716c4d154dca43c662571129af31b27433b919a32Adam Lesinski sourceName.append(zipFileName); 98816c4d154dca43c662571129af31b27433b919a32Adam Lesinski sourceName.append(":"); 98916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (dirName.length() > 0) { 99016c4d154dca43c662571129af31b27433b919a32Adam Lesinski sourceName.appendPath(dirName); 99116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 99216c4d154dca43c662571129af31b27433b919a32Adam Lesinski sourceName.appendPath(fileName); 99316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return sourceName; 99416c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 99516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 99616c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 99716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Create a path to a loose asset (asset-base/app/locale/vendor). 99816c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 99916c4d154dca43c662571129af31b27433b919a32Adam LesinskiString8 AssetManager::createPathNameLocked(const asset_path& ap, const char* locale, 100016c4d154dca43c662571129af31b27433b919a32Adam Lesinski const char* vendor) 100116c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 100216c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 path(ap.path); 100316c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath((locale != NULL) ? locale : kDefaultLocale); 100416c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath((vendor != NULL) ? vendor : kDefaultVendor); 100516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return path; 100616c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 100716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 100816c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 100916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Create a path to a loose asset (asset-base/app/rootDir). 101016c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 101116c4d154dca43c662571129af31b27433b919a32Adam LesinskiString8 AssetManager::createPathNameLocked(const asset_path& ap, const char* rootDir) 101216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 101316c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 path(ap.path); 101416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (rootDir != NULL) path.appendPath(rootDir); 101516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return path; 101616c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 101716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 101816c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 101916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Return a pointer to one of our open Zip archives. Returns NULL if no 102016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * matching Zip file exists. 102116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 102216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Right now we have 2 possible Zip files (1 each in app/"common"). 102316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 102416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * If caching is set to CACHE_OFF, to get the expected behavior we 102516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * need to reopen the Zip file on every request. That would be silly 102616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * and expensive, so instead we just check the file modification date. 102716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 102816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Pass in NULL values for "appName", "locale", and "vendor" if the 102916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * generics should be used. 103016c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 103116c4d154dca43c662571129af31b27433b919a32Adam LesinskiZipFileRO* AssetManager::getZipFileLocked(const asset_path& ap) 103216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 103316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("getZipFileLocked() in %p\n", this); 103416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 103516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mZipSet.getZip(ap.path); 103616c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 103716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 103816c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 103916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Try to open an asset from a file on disk. 104016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 104116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * If the file is compressed with gzip, we seek to the start of the 104216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * deflated data and pass that in (just like we would for a Zip archive). 104316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 104416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * For uncompressed data, we may already have an mmap()ed version sitting 104516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * around. If so, we want to hand that to the Asset instead. 104616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 104716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * This returns NULL if the file doesn't exist, couldn't be opened, or 104816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * claims to be a ".gz" but isn't. 104916c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 105016c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::openAssetFromFileLocked(const String8& pathName, 105116c4d154dca43c662571129af31b27433b919a32Adam Lesinski AccessMode mode) 105216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 105316c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* pAsset = NULL; 105416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 105516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (strcasecmp(pathName.getPathExtension().string(), ".gz") == 0) { 105616c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("TRYING '%s'\n", (const char*) pathName); 105716c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = Asset::createFromCompressedFile(pathName.string(), mode); 105816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 105916c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("TRYING '%s'\n", (const char*) pathName); 106016c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = Asset::createFromFile(pathName.string(), mode); 106116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 106216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 106316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pAsset; 106416c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 106516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 106616c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 106716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Given an entry in a Zip archive, create a new Asset object. 106816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 106916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * If the entry is uncompressed, we may want to create or share a 107016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * slice of shared memory. 107116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 107216c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile, 107316c4d154dca43c662571129af31b27433b919a32Adam Lesinski const ZipEntryRO entry, AccessMode mode, const String8& entryName) 107416c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 107516c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* pAsset = NULL; 107616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 107716c4d154dca43c662571129af31b27433b919a32Adam Lesinski // TODO: look for previously-created shared memory slice? 107816c4d154dca43c662571129af31b27433b919a32Adam Lesinski int method; 107916c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t uncompressedLen; 108016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 108116c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("USING Zip '%s'\n", pEntry->getFileName()); 108216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 108316c4d154dca43c662571129af31b27433b919a32Adam Lesinski //pZipFile->getEntryInfo(entry, &method, &uncompressedLen, &compressedLen, 108416c4d154dca43c662571129af31b27433b919a32Adam Lesinski // &offset); 108516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL, 108616c4d154dca43c662571129af31b27433b919a32Adam Lesinski NULL, NULL)) 108716c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 108816c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("getEntryInfo failed\n"); 108916c4d154dca43c662571129af31b27433b919a32Adam Lesinski return NULL; 109016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 109116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 109216c4d154dca43c662571129af31b27433b919a32Adam Lesinski FileMap* dataMap = pZipFile->createEntryFileMap(entry); 109316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (dataMap == NULL) { 109416c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("create map from entry failed\n"); 109516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return NULL; 109616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 109716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 109816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (method == ZipFileRO::kCompressStored) { 109916c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = Asset::createFromUncompressedMap(dataMap, mode); 110016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(), 110116c4d154dca43c662571129af31b27433b919a32Adam Lesinski dataMap->getFileName(), mode, pAsset); 110216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 110316c4d154dca43c662571129af31b27433b919a32Adam Lesinski pAsset = Asset::createFromCompressedMap(dataMap, method, 110416c4d154dca43c662571129af31b27433b919a32Adam Lesinski uncompressedLen, mode); 110516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(), 110616c4d154dca43c662571129af31b27433b919a32Adam Lesinski dataMap->getFileName(), mode, pAsset); 110716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 110816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pAsset == NULL) { 110916c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* unexpected */ 111016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("create from segment failed\n"); 111116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 111216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 111316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pAsset; 111416c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 111516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 111616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 111716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 111816c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 111916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Open a directory in the asset namespace. 112016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 112116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * An "asset directory" is simply the combination of all files in all 112216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * locations, with ".gz" stripped for loose files. With app, locale, and 112316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * vendor defined, we have 8 directories and 2 Zip archives to scan. 112416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 112516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Pass in "" for the root dir. 112616c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 112716c4d154dca43c662571129af31b27433b919a32Adam LesinskiAssetDir* AssetManager::openDir(const char* dirName) 112816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 112916c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 113016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 113116c4d154dca43c662571129af31b27433b919a32Adam Lesinski AssetDir* pDir = NULL; 113216c4d154dca43c662571129af31b27433b919a32Adam Lesinski SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL; 113316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 113416c4d154dca43c662571129af31b27433b919a32Adam Lesinski LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager"); 113516c4d154dca43c662571129af31b27433b919a32Adam Lesinski assert(dirName != NULL); 113616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 113716c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase); 113816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 113916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCacheMode != CACHE_OFF && !mCacheValid) 114016c4d154dca43c662571129af31b27433b919a32Adam Lesinski loadFileNameCacheLocked(); 114116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 114216c4d154dca43c662571129af31b27433b919a32Adam Lesinski pDir = new AssetDir; 114316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 114416c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 114516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Scan the various directories, merging what we find into a single 114616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * vector. We want to scan them in reverse priority order so that 114716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * the ".EXCLUDE" processing works correctly. Also, if we decide we 114816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * want to remember where the file is coming from, we'll get the right 114916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * version. 115016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 115116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * We start with Zip archives, then do loose files. 115216c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 115316c4d154dca43c662571129af31b27433b919a32Adam Lesinski pMergedInfo = new SortedVector<AssetDir::FileInfo>; 115416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 115516c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t i = mAssetPaths.size(); 115616c4d154dca43c662571129af31b27433b919a32Adam Lesinski while (i > 0) { 115716c4d154dca43c662571129af31b27433b919a32Adam Lesinski i--; 115816c4d154dca43c662571129af31b27433b919a32Adam Lesinski const asset_path& ap = mAssetPaths.itemAt(i); 115916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ap.type == kFileTypeRegular) { 116016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Adding directory %s from zip %s", dirName, ap.path.string()); 116116c4d154dca43c662571129af31b27433b919a32Adam Lesinski scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName); 116216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 116316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Adding directory %s from dir %s", dirName, ap.path.string()); 116416c4d154dca43c662571129af31b27433b919a32Adam Lesinski scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName); 116516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 116616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 116716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 116816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#if 0 116916c4d154dca43c662571129af31b27433b919a32Adam Lesinski printf("FILE LIST:\n"); 117016c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (i = 0; i < (size_t) pMergedInfo->size(); i++) { 117116c4d154dca43c662571129af31b27433b919a32Adam Lesinski printf(" %d: (%d) '%s'\n", i, 117216c4d154dca43c662571129af31b27433b919a32Adam Lesinski pMergedInfo->itemAt(i).getFileType(), 117316c4d154dca43c662571129af31b27433b919a32Adam Lesinski (const char*) pMergedInfo->itemAt(i).getFileName()); 117416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 117516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 117616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 117716c4d154dca43c662571129af31b27433b919a32Adam Lesinski pDir->setFileList(pMergedInfo); 117816c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pDir; 117916c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 118016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 118116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 118216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Open a directory in the non-asset namespace. 118316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 118416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * An "asset directory" is simply the combination of all files in all 118516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * locations, with ".gz" stripped for loose files. With app, locale, and 118616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * vendor defined, we have 8 directories and 2 Zip archives to scan. 118716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 118816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Pass in "" for the root dir. 118916c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 1190a0c6260705c841f501282e0e337970ca9a00e064Narayan KamathAssetDir* AssetManager::openNonAssetDir(const int32_t cookie, const char* dirName) 119116c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 119216c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(mLock); 119316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 119416c4d154dca43c662571129af31b27433b919a32Adam Lesinski AssetDir* pDir = NULL; 119516c4d154dca43c662571129af31b27433b919a32Adam Lesinski SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL; 119616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 119716c4d154dca43c662571129af31b27433b919a32Adam Lesinski LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager"); 119816c4d154dca43c662571129af31b27433b919a32Adam Lesinski assert(dirName != NULL); 119916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 120016c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase); 120116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 120216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCacheMode != CACHE_OFF && !mCacheValid) 120316c4d154dca43c662571129af31b27433b919a32Adam Lesinski loadFileNameCacheLocked(); 120416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 120516c4d154dca43c662571129af31b27433b919a32Adam Lesinski pDir = new AssetDir; 120616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 120716c4d154dca43c662571129af31b27433b919a32Adam Lesinski pMergedInfo = new SortedVector<AssetDir::FileInfo>; 120816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 1209a0c6260705c841f501282e0e337970ca9a00e064Narayan Kamath const size_t which = static_cast<size_t>(cookie) - 1; 121016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 121116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (which < mAssetPaths.size()) { 121216c4d154dca43c662571129af31b27433b919a32Adam Lesinski const asset_path& ap = mAssetPaths.itemAt(which); 121316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (ap.type == kFileTypeRegular) { 121416c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Adding directory %s from zip %s", dirName, ap.path.string()); 121516c4d154dca43c662571129af31b27433b919a32Adam Lesinski scanAndMergeZipLocked(pMergedInfo, ap, NULL, dirName); 121616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 121716c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Adding directory %s from dir %s", dirName, ap.path.string()); 121816c4d154dca43c662571129af31b27433b919a32Adam Lesinski scanAndMergeDirLocked(pMergedInfo, ap, NULL, dirName); 121916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 122016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 122116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 122216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#if 0 122316c4d154dca43c662571129af31b27433b919a32Adam Lesinski printf("FILE LIST:\n"); 122416c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (i = 0; i < (size_t) pMergedInfo->size(); i++) { 122516c4d154dca43c662571129af31b27433b919a32Adam Lesinski printf(" %d: (%d) '%s'\n", i, 122616c4d154dca43c662571129af31b27433b919a32Adam Lesinski pMergedInfo->itemAt(i).getFileType(), 122716c4d154dca43c662571129af31b27433b919a32Adam Lesinski (const char*) pMergedInfo->itemAt(i).getFileName()); 122816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 122916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 123016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 123116c4d154dca43c662571129af31b27433b919a32Adam Lesinski pDir->setFileList(pMergedInfo); 123216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pDir; 123316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 123416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 123516c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 123616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Scan the contents of the specified directory and merge them into the 123716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * "pMergedInfo" vector, removing previous entries if we find "exclude" 123816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * directives. 123916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 124016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Returns "false" if we found nothing to contribute. 124116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 124216c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo, 124316c4d154dca43c662571129af31b27433b919a32Adam Lesinski const asset_path& ap, const char* rootDir, const char* dirName) 124416c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 124516c4d154dca43c662571129af31b27433b919a32Adam Lesinski SortedVector<AssetDir::FileInfo>* pContents; 124616c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 path; 124716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 124816c4d154dca43c662571129af31b27433b919a32Adam Lesinski assert(pMergedInfo != NULL); 124916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 125016c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("scanAndMergeDir: %s %s %s %s\n", appName, locale, vendor,dirName); 125116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 125216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCacheValid) { 125316c4d154dca43c662571129af31b27433b919a32Adam Lesinski int i, start, count; 125416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 125516c4d154dca43c662571129af31b27433b919a32Adam Lesinski pContents = new SortedVector<AssetDir::FileInfo>; 125616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 125716c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 125816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Get the basic partial path and find it in the cache. That's 125916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * the start point for the search. 126016c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 126116c4d154dca43c662571129af31b27433b919a32Adam Lesinski path = createPathNameLocked(ap, rootDir); 126216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (dirName[0] != '\0') 126316c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath(dirName); 126416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 126516c4d154dca43c662571129af31b27433b919a32Adam Lesinski start = mCache.indexOf(path); 126616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (start == NAME_NOT_FOUND) { 126716c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("+++ not found in cache: dir '%s'\n", (const char*) path); 126816c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete pContents; 126916c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 127016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 127116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 127216c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 127316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * The match string looks like "common/default/default/foo/bar/". 127416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * The '/' on the end ensures that we don't match on the directory 127516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * itself or on ".../foo/barfy/". 127616c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 127716c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.append("/"); 127816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 127916c4d154dca43c662571129af31b27433b919a32Adam Lesinski count = mCache.size(); 128016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 128116c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 128216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Pick out the stuff in the current dir by examining the pathname. 128316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * It needs to match the partial pathname prefix, and not have a '/' 128416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * (fssep) anywhere after the prefix. 128516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 128616c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (i = start+1; i < count; i++) { 128716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mCache[i].getFileName().length() > path.length() && 128816c4d154dca43c662571129af31b27433b919a32Adam Lesinski strncmp(mCache[i].getFileName().string(), path.string(), path.length()) == 0) 128916c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 129016c4d154dca43c662571129af31b27433b919a32Adam Lesinski const char* name = mCache[i].getFileName().string(); 129116c4d154dca43c662571129af31b27433b919a32Adam Lesinski // XXX THIS IS BROKEN! Looks like we need to store the full 129216c4d154dca43c662571129af31b27433b919a32Adam Lesinski // path prefix separately from the file path. 129316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (strchr(name + path.length(), '/') == NULL) { 129416c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* grab it, reducing path to just the filename component */ 129516c4d154dca43c662571129af31b27433b919a32Adam Lesinski AssetDir::FileInfo tmp = mCache[i]; 129616c4d154dca43c662571129af31b27433b919a32Adam Lesinski tmp.setFileName(tmp.getFileName().getPathLeaf()); 129716c4d154dca43c662571129af31b27433b919a32Adam Lesinski pContents->add(tmp); 129816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 129916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 130016c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* no longer in the dir or its subdirs */ 130116c4d154dca43c662571129af31b27433b919a32Adam Lesinski break; 130216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 130316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 130416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 130516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 130616c4d154dca43c662571129af31b27433b919a32Adam Lesinski path = createPathNameLocked(ap, rootDir); 130716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (dirName[0] != '\0') 130816c4d154dca43c662571129af31b27433b919a32Adam Lesinski path.appendPath(dirName); 130916c4d154dca43c662571129af31b27433b919a32Adam Lesinski pContents = scanDirLocked(path); 131016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pContents == NULL) 131116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 131216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 131316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 131416c4d154dca43c662571129af31b27433b919a32Adam Lesinski // if we wanted to do an incremental cache fill, we would do it here 131516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 131616c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 131716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Process "exclude" directives. If we find a filename that ends with 131816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * ".EXCLUDE", we look for a matching entry in the "merged" set, and 131916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * remove it if we find it. We also delete the "exclude" entry. 132016c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 132116c4d154dca43c662571129af31b27433b919a32Adam Lesinski int i, count, exclExtLen; 132216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 132316c4d154dca43c662571129af31b27433b919a32Adam Lesinski count = pContents->size(); 132416c4d154dca43c662571129af31b27433b919a32Adam Lesinski exclExtLen = strlen(kExcludeExtension); 132516c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (i = 0; i < count; i++) { 132616c4d154dca43c662571129af31b27433b919a32Adam Lesinski const char* name; 132716c4d154dca43c662571129af31b27433b919a32Adam Lesinski int nameLen; 132816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 132916c4d154dca43c662571129af31b27433b919a32Adam Lesinski name = pContents->itemAt(i).getFileName().string(); 133016c4d154dca43c662571129af31b27433b919a32Adam Lesinski nameLen = strlen(name); 133116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (nameLen > exclExtLen && 133216c4d154dca43c662571129af31b27433b919a32Adam Lesinski strcmp(name + (nameLen - exclExtLen), kExcludeExtension) == 0) 133316c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 133416c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 match(name, nameLen - exclExtLen); 133516c4d154dca43c662571129af31b27433b919a32Adam Lesinski int matchIdx; 133616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 133716c4d154dca43c662571129af31b27433b919a32Adam Lesinski matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match); 133816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (matchIdx > 0) { 133916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Excluding '%s' [%s]\n", 134016c4d154dca43c662571129af31b27433b919a32Adam Lesinski pMergedInfo->itemAt(matchIdx).getFileName().string(), 134116c4d154dca43c662571129af31b27433b919a32Adam Lesinski pMergedInfo->itemAt(matchIdx).getSourceName().string()); 134216c4d154dca43c662571129af31b27433b919a32Adam Lesinski pMergedInfo->removeAt(matchIdx); 134316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 134416c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("+++ no match on '%s'\n", (const char*) match); 134516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 134616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 134716c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGD("HEY: size=%d removing %d\n", (int)pContents->size(), i); 134816c4d154dca43c662571129af31b27433b919a32Adam Lesinski pContents->removeAt(i); 134916c4d154dca43c662571129af31b27433b919a32Adam Lesinski i--; // adjust "for" loop 135016c4d154dca43c662571129af31b27433b919a32Adam Lesinski count--; // and loop limit 135116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 135216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 135316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 135416c4d154dca43c662571129af31b27433b919a32Adam Lesinski mergeInfoLocked(pMergedInfo, pContents); 135516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 135616c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete pContents; 135716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 135816c4d154dca43c662571129af31b27433b919a32Adam Lesinski return true; 135916c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 136016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 136116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 136216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Scan the contents of the specified directory, and stuff what we find 136316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * into a newly-allocated vector. 136416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 136516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Files ending in ".gz" will have their extensions removed. 136616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 136716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * We should probably think about skipping files with "illegal" names, 136816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * e.g. illegal characters (/\:) or excessive length. 136916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 137016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Returns NULL if the specified directory doesn't exist. 137116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 137216c4d154dca43c662571129af31b27433b919a32Adam LesinskiSortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& path) 137316c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 137416c4d154dca43c662571129af31b27433b919a32Adam Lesinski SortedVector<AssetDir::FileInfo>* pContents = NULL; 137516c4d154dca43c662571129af31b27433b919a32Adam Lesinski DIR* dir; 137616c4d154dca43c662571129af31b27433b919a32Adam Lesinski struct dirent* entry; 137716c4d154dca43c662571129af31b27433b919a32Adam Lesinski FileType fileType; 137816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 137916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Scanning dir '%s'\n", path.string()); 138016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 138116c4d154dca43c662571129af31b27433b919a32Adam Lesinski dir = opendir(path.string()); 138216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (dir == NULL) 138316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return NULL; 138416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 138516c4d154dca43c662571129af31b27433b919a32Adam Lesinski pContents = new SortedVector<AssetDir::FileInfo>; 138616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 138716c4d154dca43c662571129af31b27433b919a32Adam Lesinski while (1) { 138816c4d154dca43c662571129af31b27433b919a32Adam Lesinski entry = readdir(dir); 138916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (entry == NULL) 139016c4d154dca43c662571129af31b27433b919a32Adam Lesinski break; 139116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 139216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (strcmp(entry->d_name, ".") == 0 || 139316c4d154dca43c662571129af31b27433b919a32Adam Lesinski strcmp(entry->d_name, "..") == 0) 139416c4d154dca43c662571129af31b27433b919a32Adam Lesinski continue; 139516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 139616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifdef _DIRENT_HAVE_D_TYPE 139716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (entry->d_type == DT_REG) 139816c4d154dca43c662571129af31b27433b919a32Adam Lesinski fileType = kFileTypeRegular; 139916c4d154dca43c662571129af31b27433b919a32Adam Lesinski else if (entry->d_type == DT_DIR) 140016c4d154dca43c662571129af31b27433b919a32Adam Lesinski fileType = kFileTypeDirectory; 140116c4d154dca43c662571129af31b27433b919a32Adam Lesinski else 140216c4d154dca43c662571129af31b27433b919a32Adam Lesinski fileType = kFileTypeUnknown; 140316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#else 140416c4d154dca43c662571129af31b27433b919a32Adam Lesinski // stat the file 140516c4d154dca43c662571129af31b27433b919a32Adam Lesinski fileType = ::getFileType(path.appendPathCopy(entry->d_name).string()); 140616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 140716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 140816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory) 140916c4d154dca43c662571129af31b27433b919a32Adam Lesinski continue; 141016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 141116c4d154dca43c662571129af31b27433b919a32Adam Lesinski AssetDir::FileInfo info; 141216c4d154dca43c662571129af31b27433b919a32Adam Lesinski info.set(String8(entry->d_name), fileType); 141316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (strcasecmp(info.getFileName().getPathExtension().string(), ".gz") == 0) 141416c4d154dca43c662571129af31b27433b919a32Adam Lesinski info.setFileName(info.getFileName().getBasePath()); 141516c4d154dca43c662571129af31b27433b919a32Adam Lesinski info.setSourceName(path.appendPathCopy(info.getFileName())); 141616c4d154dca43c662571129af31b27433b919a32Adam Lesinski pContents->add(info); 141716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 141816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 141916c4d154dca43c662571129af31b27433b919a32Adam Lesinski closedir(dir); 142016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return pContents; 142116c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 142216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 142316c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 142416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Scan the contents out of the specified Zip archive, and merge what we 142516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * find into "pMergedInfo". If the Zip archive in question doesn't exist, 142616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * we return immediately. 142716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 142816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Returns "false" if we found nothing to contribute. 142916c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 143016c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo, 143116c4d154dca43c662571129af31b27433b919a32Adam Lesinski const asset_path& ap, const char* rootDir, const char* baseDirName) 143216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 143316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ZipFileRO* pZip; 143416c4d154dca43c662571129af31b27433b919a32Adam Lesinski Vector<String8> dirs; 143516c4d154dca43c662571129af31b27433b919a32Adam Lesinski AssetDir::FileInfo info; 143616c4d154dca43c662571129af31b27433b919a32Adam Lesinski SortedVector<AssetDir::FileInfo> contents; 143716c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 sourceName, zipName, dirName; 143816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 143916c4d154dca43c662571129af31b27433b919a32Adam Lesinski pZip = mZipSet.getZip(ap.path); 144016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pZip == NULL) { 144116c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("Failure opening zip %s\n", ap.path.string()); 144216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 144316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 144416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 144516c4d154dca43c662571129af31b27433b919a32Adam Lesinski zipName = ZipSet::getPathName(ap.path.string()); 144616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 144716c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* convert "sounds" to "rootDir/sounds" */ 144816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (rootDir != NULL) dirName = rootDir; 144916c4d154dca43c662571129af31b27433b919a32Adam Lesinski dirName.appendPath(baseDirName); 145016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 145116c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 145216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Scan through the list of files, looking for a match. The files in 145316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * the Zip table of contents are not in sorted order, so we have to 145416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * process the entire list. We're looking for a string that begins 145516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * with the characters in "dirName", is followed by a '/', and has no 145616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * subsequent '/' in the stuff that follows. 145716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 145816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * What makes this especially fun is that directories are not stored 145916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * explicitly in Zip archives, so we have to infer them from context. 146016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * When we see "sounds/foo.wav" we have to leave a note to ourselves 146116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * to insert a directory called "sounds" into the list. We store 146216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * these in temporary vector so that we only return each one once. 146316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 146416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Name comparisons are case-sensitive to match UNIX filesystem 146516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * semantics. 146616c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 146716c4d154dca43c662571129af31b27433b919a32Adam Lesinski int dirNameLen = dirName.length(); 1468560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath void *iterationCookie; 1469560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath if (!pZip->startIteration(&iterationCookie)) { 1470560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath ALOGW("ZipFileRO::startIteration returned false"); 1471560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath return false; 1472560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath } 1473560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath 1474560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath ZipEntryRO entry; 1475560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath while ((entry = pZip->nextEntry(iterationCookie)) != NULL) { 147616c4d154dca43c662571129af31b27433b919a32Adam Lesinski char nameBuf[256]; 147716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 147816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pZip->getEntryFileName(entry, nameBuf, sizeof(nameBuf)) != 0) { 147916c4d154dca43c662571129af31b27433b919a32Adam Lesinski // TODO: fix this if we expect to have long names 148016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGE("ARGH: name too long?\n"); 148116c4d154dca43c662571129af31b27433b919a32Adam Lesinski continue; 148216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 148316c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("Comparing %s in %s?\n", nameBuf, dirName.string()); 148416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (dirNameLen == 0 || 148516c4d154dca43c662571129af31b27433b919a32Adam Lesinski (strncmp(nameBuf, dirName.string(), dirNameLen) == 0 && 148616c4d154dca43c662571129af31b27433b919a32Adam Lesinski nameBuf[dirNameLen] == '/')) 148716c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 148816c4d154dca43c662571129af31b27433b919a32Adam Lesinski const char* cp; 148916c4d154dca43c662571129af31b27433b919a32Adam Lesinski const char* nextSlash; 149016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 149116c4d154dca43c662571129af31b27433b919a32Adam Lesinski cp = nameBuf + dirNameLen; 149216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (dirNameLen != 0) 149316c4d154dca43c662571129af31b27433b919a32Adam Lesinski cp++; // advance past the '/' 149416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 149516c4d154dca43c662571129af31b27433b919a32Adam Lesinski nextSlash = strchr(cp, '/'); 149616c4d154dca43c662571129af31b27433b919a32Adam Lesinski//xxx this may break if there are bare directory entries 149716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (nextSlash == NULL) { 149816c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* this is a file in the requested directory */ 149916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 150016c4d154dca43c662571129af31b27433b919a32Adam Lesinski info.set(String8(nameBuf).getPathLeaf(), kFileTypeRegular); 150116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 150216c4d154dca43c662571129af31b27433b919a32Adam Lesinski info.setSourceName( 150316c4d154dca43c662571129af31b27433b919a32Adam Lesinski createZipSourceNameLocked(zipName, dirName, info.getFileName())); 150416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 150516c4d154dca43c662571129af31b27433b919a32Adam Lesinski contents.add(info); 150616c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("FOUND: file '%s'\n", info.getFileName().string()); 150716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 150816c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* this is a subdir; add it if we don't already have it*/ 150916c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 subdirName(cp, nextSlash - cp); 151016c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t j; 151116c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t N = dirs.size(); 151216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 151316c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (j = 0; j < N; j++) { 151416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (subdirName == dirs[j]) { 151516c4d154dca43c662571129af31b27433b919a32Adam Lesinski break; 151616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 151716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 151816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (j == N) { 151916c4d154dca43c662571129af31b27433b919a32Adam Lesinski dirs.add(subdirName); 152016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 152116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 152216c4d154dca43c662571129af31b27433b919a32Adam Lesinski //printf("FOUND: dir '%s'\n", subdirName.string()); 152316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 152416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 152516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 152616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 1527560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath pZip->endIteration(iterationCookie); 1528560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath 152916c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 153016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Add the set of unique directories. 153116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 153216c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (int i = 0; i < (int) dirs.size(); i++) { 153316c4d154dca43c662571129af31b27433b919a32Adam Lesinski info.set(dirs[i], kFileTypeDirectory); 153416c4d154dca43c662571129af31b27433b919a32Adam Lesinski info.setSourceName( 153516c4d154dca43c662571129af31b27433b919a32Adam Lesinski createZipSourceNameLocked(zipName, dirName, info.getFileName())); 153616c4d154dca43c662571129af31b27433b919a32Adam Lesinski contents.add(info); 153716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 153816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 153916c4d154dca43c662571129af31b27433b919a32Adam Lesinski mergeInfoLocked(pMergedInfo, &contents); 154016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 154116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return true; 154216c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 154316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 154416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 154516c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 154616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Merge two vectors of FileInfo. 154716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 154816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * The merged contents will be stuffed into *pMergedInfo. 154916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 155016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * If an entry for a file exists in both "pMergedInfo" and "pContents", 155116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * we use the newer "pContents" entry. 155216c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 155316c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo, 155416c4d154dca43c662571129af31b27433b919a32Adam Lesinski const SortedVector<AssetDir::FileInfo>* pContents) 155516c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 155616c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 155716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Merge what we found in this directory with what we found in 155816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * other places. 155916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 156016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Two basic approaches: 156116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * (1) Create a new array that holds the unique values of the two 156216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * arrays. 156316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * (2) Take the elements from pContents and shove them into pMergedInfo. 156416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 156516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Because these are vectors of complex objects, moving elements around 156616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * inside the vector requires constructing new objects and allocating 156716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * storage for members. With approach #1, we're always adding to the 156816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * end, whereas with #2 we could be inserting multiple elements at the 156916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * front of the vector. Approach #1 requires a full copy of the 157016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * contents of pMergedInfo, but approach #2 requires the same copy for 157116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * every insertion at the front of pMergedInfo. 157216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 157316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * (We should probably use a SortedVector interface that allows us to 157416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * just stuff items in, trusting us to maintain the sort order.) 157516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 157616c4d154dca43c662571129af31b27433b919a32Adam Lesinski SortedVector<AssetDir::FileInfo>* pNewSorted; 157716c4d154dca43c662571129af31b27433b919a32Adam Lesinski int mergeMax, contMax; 157816c4d154dca43c662571129af31b27433b919a32Adam Lesinski int mergeIdx, contIdx; 157916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 158016c4d154dca43c662571129af31b27433b919a32Adam Lesinski pNewSorted = new SortedVector<AssetDir::FileInfo>; 158116c4d154dca43c662571129af31b27433b919a32Adam Lesinski mergeMax = pMergedInfo->size(); 158216c4d154dca43c662571129af31b27433b919a32Adam Lesinski contMax = pContents->size(); 158316c4d154dca43c662571129af31b27433b919a32Adam Lesinski mergeIdx = contIdx = 0; 158416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 158516c4d154dca43c662571129af31b27433b919a32Adam Lesinski while (mergeIdx < mergeMax || contIdx < contMax) { 158616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mergeIdx == mergeMax) { 158716c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* hit end of "merge" list, copy rest of "contents" */ 158816c4d154dca43c662571129af31b27433b919a32Adam Lesinski pNewSorted->add(pContents->itemAt(contIdx)); 158916c4d154dca43c662571129af31b27433b919a32Adam Lesinski contIdx++; 159016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else if (contIdx == contMax) { 159116c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* hit end of "cont" list, copy rest of "merge" */ 159216c4d154dca43c662571129af31b27433b919a32Adam Lesinski pNewSorted->add(pMergedInfo->itemAt(mergeIdx)); 159316c4d154dca43c662571129af31b27433b919a32Adam Lesinski mergeIdx++; 159416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else if (pMergedInfo->itemAt(mergeIdx) == pContents->itemAt(contIdx)) 159516c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 159616c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* items are identical, add newer and advance both indices */ 159716c4d154dca43c662571129af31b27433b919a32Adam Lesinski pNewSorted->add(pContents->itemAt(contIdx)); 159816c4d154dca43c662571129af31b27433b919a32Adam Lesinski mergeIdx++; 159916c4d154dca43c662571129af31b27433b919a32Adam Lesinski contIdx++; 160016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else if (pMergedInfo->itemAt(mergeIdx) < pContents->itemAt(contIdx)) 160116c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 160216c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* "merge" is lower, add that one */ 160316c4d154dca43c662571129af31b27433b919a32Adam Lesinski pNewSorted->add(pMergedInfo->itemAt(mergeIdx)); 160416c4d154dca43c662571129af31b27433b919a32Adam Lesinski mergeIdx++; 160516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 160616c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* "cont" is lower, add that one */ 160716c4d154dca43c662571129af31b27433b919a32Adam Lesinski assert(pContents->itemAt(contIdx) < pMergedInfo->itemAt(mergeIdx)); 160816c4d154dca43c662571129af31b27433b919a32Adam Lesinski pNewSorted->add(pContents->itemAt(contIdx)); 160916c4d154dca43c662571129af31b27433b919a32Adam Lesinski contIdx++; 161016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 161116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 161216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 161316c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 161416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Overwrite the "merged" list with the new stuff. 161516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 161616c4d154dca43c662571129af31b27433b919a32Adam Lesinski *pMergedInfo = *pNewSorted; 161716c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete pNewSorted; 161816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 161916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#if 0 // for Vector, rather than SortedVector 162016c4d154dca43c662571129af31b27433b919a32Adam Lesinski int i, j; 162116c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (i = pContents->size() -1; i >= 0; i--) { 162216c4d154dca43c662571129af31b27433b919a32Adam Lesinski bool add = true; 162316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 162416c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (j = pMergedInfo->size() -1; j >= 0; j--) { 162516c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* case-sensitive comparisons, to behave like UNIX fs */ 162616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (strcmp(pContents->itemAt(i).mFileName, 162716c4d154dca43c662571129af31b27433b919a32Adam Lesinski pMergedInfo->itemAt(j).mFileName) == 0) 162816c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 162916c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* match, don't add this entry */ 163016c4d154dca43c662571129af31b27433b919a32Adam Lesinski add = false; 163116c4d154dca43c662571129af31b27433b919a32Adam Lesinski break; 163216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 163316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 163416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 163516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (add) 163616c4d154dca43c662571129af31b27433b919a32Adam Lesinski pMergedInfo->add(pContents->itemAt(i)); 163716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 163816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 163916c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 164016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 164116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 164216c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 164316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Load all files into the file name cache. We want to do this across 164416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * all combinations of { appname, locale, vendor }, performing a recursive 164516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * directory traversal. 164616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 164716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * This is not the most efficient data structure. Also, gathering the 164816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * information as we needed it (file-by-file or directory-by-directory) 164916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * would be faster. However, on the actual device, 99% of the files will 165016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * live in Zip archives, so this list will be very small. The trouble 165116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * is that we have to check the "loose" files first, so it's important 165216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * that we don't beat the filesystem silly looking for files that aren't 165316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * there. 165416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 165516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Note on thread safety: this is the only function that causes updates 165616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * to mCache, and anybody who tries to use it will call here if !mCacheValid, 165716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * so we need to employ a mutex here. 165816c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 165916c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::loadFileNameCacheLocked(void) 166016c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 166116c4d154dca43c662571129af31b27433b919a32Adam Lesinski assert(!mCacheValid); 166216c4d154dca43c662571129af31b27433b919a32Adam Lesinski assert(mCache.size() == 0); 166316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 166416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifdef DO_TIMINGS // need to link against -lrt for this now 166516c4d154dca43c662571129af31b27433b919a32Adam Lesinski DurationTimer timer; 166616c4d154dca43c662571129af31b27433b919a32Adam Lesinski timer.start(); 166716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 166816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 166916c4d154dca43c662571129af31b27433b919a32Adam Lesinski fncScanLocked(&mCache, ""); 167016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 167116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifdef DO_TIMINGS 167216c4d154dca43c662571129af31b27433b919a32Adam Lesinski timer.stop(); 167316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGD("Cache scan took %.3fms\n", 167416c4d154dca43c662571129af31b27433b919a32Adam Lesinski timer.durationUsecs() / 1000.0); 167516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 167616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 167716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#if 0 167816c4d154dca43c662571129af31b27433b919a32Adam Lesinski int i; 167916c4d154dca43c662571129af31b27433b919a32Adam Lesinski printf("CACHED FILE LIST (%d entries):\n", mCache.size()); 168016c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (i = 0; i < (int) mCache.size(); i++) { 168116c4d154dca43c662571129af31b27433b919a32Adam Lesinski printf(" %d: (%d) '%s'\n", i, 168216c4d154dca43c662571129af31b27433b919a32Adam Lesinski mCache.itemAt(i).getFileType(), 168316c4d154dca43c662571129af31b27433b919a32Adam Lesinski (const char*) mCache.itemAt(i).getFileName()); 168416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 168516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 168616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 168716c4d154dca43c662571129af31b27433b919a32Adam Lesinski mCacheValid = true; 168816c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 168916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 169016c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 169116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Scan up to 8 versions of the specified directory. 169216c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 169316c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo, 169416c4d154dca43c662571129af31b27433b919a32Adam Lesinski const char* dirName) 169516c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 169616c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t i = mAssetPaths.size(); 169716c4d154dca43c662571129af31b27433b919a32Adam Lesinski while (i > 0) { 169816c4d154dca43c662571129af31b27433b919a32Adam Lesinski i--; 169916c4d154dca43c662571129af31b27433b919a32Adam Lesinski const asset_path& ap = mAssetPaths.itemAt(i); 170016c4d154dca43c662571129af31b27433b919a32Adam Lesinski fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, NULL, dirName); 170116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mLocale != NULL) 170216c4d154dca43c662571129af31b27433b919a32Adam Lesinski fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, NULL, dirName); 170316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mVendor != NULL) 170416c4d154dca43c662571129af31b27433b919a32Adam Lesinski fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, mVendor, dirName); 170516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mLocale != NULL && mVendor != NULL) 170616c4d154dca43c662571129af31b27433b919a32Adam Lesinski fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, mVendor, dirName); 170716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 170816c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 170916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 171016c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 171116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Recursively scan this directory and all subdirs. 171216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 171316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * This is similar to scanAndMergeDir, but we don't remove the .EXCLUDE 171416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * files, and we prepend the extended partial path to the filenames. 171516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 171616c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool AssetManager::fncScanAndMergeDirLocked( 171716c4d154dca43c662571129af31b27433b919a32Adam Lesinski SortedVector<AssetDir::FileInfo>* pMergedInfo, 171816c4d154dca43c662571129af31b27433b919a32Adam Lesinski const asset_path& ap, const char* locale, const char* vendor, 171916c4d154dca43c662571129af31b27433b919a32Adam Lesinski const char* dirName) 172016c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 172116c4d154dca43c662571129af31b27433b919a32Adam Lesinski SortedVector<AssetDir::FileInfo>* pContents; 172216c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 partialPath; 172316c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 fullPath; 172416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 172516c4d154dca43c662571129af31b27433b919a32Adam Lesinski // XXX This is broken -- the filename cache needs to hold the base 172616c4d154dca43c662571129af31b27433b919a32Adam Lesinski // asset path separately from its filename. 172716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 172816c4d154dca43c662571129af31b27433b919a32Adam Lesinski partialPath = createPathNameLocked(ap, locale, vendor); 172916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (dirName[0] != '\0') { 173016c4d154dca43c662571129af31b27433b919a32Adam Lesinski partialPath.appendPath(dirName); 173116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 173216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 173316c4d154dca43c662571129af31b27433b919a32Adam Lesinski fullPath = partialPath; 173416c4d154dca43c662571129af31b27433b919a32Adam Lesinski pContents = scanDirLocked(fullPath); 173516c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pContents == NULL) { 173616c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; // directory did not exist 173716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 173816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 173916c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 174016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Scan all subdirectories of the current dir, merging what we find 174116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * into "pMergedInfo". 174216c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 174316c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (int i = 0; i < (int) pContents->size(); i++) { 174416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (pContents->itemAt(i).getFileType() == kFileTypeDirectory) { 174516c4d154dca43c662571129af31b27433b919a32Adam Lesinski String8 subdir(dirName); 174616c4d154dca43c662571129af31b27433b919a32Adam Lesinski subdir.appendPath(pContents->itemAt(i).getFileName()); 174716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 174816c4d154dca43c662571129af31b27433b919a32Adam Lesinski fncScanAndMergeDirLocked(pMergedInfo, ap, locale, vendor, subdir.string()); 174916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 175016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 175116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 175216c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 175316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * To be consistent, we want entries for the root directory. If 175416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * we're the root, add one now. 175516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 175616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (dirName[0] == '\0') { 175716c4d154dca43c662571129af31b27433b919a32Adam Lesinski AssetDir::FileInfo tmpInfo; 175816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 175916c4d154dca43c662571129af31b27433b919a32Adam Lesinski tmpInfo.set(String8(""), kFileTypeDirectory); 176016c4d154dca43c662571129af31b27433b919a32Adam Lesinski tmpInfo.setSourceName(createPathNameLocked(ap, locale, vendor)); 176116c4d154dca43c662571129af31b27433b919a32Adam Lesinski pContents->add(tmpInfo); 176216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 176316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 176416c4d154dca43c662571129af31b27433b919a32Adam Lesinski /* 176516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * We want to prepend the extended partial path to every entry in 176616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * "pContents". It's the same value for each entry, so this will 176716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * not change the sorting order of the vector contents. 176816c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 176916c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (int i = 0; i < (int) pContents->size(); i++) { 177016c4d154dca43c662571129af31b27433b919a32Adam Lesinski const AssetDir::FileInfo& info = pContents->itemAt(i); 177116c4d154dca43c662571129af31b27433b919a32Adam Lesinski pContents->editItemAt(i).setFileName(partialPath.appendPathCopy(info.getFileName())); 177216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 177316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 177416c4d154dca43c662571129af31b27433b919a32Adam Lesinski mergeInfoLocked(pMergedInfo, pContents); 177516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return true; 177616c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 177716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 177816c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 177916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Trash the cache. 178016c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 178116c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::purgeFileNameCacheLocked(void) 178216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 178316c4d154dca43c662571129af31b27433b919a32Adam Lesinski mCacheValid = false; 178416c4d154dca43c662571129af31b27433b919a32Adam Lesinski mCache.clear(); 178516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 178616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 178716c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 178816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * =========================================================================== 178916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * AssetManager::SharedZip 179016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * =========================================================================== 179116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 179216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 179316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 179416c4d154dca43c662571129af31b27433b919a32Adam LesinskiMutex AssetManager::SharedZip::gLock; 179516c4d154dca43c662571129af31b27433b919a32Adam LesinskiDefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen; 179616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 179716c4d154dca43c662571129af31b27433b919a32Adam LesinskiAssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen) 179816c4d154dca43c662571129af31b27433b919a32Adam Lesinski : mPath(path), mZipFile(NULL), mModWhen(modWhen), 179916c4d154dca43c662571129af31b27433b919a32Adam Lesinski mResourceTableAsset(NULL), mResourceTable(NULL) 180016c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 180116c4d154dca43c662571129af31b27433b919a32Adam Lesinski //ALOGI("Creating SharedZip %p %s\n", this, (const char*)mPath); 180216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("+++ opening zip '%s'\n", mPath.string()); 1803560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath mZipFile = ZipFileRO::open(mPath.string()); 1804560566d2915c03bed338fc532ac7f7aa3620cfdfNarayan Kamath if (mZipFile == NULL) { 180516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGD("failed to open Zip archive '%s'\n", mPath.string()); 180616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 180716c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 180816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 180916c4d154dca43c662571129af31b27433b919a32Adam Lesinskisp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path) 181016c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 181116c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(gLock); 181216c4d154dca43c662571129af31b27433b919a32Adam Lesinski time_t modWhen = getFileModDate(path); 181316c4d154dca43c662571129af31b27433b919a32Adam Lesinski sp<SharedZip> zip = gOpen.valueFor(path).promote(); 181416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (zip != NULL && zip->mModWhen == modWhen) { 181516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return zip; 181616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 181716c4d154dca43c662571129af31b27433b919a32Adam Lesinski zip = new SharedZip(path, modWhen); 181816c4d154dca43c662571129af31b27433b919a32Adam Lesinski gOpen.add(path, zip); 181916c4d154dca43c662571129af31b27433b919a32Adam Lesinski return zip; 182016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 182116c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 182216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 182316c4d154dca43c662571129af31b27433b919a32Adam LesinskiZipFileRO* AssetManager::SharedZip::getZip() 182416c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 182516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mZipFile; 182616c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 182716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 182816c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::SharedZip::getResourceTableAsset() 182916c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 183016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset); 183116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mResourceTableAsset; 183216c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 183316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 183416c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset) 183516c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 183616c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 183716c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(gLock); 183816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mResourceTableAsset == NULL) { 183916c4d154dca43c662571129af31b27433b919a32Adam Lesinski mResourceTableAsset = asset; 184016c4d154dca43c662571129af31b27433b919a32Adam Lesinski // This is not thread safe the first time it is called, so 184116c4d154dca43c662571129af31b27433b919a32Adam Lesinski // do it here with the global lock held. 184216c4d154dca43c662571129af31b27433b919a32Adam Lesinski asset->getBuffer(true); 184316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return asset; 184416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 184516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 184616c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete asset; 184716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mResourceTableAsset; 184816c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 184916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 185016c4d154dca43c662571129af31b27433b919a32Adam LesinskiResTable* AssetManager::SharedZip::getResourceTable() 185116c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 185216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Getting from SharedZip %p resource table %p\n", this, mResourceTable); 185316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mResourceTable; 185416c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 185516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 185616c4d154dca43c662571129af31b27433b919a32Adam LesinskiResTable* AssetManager::SharedZip::setResourceTable(ResTable* res) 185716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 185816c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 185916c4d154dca43c662571129af31b27433b919a32Adam Lesinski AutoMutex _l(gLock); 186016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mResourceTable == NULL) { 186116c4d154dca43c662571129af31b27433b919a32Adam Lesinski mResourceTable = res; 186216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return res; 186316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 186416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 186516c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete res; 186616c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mResourceTable; 186716c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 186816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 186916c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool AssetManager::SharedZip::isUpToDate() 187016c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 187116c4d154dca43c662571129af31b27433b919a32Adam Lesinski time_t modWhen = getFileModDate(mPath.string()); 187216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mModWhen == modWhen; 187316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 187416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 187516c4d154dca43c662571129af31b27433b919a32Adam LesinskiAssetManager::SharedZip::~SharedZip() 187616c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 187716c4d154dca43c662571129af31b27433b919a32Adam Lesinski //ALOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath); 187816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mResourceTable != NULL) { 187916c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete mResourceTable; 188016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 188116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mResourceTableAsset != NULL) { 188216c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete mResourceTableAsset; 188316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 188416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mZipFile != NULL) { 188516c4d154dca43c662571129af31b27433b919a32Adam Lesinski delete mZipFile; 188616c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGV("Closed '%s'\n", mPath.string()); 188716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 188816c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 188916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 189016c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 189116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * =========================================================================== 189216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * AssetManager::ZipSet 189316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * =========================================================================== 189416c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 189516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 189616c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 189716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Constructor. 189816c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 189916c4d154dca43c662571129af31b27433b919a32Adam LesinskiAssetManager::ZipSet::ZipSet(void) 190016c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 190116c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 190216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 190316c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 190416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Destructor. Close any open archives. 190516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 190616c4d154dca43c662571129af31b27433b919a32Adam LesinskiAssetManager::ZipSet::~ZipSet(void) 190716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 190816c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t N = mZipFile.size(); 190916c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (size_t i = 0; i < N; i++) 191016c4d154dca43c662571129af31b27433b919a32Adam Lesinski closeZip(i); 191116c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 191216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 191316c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 191416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Close a Zip file and reset the entry. 191516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 191616c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid AssetManager::ZipSet::closeZip(int idx) 191716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 191816c4d154dca43c662571129af31b27433b919a32Adam Lesinski mZipFile.editItemAt(idx) = NULL; 191916c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 192016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 192116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 192216c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 192316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Retrieve the appropriate Zip file from the set. 192416c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 192516c4d154dca43c662571129af31b27433b919a32Adam LesinskiZipFileRO* AssetManager::ZipSet::getZip(const String8& path) 192616c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 192716c4d154dca43c662571129af31b27433b919a32Adam Lesinski int idx = getIndex(path); 192816c4d154dca43c662571129af31b27433b919a32Adam Lesinski sp<SharedZip> zip = mZipFile[idx]; 192916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (zip == NULL) { 193016c4d154dca43c662571129af31b27433b919a32Adam Lesinski zip = SharedZip::get(path); 193116c4d154dca43c662571129af31b27433b919a32Adam Lesinski mZipFile.editItemAt(idx) = zip; 193216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 193316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return zip->getZip(); 193416c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 193516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 193616c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::ZipSet::getZipResourceTableAsset(const String8& path) 193716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 193816c4d154dca43c662571129af31b27433b919a32Adam Lesinski int idx = getIndex(path); 193916c4d154dca43c662571129af31b27433b919a32Adam Lesinski sp<SharedZip> zip = mZipFile[idx]; 194016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (zip == NULL) { 194116c4d154dca43c662571129af31b27433b919a32Adam Lesinski zip = SharedZip::get(path); 194216c4d154dca43c662571129af31b27433b919a32Adam Lesinski mZipFile.editItemAt(idx) = zip; 194316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 194416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return zip->getResourceTableAsset(); 194516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 194616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 194716c4d154dca43c662571129af31b27433b919a32Adam LesinskiAsset* AssetManager::ZipSet::setZipResourceTableAsset(const String8& path, 194816c4d154dca43c662571129af31b27433b919a32Adam Lesinski Asset* asset) 194916c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 195016c4d154dca43c662571129af31b27433b919a32Adam Lesinski int idx = getIndex(path); 195116c4d154dca43c662571129af31b27433b919a32Adam Lesinski sp<SharedZip> zip = mZipFile[idx]; 195216c4d154dca43c662571129af31b27433b919a32Adam Lesinski // doesn't make sense to call before previously accessing. 195316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return zip->setResourceTableAsset(asset); 195416c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 195516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 195616c4d154dca43c662571129af31b27433b919a32Adam LesinskiResTable* AssetManager::ZipSet::getZipResourceTable(const String8& path) 195716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 195816c4d154dca43c662571129af31b27433b919a32Adam Lesinski int idx = getIndex(path); 195916c4d154dca43c662571129af31b27433b919a32Adam Lesinski sp<SharedZip> zip = mZipFile[idx]; 196016c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (zip == NULL) { 196116c4d154dca43c662571129af31b27433b919a32Adam Lesinski zip = SharedZip::get(path); 196216c4d154dca43c662571129af31b27433b919a32Adam Lesinski mZipFile.editItemAt(idx) = zip; 196316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 196416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return zip->getResourceTable(); 196516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 196616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 196716c4d154dca43c662571129af31b27433b919a32Adam LesinskiResTable* AssetManager::ZipSet::setZipResourceTable(const String8& path, 196816c4d154dca43c662571129af31b27433b919a32Adam Lesinski ResTable* res) 196916c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 197016c4d154dca43c662571129af31b27433b919a32Adam Lesinski int idx = getIndex(path); 197116c4d154dca43c662571129af31b27433b919a32Adam Lesinski sp<SharedZip> zip = mZipFile[idx]; 197216c4d154dca43c662571129af31b27433b919a32Adam Lesinski // doesn't make sense to call before previously accessing. 197316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return zip->setResourceTable(res); 197416c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 197516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 197616c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 197716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Generate the partial pathname for the specified archive. The caller 197816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * gets to prepend the asset root directory. 197916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 198016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Returns something like "common/en-US-noogle.jar". 198116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 198216c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*static*/ String8 AssetManager::ZipSet::getPathName(const char* zipPath) 198316c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 198416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return String8(zipPath); 198516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 198616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 198716c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool AssetManager::ZipSet::isUpToDate() 198816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 198916c4d154dca43c662571129af31b27433b919a32Adam Lesinski const size_t N = mZipFile.size(); 199016c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (size_t i=0; i<N; i++) { 199116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mZipFile[i] != NULL && !mZipFile[i]->isUpToDate()) { 199216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 199316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 199416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 199516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return true; 199616c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 199716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 199816c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 199916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Compute the zip file's index. 200016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 200116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * "appName", "locale", and "vendor" should be set to NULL to indicate the 200216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * default directory. 200316c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 200416c4d154dca43c662571129af31b27433b919a32Adam Lesinskiint AssetManager::ZipSet::getIndex(const String8& zip) const 200516c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 200616c4d154dca43c662571129af31b27433b919a32Adam Lesinski const size_t N = mZipPath.size(); 200716c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (size_t i=0; i<N; i++) { 200816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mZipPath[i] == zip) { 200916c4d154dca43c662571129af31b27433b919a32Adam Lesinski return i; 201016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 201116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 201216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 201316c4d154dca43c662571129af31b27433b919a32Adam Lesinski mZipPath.add(zip); 201416c4d154dca43c662571129af31b27433b919a32Adam Lesinski mZipFile.add(NULL); 201516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 201616c4d154dca43c662571129af31b27433b919a32Adam Lesinski return mZipPath.size()-1; 201716c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 2018