Merge "Do not look for R.class of overlays"
This commit is contained in:
committed by
Android (Google) Code Review
commit
9f43c201fe
@@ -1215,7 +1215,8 @@ public final class LoadedApk {
|
||||
}
|
||||
|
||||
// Rewrite the R 'constants' for all library apks.
|
||||
SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
|
||||
SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers(
|
||||
false, false);
|
||||
final int N = packageIdentifiers.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final int id = packageIdentifiers.keyAt(i);
|
||||
|
||||
@@ -1491,9 +1491,17 @@ public final class AssetManager implements AutoCloseable {
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public SparseArray<String> getAssignedPackageIdentifiers() {
|
||||
return getAssignedPackageIdentifiers(true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public SparseArray<String> getAssignedPackageIdentifiers(boolean includeOverlays,
|
||||
boolean includeLoaders) {
|
||||
synchronized (this) {
|
||||
ensureValidLocked();
|
||||
return nativeGetAssignedPackageIdentifiers(mObject);
|
||||
return nativeGetAssignedPackageIdentifiers(mObject, includeOverlays, includeLoaders);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1557,7 +1565,7 @@ public final class AssetManager implements AutoCloseable {
|
||||
int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, int screenLayout,
|
||||
int uiMode, int colorMode, int majorVersion);
|
||||
private static native @NonNull SparseArray<String> nativeGetAssignedPackageIdentifiers(
|
||||
long ptr);
|
||||
long ptr, boolean includeOverlays, boolean includeLoaders);
|
||||
|
||||
// File native methods.
|
||||
private static native @Nullable String[] nativeList(long ptr, @NonNull String path)
|
||||
|
||||
@@ -556,7 +556,9 @@ static void NativeSetConfiguration(JNIEnv* env, jclass /*clazz*/, jlong ptr, jin
|
||||
assetmanager->SetConfiguration(configuration);
|
||||
}
|
||||
|
||||
static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/, jlong ptr) {
|
||||
static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/, jlong ptr,
|
||||
jboolean includeOverlays,
|
||||
jboolean includeLoaders) {
|
||||
ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
|
||||
|
||||
jobject sparse_array =
|
||||
@@ -567,6 +569,10 @@ static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Optionally exclude overlays and loaders.
|
||||
uint64_t exclusion_flags = ((includeOverlays) ? 0U : PROPERTY_OVERLAY)
|
||||
| ((includeLoaders) ? 0U : PROPERTY_LOADER);
|
||||
|
||||
assetmanager->ForEachPackage([&](const std::string& package_name, uint8_t package_id) -> bool {
|
||||
jstring jpackage_name = env->NewStringUTF(package_name.c_str());
|
||||
if (jpackage_name == nullptr) {
|
||||
@@ -577,7 +583,8 @@ static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/
|
||||
env->CallVoidMethod(sparse_array, gSparseArrayOffsets.put, static_cast<jint>(package_id),
|
||||
jpackage_name);
|
||||
return true;
|
||||
});
|
||||
}, exclusion_flags);
|
||||
|
||||
return sparse_array;
|
||||
}
|
||||
|
||||
@@ -1591,7 +1598,7 @@ static const JNINativeMethod gAssetManagerMethods[] = {
|
||||
{"nativeSetApkAssets", "(J[Landroid/content/res/ApkAssets;Z)V", (void*)NativeSetApkAssets},
|
||||
{"nativeSetConfiguration", "(JIILjava/lang/String;IIIIIIIIIIIIIII)V",
|
||||
(void*)NativeSetConfiguration},
|
||||
{"nativeGetAssignedPackageIdentifiers", "(J)Landroid/util/SparseArray;",
|
||||
{"nativeGetAssignedPackageIdentifiers", "(JZZ)Landroid/util/SparseArray;",
|
||||
(void*)NativeGetAssignedPackageIdentifiers},
|
||||
|
||||
// AssetManager file methods.
|
||||
|
||||
@@ -43,20 +43,22 @@ static const std::string kResourcesArsc("resources.arsc");
|
||||
ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle,
|
||||
const std::string& path,
|
||||
time_t last_mod_time,
|
||||
bool for_loader)
|
||||
package_property_t property_flags)
|
||||
: zip_handle_(unmanaged_handle, ::CloseArchive), path_(path), last_mod_time_(last_mod_time),
|
||||
for_loader_(for_loader) {
|
||||
property_flags_(property_flags) {
|
||||
}
|
||||
|
||||
std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system,
|
||||
bool for_loader) {
|
||||
return LoadImpl({} /*fd*/, path, nullptr, nullptr, system, false /*load_as_shared_library*/,
|
||||
for_loader);
|
||||
package_property_t flags = (system ? PROPERTY_SYSTEM : 0U) |
|
||||
(for_loader ? PROPERTY_LOADER : 0U);
|
||||
return LoadImpl({} /*fd*/, path, nullptr, nullptr, flags);
|
||||
}
|
||||
|
||||
std::unique_ptr<const ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path,
|
||||
bool system) {
|
||||
return LoadImpl({} /*fd*/, path, nullptr, nullptr, system, true /*load_as_shared_library*/);
|
||||
package_property_t flags = PROPERTY_DYNAMIC | (system ? PROPERTY_SYSTEM : 0U);
|
||||
return LoadImpl({} /*fd*/, path, nullptr, nullptr, flags);
|
||||
}
|
||||
|
||||
std::unique_ptr<const ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap_path,
|
||||
@@ -74,27 +76,33 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap
|
||||
LOG(ERROR) << "failed to load IDMAP " << idmap_path;
|
||||
return {};
|
||||
}
|
||||
return LoadImpl({} /*fd*/, loaded_idmap->OverlayApkPath(), std::move(idmap_asset),
|
||||
std::move(loaded_idmap), system, true /*load_as_shared_library*/);
|
||||
|
||||
return LoadImpl({} /*fd*/, loaded_idmap->OverlayApkPath(),
|
||||
std::move(idmap_asset),
|
||||
std::move(loaded_idmap),
|
||||
PROPERTY_OVERLAY | (system ? PROPERTY_SYSTEM : 0U));
|
||||
}
|
||||
|
||||
std::unique_ptr<const ApkAssets> ApkAssets::LoadFromFd(unique_fd fd,
|
||||
const std::string& friendly_name,
|
||||
bool system, bool force_shared_lib,
|
||||
bool for_loader) {
|
||||
package_property_t flags = (system ? PROPERTY_SYSTEM : 0U) |
|
||||
(force_shared_lib ? PROPERTY_DYNAMIC : 0U) |
|
||||
(for_loader ? PROPERTY_LOADER : 0U);
|
||||
return LoadImpl(std::move(fd), friendly_name, nullptr /*idmap_asset*/, nullptr /*loaded_idmap*/,
|
||||
system, force_shared_lib, for_loader);
|
||||
flags);
|
||||
}
|
||||
|
||||
std::unique_ptr<const ApkAssets> ApkAssets::LoadArsc(const std::string& path,
|
||||
bool for_loader) {
|
||||
return LoadArscImpl({} /*fd*/, path, for_loader);
|
||||
return LoadArscImpl({} /*fd*/, path, for_loader ? PROPERTY_LOADER : 0U);
|
||||
}
|
||||
|
||||
std::unique_ptr<const ApkAssets> ApkAssets::LoadArsc(unique_fd fd,
|
||||
const std::string& friendly_name,
|
||||
bool for_loader) {
|
||||
return LoadArscImpl(std::move(fd), friendly_name, for_loader);
|
||||
return LoadArscImpl(std::move(fd), friendly_name, for_loader ? PROPERTY_LOADER : 0U);
|
||||
}
|
||||
|
||||
std::unique_ptr<Asset> ApkAssets::CreateAssetFromFile(const std::string& path) {
|
||||
@@ -120,8 +128,7 @@ std::unique_ptr<Asset> ApkAssets::CreateAssetFromFile(const std::string& path) {
|
||||
|
||||
std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
|
||||
unique_fd fd, const std::string& path, std::unique_ptr<Asset> idmap_asset,
|
||||
std::unique_ptr<const LoadedIdmap> loaded_idmap, bool system, bool load_as_shared_library,
|
||||
bool for_loader) {
|
||||
std::unique_ptr<const LoadedIdmap> loaded_idmap, package_property_t property_flags) {
|
||||
::ZipArchiveHandle unmanaged_handle;
|
||||
int32_t result;
|
||||
if (fd >= 0) {
|
||||
@@ -141,7 +148,7 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
|
||||
|
||||
// Wrap the handle in a unique_ptr so it gets automatically closed.
|
||||
std::unique_ptr<ApkAssets>
|
||||
loaded_apk(new ApkAssets(unmanaged_handle, path, last_mod_time, for_loader));
|
||||
loaded_apk(new ApkAssets(unmanaged_handle, path, last_mod_time, property_flags));
|
||||
|
||||
// Find the resource table.
|
||||
::ZipEntry entry;
|
||||
@@ -170,9 +177,8 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
|
||||
const StringPiece data(
|
||||
reinterpret_cast<const char*>(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/)),
|
||||
loaded_apk->resources_asset_->getLength());
|
||||
loaded_apk->loaded_arsc_ =
|
||||
LoadedArsc::Load(data, loaded_apk->loaded_idmap_.get(), system, load_as_shared_library,
|
||||
for_loader);
|
||||
loaded_apk->loaded_arsc_ = LoadedArsc::Load(data, loaded_apk->loaded_idmap_.get(),
|
||||
property_flags);
|
||||
if (loaded_apk->loaded_arsc_ == nullptr) {
|
||||
LOG(ERROR) << "Failed to load '" << kResourcesArsc << "' in APK '" << path << "'.";
|
||||
return {};
|
||||
@@ -184,7 +190,7 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(
|
||||
|
||||
std::unique_ptr<const ApkAssets> ApkAssets::LoadArscImpl(unique_fd fd,
|
||||
const std::string& path,
|
||||
bool for_loader) {
|
||||
package_property_t property_flags) {
|
||||
std::unique_ptr<Asset> resources_asset;
|
||||
|
||||
if (fd >= 0) {
|
||||
@@ -201,13 +207,14 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadArscImpl(unique_fd fd,
|
||||
|
||||
time_t last_mod_time = getFileModDate(path.c_str());
|
||||
|
||||
std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(nullptr, path, last_mod_time, for_loader));
|
||||
std::unique_ptr<ApkAssets> loaded_apk(
|
||||
new ApkAssets(nullptr, path, last_mod_time, property_flags));
|
||||
loaded_apk->resources_asset_ = std::move(resources_asset);
|
||||
|
||||
const StringPiece data(
|
||||
reinterpret_cast<const char*>(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/)),
|
||||
loaded_apk->resources_asset_->getLength());
|
||||
loaded_apk->loaded_arsc_ = LoadedArsc::Load(data, nullptr, false, false, for_loader);
|
||||
loaded_apk->loaded_arsc_ = LoadedArsc::Load(data, nullptr, property_flags);
|
||||
if (loaded_apk->loaded_arsc_ == nullptr) {
|
||||
LOG(ERROR) << "Failed to load '" << kResourcesArsc << path;
|
||||
return {};
|
||||
@@ -320,8 +327,8 @@ bool ApkAssets::ForEachFile(const std::string& root_path,
|
||||
}
|
||||
|
||||
bool ApkAssets::IsUpToDate() const {
|
||||
// Loaders are invalidated by the app, not the system, so assume up to date
|
||||
if (for_loader_) {
|
||||
if (IsLoader()) {
|
||||
// Loaders are invalidated by the app, not the system, so assume up to date.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ static bool compare_overlay_entries(const Idmap_overlay_entry& e1, const uint32_
|
||||
}
|
||||
|
||||
OverlayStringPool::OverlayStringPool(const LoadedIdmap* loaded_idmap)
|
||||
: data_header_(loaded_idmap->data_header_),
|
||||
idmap_string_pool_(loaded_idmap->string_pool_.get()) { };
|
||||
: data_header_(loaded_idmap->data_header_),
|
||||
idmap_string_pool_(loaded_idmap->string_pool_.get()) { };
|
||||
|
||||
OverlayStringPool::~OverlayStringPool() {
|
||||
uninit();
|
||||
@@ -188,11 +188,12 @@ LoadedIdmap::LoadedIdmap(const Idmap_header* header,
|
||||
const Idmap_data_header* data_header,
|
||||
const Idmap_target_entry* target_entries,
|
||||
const Idmap_overlay_entry* overlay_entries,
|
||||
ResStringPool* string_pool) : header_(header),
|
||||
data_header_(data_header),
|
||||
target_entries_(target_entries),
|
||||
overlay_entries_(overlay_entries),
|
||||
string_pool_(string_pool) {
|
||||
ResStringPool* string_pool)
|
||||
: header_(header),
|
||||
data_header_(data_header),
|
||||
target_entries_(target_entries),
|
||||
overlay_entries_(overlay_entries),
|
||||
string_pool_(string_pool) {
|
||||
|
||||
size_t length = strnlen(reinterpret_cast<const char*>(header_->overlay_path),
|
||||
arraysize(header_->overlay_path));
|
||||
@@ -264,7 +265,7 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_da
|
||||
}
|
||||
}
|
||||
|
||||
// Can't use make_unique because LoadedImpl constructor is private.
|
||||
// Can't use make_unique because LoadedIdmap constructor is private.
|
||||
std::unique_ptr<LoadedIdmap> loaded_idmap = std::unique_ptr<LoadedIdmap>(
|
||||
new LoadedIdmap(header, data_header, target_entries, overlay_entries,
|
||||
idmap_string_pool.release()));
|
||||
|
||||
@@ -397,9 +397,7 @@ const LoadedPackage* LoadedArsc::GetPackageById(uint8_t package_id) const {
|
||||
}
|
||||
|
||||
std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
|
||||
bool system,
|
||||
bool load_as_shared_library,
|
||||
bool for_loader) {
|
||||
package_property_t property_flags) {
|
||||
ATRACE_NAME("LoadedPackage::Load");
|
||||
std::unique_ptr<LoadedPackage> loaded_package(new LoadedPackage());
|
||||
|
||||
@@ -413,17 +411,24 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
|
||||
return {};
|
||||
}
|
||||
|
||||
loaded_package->system_ = system;
|
||||
if ((property_flags & PROPERTY_SYSTEM) != 0) {
|
||||
loaded_package->property_flags_ |= PROPERTY_SYSTEM;
|
||||
}
|
||||
|
||||
if ((property_flags & PROPERTY_LOADER) != 0) {
|
||||
loaded_package->property_flags_ |= PROPERTY_LOADER;
|
||||
}
|
||||
|
||||
if ((property_flags & PROPERTY_OVERLAY) != 0) {
|
||||
// Overlay resources must have an exclusive resource id space for referencing internal
|
||||
// resources.
|
||||
loaded_package->property_flags_ |= PROPERTY_OVERLAY | PROPERTY_DYNAMIC;
|
||||
}
|
||||
|
||||
loaded_package->package_id_ = dtohl(header->id);
|
||||
if (loaded_package->package_id_ == 0 ||
|
||||
(loaded_package->package_id_ == kAppPackageId && load_as_shared_library)) {
|
||||
// Package ID of 0 means this is a shared library.
|
||||
loaded_package->dynamic_ = true;
|
||||
}
|
||||
|
||||
if (for_loader) {
|
||||
loaded_package->custom_loader_ = true;
|
||||
(loaded_package->package_id_ == kAppPackageId && (property_flags & PROPERTY_DYNAMIC) != 0)) {
|
||||
loaded_package->property_flags_ |= PROPERTY_DYNAMIC;
|
||||
}
|
||||
|
||||
if (header->header.headerSize >= sizeof(ResTable_package)) {
|
||||
@@ -677,7 +682,7 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
|
||||
}
|
||||
|
||||
bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
|
||||
bool load_as_shared_library, bool for_loader) {
|
||||
package_property_t property_flags) {
|
||||
const ResTable_header* header = chunk.header<ResTable_header>();
|
||||
if (header == nullptr) {
|
||||
LOG(ERROR) << "RES_TABLE_TYPE too small.";
|
||||
@@ -720,7 +725,7 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
|
||||
packages_seen++;
|
||||
|
||||
std::unique_ptr<const LoadedPackage> loaded_package =
|
||||
LoadedPackage::Load(child_chunk, system_, load_as_shared_library, for_loader);
|
||||
LoadedPackage::Load(child_chunk, property_flags);
|
||||
if (!loaded_package) {
|
||||
return false;
|
||||
}
|
||||
@@ -744,24 +749,18 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
|
||||
|
||||
std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const StringPiece& data,
|
||||
const LoadedIdmap* loaded_idmap,
|
||||
bool system,
|
||||
bool load_as_shared_library,
|
||||
bool for_loader) {
|
||||
package_property_t property_flags) {
|
||||
ATRACE_NAME("LoadedArsc::Load");
|
||||
|
||||
// Not using make_unique because the constructor is private.
|
||||
std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc());
|
||||
loaded_arsc->system_ = system;
|
||||
|
||||
ChunkIterator iter(data.data(), data.size());
|
||||
while (iter.HasNext()) {
|
||||
const Chunk chunk = iter.Next();
|
||||
switch (chunk.type()) {
|
||||
case RES_TABLE_TYPE:
|
||||
if (!loaded_arsc->LoadTable(chunk,
|
||||
loaded_idmap,
|
||||
load_as_shared_library,
|
||||
for_loader)) {
|
||||
if (!loaded_arsc->LoadTable(chunk, loaded_idmap, property_flags)) {
|
||||
return {};
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -76,10 +76,10 @@ class ApkAssets {
|
||||
// Takes ownership of the file descriptor.
|
||||
static std::unique_ptr<const ApkAssets> LoadArsc(base::unique_fd fd,
|
||||
const std::string& friendly_name,
|
||||
bool resource_loader = false);
|
||||
bool for_loader = false);
|
||||
|
||||
// Creates a totally empty ApkAssets with no resources table and no file entries.
|
||||
static std::unique_ptr<const ApkAssets> LoadEmpty(bool resource_loader = false);
|
||||
static std::unique_ptr<const ApkAssets> LoadEmpty(bool for_loader = false);
|
||||
|
||||
std::unique_ptr<Asset> Open(const std::string& path,
|
||||
Asset::AccessMode mode = Asset::AccessMode::ACCESS_RANDOM) const;
|
||||
@@ -100,12 +100,12 @@ class ApkAssets {
|
||||
return loaded_idmap_.get();
|
||||
}
|
||||
|
||||
inline bool IsOverlay() const {
|
||||
return idmap_asset_.get() != nullptr;
|
||||
inline bool IsLoader() const {
|
||||
return (property_flags_ & PROPERTY_LOADER) != 0;
|
||||
}
|
||||
|
||||
inline bool IsLoader() const {
|
||||
return for_loader_;
|
||||
inline bool IsOverlay() const {
|
||||
return (property_flags_ & PROPERTY_OVERLAY) != 0;
|
||||
}
|
||||
|
||||
bool IsUpToDate() const;
|
||||
@@ -119,24 +119,23 @@ class ApkAssets {
|
||||
static std::unique_ptr<const ApkAssets> LoadImpl(base::unique_fd fd, const std::string& path,
|
||||
std::unique_ptr<Asset> idmap_asset,
|
||||
std::unique_ptr<const LoadedIdmap> loaded_idmap,
|
||||
bool system, bool load_as_shared_library,
|
||||
bool resource_loader = false);
|
||||
package_property_t property_flags);
|
||||
|
||||
static std::unique_ptr<const ApkAssets> LoadArscImpl(base::unique_fd fd,
|
||||
const std::string& path,
|
||||
bool resource_loader = false);
|
||||
package_property_t property_flags);
|
||||
|
||||
ApkAssets(ZipArchiveHandle unmanaged_handle,
|
||||
const std::string& path,
|
||||
time_t last_mod_time,
|
||||
bool for_loader = false);
|
||||
package_property_t property_flags);
|
||||
|
||||
using ZipArchivePtr = std::unique_ptr<ZipArchive, void (*)(ZipArchiveHandle)>;
|
||||
|
||||
ZipArchivePtr zip_handle_;
|
||||
const std::string path_;
|
||||
time_t last_mod_time_;
|
||||
bool for_loader_;
|
||||
package_property_t property_flags_ = 0U;
|
||||
std::unique_ptr<Asset> resources_asset_;
|
||||
std::unique_ptr<Asset> idmap_asset_;
|
||||
std::unique_ptr<const LoadedArsc> loaded_arsc_;
|
||||
|
||||
@@ -263,10 +263,13 @@ class AssetManager2 {
|
||||
// Creates a new Theme from this AssetManager.
|
||||
std::unique_ptr<Theme> NewTheme();
|
||||
|
||||
void ForEachPackage(const std::function<bool(const std::string&, uint8_t)> func) const {
|
||||
void ForEachPackage(const std::function<bool(const std::string&, uint8_t)> func,
|
||||
package_property_t excluded_property_flags = 0U) const {
|
||||
for (const PackageGroup& package_group : package_groups_) {
|
||||
if (!func(package_group.packages_.front().loaded_package_->GetPackageName(),
|
||||
package_group.dynamic_ref_table->mAssignedPackageId)) {
|
||||
const auto loaded_package = package_group.packages_.front().loaded_package_;
|
||||
if ((loaded_package->GetPropertyFlags() & excluded_property_flags) == 0U
|
||||
&& !func(loaded_package->GetPackageName(),
|
||||
package_group.dynamic_ref_table->mAssignedPackageId)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,14 @@ struct TypeSpec {
|
||||
}
|
||||
};
|
||||
|
||||
using package_property_t = uint32_t;
|
||||
enum : package_property_t {
|
||||
PROPERTY_DYNAMIC = 1,
|
||||
PROPERTY_LOADER = 2,
|
||||
PROPERTY_OVERLAY = 4,
|
||||
PROPERTY_SYSTEM = 8,
|
||||
};
|
||||
|
||||
// TypeSpecPtr points to a block of memory that holds a TypeSpec struct, followed by an array of
|
||||
// ResTable_type pointers.
|
||||
// TypeSpecPtr is a managed pointer that knows how to delete itself.
|
||||
@@ -131,9 +139,8 @@ class LoadedPackage {
|
||||
return iterator(this, resource_ids_.size() + 1, 0);
|
||||
}
|
||||
|
||||
static std::unique_ptr<const LoadedPackage> Load(const Chunk& chunk, bool system,
|
||||
bool load_as_shared_library,
|
||||
bool load_as_custom_loader);
|
||||
static std::unique_ptr<const LoadedPackage> Load(const Chunk& chunk,
|
||||
package_property_t property_flags);
|
||||
|
||||
~LoadedPackage();
|
||||
|
||||
@@ -170,17 +177,26 @@ class LoadedPackage {
|
||||
|
||||
// Returns true if this package is dynamic (shared library) and needs to have an ID assigned.
|
||||
inline bool IsDynamic() const {
|
||||
return dynamic_;
|
||||
return (property_flags_ & PROPERTY_DYNAMIC) != 0;
|
||||
}
|
||||
|
||||
// Returns true if this package is a Runtime Resource Overlay.
|
||||
inline bool IsOverlay() const {
|
||||
return (property_flags_ & PROPERTY_OVERLAY) != 0;
|
||||
}
|
||||
|
||||
// Returns true if this package originates from a system provided resource.
|
||||
inline bool IsSystem() const {
|
||||
return system_;
|
||||
return (property_flags_ & PROPERTY_SYSTEM) != 0;
|
||||
}
|
||||
|
||||
// Returns true if this package is a custom loader and should behave like an overlay
|
||||
// Returns true if this package is a custom loader and should behave like an overlay.
|
||||
inline bool IsCustomLoader() const {
|
||||
return custom_loader_;
|
||||
return (property_flags_ & PROPERTY_LOADER) != 0;
|
||||
}
|
||||
|
||||
inline package_property_t GetPropertyFlags() const {
|
||||
return property_flags_;
|
||||
}
|
||||
|
||||
// Returns the map of package name to package ID used in this LoadedPackage. At runtime, a
|
||||
@@ -248,12 +264,10 @@ class LoadedPackage {
|
||||
ResStringPool type_string_pool_;
|
||||
ResStringPool key_string_pool_;
|
||||
std::string package_name_;
|
||||
bool defines_overlayable_ = false;
|
||||
int package_id_ = -1;
|
||||
int type_id_offset_ = 0;
|
||||
bool dynamic_ = false;
|
||||
bool system_ = false;
|
||||
bool custom_loader_ = false;
|
||||
bool defines_overlayable_ = false;
|
||||
package_property_t property_flags_ = 0U;
|
||||
|
||||
ByteBucketArray<TypeSpecPtr> type_specs_;
|
||||
ByteBucketArray<uint32_t> resource_ids_;
|
||||
@@ -274,9 +288,7 @@ class LoadedArsc {
|
||||
// ID.
|
||||
static std::unique_ptr<const LoadedArsc> Load(const StringPiece& data,
|
||||
const LoadedIdmap* loaded_idmap = nullptr,
|
||||
bool system = false,
|
||||
bool load_as_shared_library = false,
|
||||
bool for_loader = false);
|
||||
package_property_t property_flags = 0U);
|
||||
|
||||
// Create an empty LoadedArsc. This is used when an APK has no resources.arsc.
|
||||
static std::unique_ptr<const LoadedArsc> CreateEmpty();
|
||||
@@ -296,28 +308,15 @@ class LoadedArsc {
|
||||
return packages_;
|
||||
}
|
||||
|
||||
// Returns true if this is a system provided resource.
|
||||
inline bool IsSystem() const {
|
||||
return system_;
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(LoadedArsc);
|
||||
|
||||
LoadedArsc() = default;
|
||||
bool LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, bool load_as_shared_library,
|
||||
bool for_loader);
|
||||
|
||||
static std::unique_ptr<const LoadedArsc> LoadData(std::unique_ptr<LoadedArsc>& loaded_arsc,
|
||||
const char* data,
|
||||
size_t length,
|
||||
const LoadedIdmap* loaded_idmap = nullptr,
|
||||
bool load_as_shared_library = false,
|
||||
bool for_loader = false);
|
||||
bool LoadTable(
|
||||
const Chunk& chunk, const LoadedIdmap* loaded_idmap, package_property_t property_flags);
|
||||
|
||||
std::unique_ptr<ResStringPool> global_string_pool_ = util::make_unique<ResStringPool>();
|
||||
std::vector<std::unique_ptr<const LoadedPackage>> packages_;
|
||||
bool system_ = false;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -144,8 +144,7 @@ TEST(LoadedArscTest, LoadAppAsSharedLibrary) {
|
||||
"resources.arsc", &contents));
|
||||
|
||||
std::unique_ptr<const LoadedArsc> loaded_arsc =
|
||||
LoadedArsc::Load(StringPiece(contents), nullptr /* loaded_idmap */, false /*system*/,
|
||||
true /*load_as_shared_library*/);
|
||||
LoadedArsc::Load(StringPiece(contents), nullptr /* loaded_idmap */, PROPERTY_DYNAMIC);
|
||||
ASSERT_THAT(loaded_arsc, NotNull());
|
||||
|
||||
const auto& packages = loaded_arsc->GetPackages();
|
||||
@@ -227,9 +226,7 @@ TEST(LoadedArscTest, LoadOverlayable) {
|
||||
ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/overlayable/overlayable.apk",
|
||||
"resources.arsc", &contents));
|
||||
|
||||
std::unique_ptr<const LoadedArsc> loaded_arsc =
|
||||
LoadedArsc::Load(StringPiece(contents), nullptr /* loaded_idmap */, false /*system*/,
|
||||
false /*load_as_shared_library*/);
|
||||
std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
|
||||
|
||||
ASSERT_THAT(loaded_arsc, NotNull());
|
||||
const LoadedPackage* package = loaded_arsc->GetPackageById(
|
||||
@@ -346,7 +343,7 @@ TEST(LoadedArscTest, LoadCustomLoader) {
|
||||
asset->getLength());
|
||||
|
||||
std::unique_ptr<const LoadedArsc> loaded_arsc =
|
||||
LoadedArsc::Load(data, nullptr, false, false, true);
|
||||
LoadedArsc::Load(data, nullptr, PROPERTY_LOADER);
|
||||
ASSERT_THAT(loaded_arsc, NotNull());
|
||||
|
||||
const LoadedPackage* package =
|
||||
|
||||
Reference in New Issue
Block a user