summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ryan Mitchell <rtmitchell@google.com> 2019-01-23 16:56:51 -0800
committer Ryan Mitchell <rtmitchell@google.com> 2019-01-24 15:45:43 -0800
commit741e96ff07326292744ee5bc437ba7171f7c3f56 (patch)
tree9c4514cb534fd315b5327cb34e86e3407a9df435
parent9ce77e9b7f0a1d001428030f3ad738220378ae40 (diff)
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
-rw-r--r--libs/androidfw/AssetManager2.cpp20
-rw-r--r--libs/androidfw/ResourceUtils.cpp10
-rw-r--r--libs/androidfw/include/androidfw/ResourceUtils.h11
-rw-r--r--libs/androidfw/tests/AssetManager2_test.cpp10
4 files changed, 35 insertions, 16 deletions
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 3c35d9b33fc8..20303eba6667 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -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);
}
diff --git a/libs/androidfw/ResourceUtils.cpp b/libs/androidfw/ResourceUtils.cpp
index 645984d85c34..c63dff8f9104 100644
--- a/libs/androidfw/ResourceUtils.cpp
+++ b/libs/androidfw/ResourceUtils.cpp
@@ -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;
diff --git a/libs/androidfw/include/androidfw/ResourceUtils.h b/libs/androidfw/include/androidfw/ResourceUtils.h
index eb6eb8e66175..e649940cdde1 100644
--- a/libs/androidfw/include/androidfw/ResourceUtils.h
+++ b/libs/androidfw/include/androidfw/ResourceUtils.h
@@ -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".
diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp
index 105dcd209bf7..447fdf5d306a 100644
--- a/libs/androidfw/tests/AssetManager2_test.cpp
+++ b/libs/androidfw/tests/AssetManager2_test.cpp
@@ -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()});