Fix GetResourceName for shared libraries
GetResourceName used GetPAckageById which only works when the compile time package id is eqal to the runtime package id. This change resolves resource names correctly using the ruuntime package id. Bug: 79666085 Test: libandroidfw_tests Change-Id: Ic60cb2416329c5cb34e925991cd689ca7574b483
This commit is contained in:
@@ -562,7 +562,7 @@ std::string AssetManager2::GetLastResourceResolution() const {
|
||||
if (package != nullptr) {
|
||||
ToResourceName(last_resolution.type_string_ref,
|
||||
last_resolution.entry_string_ref,
|
||||
package,
|
||||
package->GetPackageName(),
|
||||
&resource_name);
|
||||
resource_name_string = ToFormattedResourceString(&resource_name);
|
||||
}
|
||||
@@ -607,15 +607,25 @@ bool AssetManager2::GetResourceName(uint32_t resid, ResourceName* out_name) cons
|
||||
return false;
|
||||
}
|
||||
|
||||
const LoadedPackage* package =
|
||||
apk_assets_[cookie]->GetLoadedArsc()->GetPackageById(get_package_id(resid));
|
||||
if (package == nullptr) {
|
||||
const uint8_t package_idx = package_ids_[get_package_id(resid)];
|
||||
if (package_idx == 0xff) {
|
||||
LOG(ERROR) << base::StringPrintf("No package ID %02x found for ID 0x%08x.",
|
||||
get_package_id(resid), resid);
|
||||
return false;
|
||||
}
|
||||
|
||||
const PackageGroup& package_group = package_groups_[package_idx];
|
||||
auto cookie_iter = std::find(package_group.cookies_.begin(),
|
||||
package_group.cookies_.end(), cookie);
|
||||
if (cookie_iter == package_group.cookies_.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long package_pos = std::distance(package_group.cookies_.begin(), cookie_iter);
|
||||
const LoadedPackage* package = package_group.packages_[package_pos].loaded_package_;
|
||||
return ToResourceName(entry.type_string_ref,
|
||||
entry.entry_string_ref,
|
||||
package,
|
||||
package->GetPackageName(),
|
||||
out_name);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,12 +48,12 @@ bool ExtractResourceName(const StringPiece& str, StringPiece* out_package, Strin
|
||||
!(has_type_separator && out_type->empty());
|
||||
}
|
||||
|
||||
bool ToResourceName(StringPoolRef& type_string_ref,
|
||||
StringPoolRef& entry_string_ref,
|
||||
const LoadedPackage* package,
|
||||
bool ToResourceName(const StringPoolRef& type_string_ref,
|
||||
const StringPoolRef& entry_string_ref,
|
||||
const StringPiece& package_name,
|
||||
AssetManager2::ResourceName* out_name) {
|
||||
out_name->package = package->GetPackageName().data();
|
||||
out_name->package_len = package->GetPackageName().size();
|
||||
out_name->package = package_name.data();
|
||||
out_name->package_len = package_name.size();
|
||||
|
||||
out_name->type = type_string_ref.string8(&out_name->type_len);
|
||||
out_name->type16 = nullptr;
|
||||
|
||||
@@ -28,12 +28,11 @@ namespace android {
|
||||
bool ExtractResourceName(const StringPiece& str, StringPiece* out_package, StringPiece* out_type,
|
||||
StringPiece* out_entry);
|
||||
|
||||
// Convert a type_string_ref, entry_string_ref, and package
|
||||
// to AssetManager2::ResourceName. Useful for getting
|
||||
// resource name without re-running AssetManager2::FindEntry searches.
|
||||
bool ToResourceName(StringPoolRef& type_string_ref,
|
||||
StringPoolRef& entry_string_ref,
|
||||
const LoadedPackage* package,
|
||||
// Convert a type_string_ref, entry_string_ref, and package to AssetManager2::ResourceName.
|
||||
// Useful for getting resource name without re-running AssetManager2::FindEntry searches.
|
||||
bool ToResourceName(const StringPoolRef& type_string_ref,
|
||||
const StringPoolRef& entry_string_ref,
|
||||
const StringPiece& package_name,
|
||||
AssetManager2::ResourceName* out_name);
|
||||
|
||||
// Formats a ResourceName to "package:type/entry_name".
|
||||
|
||||
@@ -210,6 +210,16 @@ TEST_F(AssetManager2Test, FindsResourceFromAppLoadedAsSharedLibrary) {
|
||||
EXPECT_EQ(fix_package_id(appaslib::R::array::integerArray1, 0x02), value.data);
|
||||
}
|
||||
|
||||
TEST_F(AssetManager2Test, GetSharedLibraryResourceName) {
|
||||
AssetManager2 assetmanager;
|
||||
assetmanager.SetApkAssets({lib_one_assets_.get()});
|
||||
|
||||
AssetManager2::ResourceName name;
|
||||
ASSERT_TRUE(assetmanager.GetResourceName(lib_one::R::string::foo, &name));
|
||||
std::string formatted_name = ToFormattedResourceString(&name);
|
||||
ASSERT_EQ(formatted_name, "com.android.lib_one:string/foo");
|
||||
}
|
||||
|
||||
TEST_F(AssetManager2Test, FindsBagResourceFromSingleApkAssets) {
|
||||
AssetManager2 assetmanager;
|
||||
assetmanager.SetApkAssets({basic_assets_.get()});
|
||||
|
||||
Reference in New Issue
Block a user