de898ff429
Shared libraries can now export resources for applications to use. Exporting resources works the same way the framework exports resources, by defining the public symbols in res/values/public.xml. Building a shared library requires aapt to be invoked with the --shared-lib option. Shared libraries will be assigned a package ID of 0x00 at build-time. At runtime, all loaded shared libraries will be assigned a new package ID. Currently, shared libraries should not import other shared libraries, as those dependencies will not be loaded at runtime. At runtime, reflection is used to update the package ID of resource symbols in the shared library's R class file. The package name of the R class file is assumed to be the same as the shared library's package name declared in its manifest. This will be customizable in a future commit. See /tests/SharedLibrary/ for examples of a shared library and its client. Bug:12724178 Change-Id: I60c0cb8ab87849f8f8a1a13431562fe8603020a7
108 lines
2.9 KiB
C++
108 lines
2.9 KiB
C++
//
|
|
// Copyright 2012 The Android Open Source Project
|
|
//
|
|
// Manage a resource ID cache.
|
|
|
|
#define LOG_TAG "ResourceIdCache"
|
|
|
|
#include <utils/String16.h>
|
|
#include <utils/Log.h>
|
|
#include "ResourceIdCache.h"
|
|
#include <map>
|
|
using namespace std;
|
|
|
|
|
|
static size_t mHits = 0;
|
|
static size_t mMisses = 0;
|
|
static size_t mCollisions = 0;
|
|
|
|
static const size_t MAX_CACHE_ENTRIES = 2048;
|
|
static const android::String16 TRUE16("1");
|
|
static const android::String16 FALSE16("0");
|
|
|
|
struct CacheEntry {
|
|
// concatenation of the relevant strings into a single instance
|
|
android::String16 hashedName;
|
|
uint32_t id;
|
|
|
|
CacheEntry() {}
|
|
CacheEntry(const android::String16& name, uint32_t resId) : hashedName(name), id(resId) { }
|
|
};
|
|
|
|
static map< uint32_t, CacheEntry > mIdMap;
|
|
|
|
|
|
// djb2; reasonable choice for strings when collisions aren't particularly important
|
|
static inline uint32_t hashround(uint32_t hash, int c) {
|
|
return ((hash << 5) + hash) + c; /* hash * 33 + c */
|
|
}
|
|
|
|
static uint32_t hash(const android::String16& hashableString) {
|
|
uint32_t hash = 5381;
|
|
const char16_t* str = hashableString.string();
|
|
while (int c = *str++) hash = hashround(hash, c);
|
|
return hash;
|
|
}
|
|
|
|
namespace android {
|
|
|
|
static inline String16 makeHashableName(const android::String16& package,
|
|
const android::String16& type,
|
|
const android::String16& name,
|
|
bool onlyPublic) {
|
|
String16 hashable = String16(name);
|
|
hashable += type;
|
|
hashable += package;
|
|
hashable += (onlyPublic ? TRUE16 : FALSE16);
|
|
return hashable;
|
|
}
|
|
|
|
uint32_t ResourceIdCache::lookup(const android::String16& package,
|
|
const android::String16& type,
|
|
const android::String16& name,
|
|
bool onlyPublic) {
|
|
const String16 hashedName = makeHashableName(package, type, name, onlyPublic);
|
|
const uint32_t hashcode = hash(hashedName);
|
|
map<uint32_t, CacheEntry>::iterator item = mIdMap.find(hashcode);
|
|
if (item == mIdMap.end()) {
|
|
// cache miss
|
|
mMisses++;
|
|
return 0;
|
|
}
|
|
|
|
// legit match?
|
|
if (hashedName == (*item).second.hashedName) {
|
|
mHits++;
|
|
return (*item).second.id;
|
|
}
|
|
|
|
// collision
|
|
mCollisions++;
|
|
mIdMap.erase(hashcode);
|
|
return 0;
|
|
}
|
|
|
|
// returns the resource ID being stored, for callsite convenience
|
|
uint32_t ResourceIdCache::store(const android::String16& package,
|
|
const android::String16& type,
|
|
const android::String16& name,
|
|
bool onlyPublic,
|
|
uint32_t resId) {
|
|
if (mIdMap.size() < MAX_CACHE_ENTRIES) {
|
|
const String16 hashedName = makeHashableName(package, type, name, onlyPublic);
|
|
const uint32_t hashcode = hash(hashedName);
|
|
mIdMap[hashcode] = CacheEntry(hashedName, resId);
|
|
}
|
|
return resId;
|
|
}
|
|
|
|
void ResourceIdCache::dump() {
|
|
printf("ResourceIdCache dump:\n");
|
|
printf("Size: %zd\n", mIdMap.size());
|
|
printf("Hits: %zd\n", mHits);
|
|
printf("Misses: %zd\n", mMisses);
|
|
printf("(Collisions: %zd)\n", mCollisions);
|
|
}
|
|
|
|
}
|