Merge changes If7ea17d5,If6364fd6 into rvc-dev
* changes: Assigned package ids to overlays last Revert "Assign shared libraries stable package ids"
This commit is contained in:
committed by
Android (Google) Code Review
commit
8275fb7d66
@@ -214,12 +214,8 @@ static jint CopyValue(JNIEnv* env, ApkAssetsCookie cookie, const Res_value& valu
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static std::unique_ptr<DynamicLibManager> sDynamicLibManager =
|
||||
std::make_unique<DynamicLibManager>();
|
||||
|
||||
// Let the opaque type AAssetManager refer to a guarded AssetManager2 instance.
|
||||
struct GuardedAssetManager : public ::AAssetManager {
|
||||
GuardedAssetManager() : guarded_assetmanager(sDynamicLibManager.get()) {}
|
||||
Guarded<AssetManager2> guarded_assetmanager;
|
||||
};
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ cc_library {
|
||||
"AttributeResolution.cpp",
|
||||
"ChunkIterator.cpp",
|
||||
"ConfigDescription.cpp",
|
||||
"DynamicLibManager.cpp",
|
||||
"Idmap.cpp",
|
||||
"LoadedArsc.cpp",
|
||||
"Locale.cpp",
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include "android-base/logging.h"
|
||||
#include "android-base/stringprintf.h"
|
||||
#include "androidfw/DynamicLibManager.h"
|
||||
#include "androidfw/ResourceUtils.h"
|
||||
#include "androidfw/Util.h"
|
||||
#include "utils/ByteOrder.h"
|
||||
@@ -67,12 +66,7 @@ struct FindEntryResult {
|
||||
StringPoolRef entry_string_ref;
|
||||
};
|
||||
|
||||
AssetManager2::AssetManager2() : dynamic_lib_manager_(std::make_unique<DynamicLibManager>()) {
|
||||
memset(&configuration_, 0, sizeof(configuration_));
|
||||
}
|
||||
|
||||
AssetManager2::AssetManager2(DynamicLibManager* dynamic_lib_manager)
|
||||
: dynamic_lib_manager_(dynamic_lib_manager) {
|
||||
AssetManager2::AssetManager2() {
|
||||
memset(&configuration_, 0, sizeof(configuration_));
|
||||
}
|
||||
|
||||
@@ -91,6 +85,9 @@ void AssetManager2::BuildDynamicRefTable() {
|
||||
package_groups_.clear();
|
||||
package_ids_.fill(0xff);
|
||||
|
||||
// A mapping from apk assets path to the runtime package id of its first loaded package.
|
||||
std::unordered_map<std::string, uint8_t> apk_assets_package_ids;
|
||||
|
||||
// Overlay resources are not directly referenced by an application so their resource ids
|
||||
// can change throughout the application's lifetime. Assign overlay package ids last.
|
||||
std::vector<const ApkAssets*> sorted_apk_assets(apk_assets_);
|
||||
@@ -98,37 +95,25 @@ void AssetManager2::BuildDynamicRefTable() {
|
||||
return !a->IsOverlay();
|
||||
});
|
||||
|
||||
std::unordered_map<std::string, uint8_t> apk_assets_package_ids;
|
||||
std::unordered_map<std::string, uint8_t> package_name_package_ids;
|
||||
|
||||
// Assign stable package ids to application packages.
|
||||
uint8_t next_available_package_id = 0U;
|
||||
for (const auto& apk_assets : sorted_apk_assets) {
|
||||
for (const auto& package : apk_assets->GetLoadedArsc()->GetPackages()) {
|
||||
uint8_t package_id = package->GetPackageId();
|
||||
if (package->IsOverlay()) {
|
||||
package_id = GetDynamicLibManager()->FindUnassignedId(next_available_package_id);
|
||||
next_available_package_id = package_id + 1;
|
||||
} else if (package->IsDynamic()) {
|
||||
package_id = GetDynamicLibManager()->GetAssignedId(package->GetPackageName());
|
||||
}
|
||||
|
||||
// Map the path of the apk assets to the package id of its first loaded package.
|
||||
apk_assets_package_ids[apk_assets->GetPath()] = package_id;
|
||||
|
||||
// Map the package name of the package to the first loaded package with that package id.
|
||||
package_name_package_ids[package->GetPackageName()] = package_id;
|
||||
}
|
||||
// The assets cookie must map to the position of the apk assets in the unsorted apk assets list.
|
||||
std::unordered_map<const ApkAssets*, ApkAssetsCookie> apk_assets_cookies;
|
||||
apk_assets_cookies.reserve(apk_assets_.size());
|
||||
for (size_t i = 0, n = apk_assets_.size(); i < n; i++) {
|
||||
apk_assets_cookies[apk_assets_[i]] = static_cast<ApkAssetsCookie>(i);
|
||||
}
|
||||
|
||||
const int apk_assets_count = apk_assets_.size();
|
||||
for (int i = 0; i < apk_assets_count; i++) {
|
||||
const auto& apk_assets = apk_assets_[i];
|
||||
for (const auto& package : apk_assets->GetLoadedArsc()->GetPackages()) {
|
||||
const auto package_id_entry = package_name_package_ids.find(package->GetPackageName());
|
||||
CHECK(package_id_entry != package_name_package_ids.end())
|
||||
<< "no package id assgined to package " << package->GetPackageName();
|
||||
const uint8_t package_id = package_id_entry->second;
|
||||
// 0x01 is reserved for the android package.
|
||||
int next_package_id = 0x02;
|
||||
for (const ApkAssets* apk_assets : sorted_apk_assets) {
|
||||
const LoadedArsc* loaded_arsc = apk_assets->GetLoadedArsc();
|
||||
for (const std::unique_ptr<const LoadedPackage>& package : loaded_arsc->GetPackages()) {
|
||||
// Get the package ID or assign one if a shared library.
|
||||
int package_id;
|
||||
if (package->IsDynamic()) {
|
||||
package_id = next_package_id++;
|
||||
} else {
|
||||
package_id = package->GetPackageId();
|
||||
}
|
||||
|
||||
// Add the mapping for package ID to index if not present.
|
||||
uint8_t idx = package_ids_[package_id];
|
||||
@@ -162,7 +147,7 @@ void AssetManager2::BuildDynamicRefTable() {
|
||||
target_package_group.overlays_.push_back(
|
||||
ConfiguredOverlay{loaded_idmap->GetTargetResourcesMap(target_package_id,
|
||||
overlay_table.get()),
|
||||
static_cast<ApkAssetsCookie>(i)});
|
||||
apk_assets_cookies[apk_assets]});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +159,7 @@ void AssetManager2::BuildDynamicRefTable() {
|
||||
|
||||
// Add the package and to the set of packages with the same ID.
|
||||
package_group->packages_.push_back(ConfiguredPackage{package.get(), {}});
|
||||
package_group->cookies_.push_back(static_cast<ApkAssetsCookie>(i));
|
||||
package_group->cookies_.push_back(apk_assets_cookies[apk_assets]);
|
||||
|
||||
// Add the package name -> build time ID mappings.
|
||||
for (const DynamicPackageEntry& entry : package->GetDynamicPackageMap()) {
|
||||
@@ -182,6 +167,8 @@ void AssetManager2::BuildDynamicRefTable() {
|
||||
package_group->dynamic_ref_table->mEntries.replaceValueFor(
|
||||
package_name, static_cast<uint8_t>(entry.package_id));
|
||||
}
|
||||
|
||||
apk_assets_package_ids.insert(std::make_pair(apk_assets->GetPath(), package_id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1329,16 +1316,6 @@ uint8_t AssetManager2::GetAssignedPackageId(const LoadedPackage* package) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
DynamicLibManager* AssetManager2::GetDynamicLibManager() const {
|
||||
auto dynamic_lib_manager =
|
||||
std::get_if<std::unique_ptr<DynamicLibManager>>(&dynamic_lib_manager_);
|
||||
if (dynamic_lib_manager) {
|
||||
return (*dynamic_lib_manager).get();
|
||||
} else {
|
||||
return *std::get_if<DynamicLibManager*>(&dynamic_lib_manager_);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Theme> AssetManager2::NewTheme() {
|
||||
return std::unique_ptr<Theme>(new Theme(this));
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "androidfw/DynamicLibManager.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
uint8_t DynamicLibManager::GetAssignedId(const std::string& library_package_name) {
|
||||
auto lib_entry = shared_lib_package_ids_.find(library_package_name);
|
||||
if (lib_entry != shared_lib_package_ids_.end()) {
|
||||
return lib_entry->second;
|
||||
}
|
||||
|
||||
return shared_lib_package_ids_[library_package_name] = next_package_id_++;
|
||||
}
|
||||
|
||||
uint8_t DynamicLibManager::FindUnassignedId(uint8_t start_package_id) {
|
||||
return (start_package_id < next_package_id_) ? next_package_id_ : start_package_id;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "androidfw/ApkAssets.h"
|
||||
#include "androidfw/Asset.h"
|
||||
#include "androidfw/AssetManager.h"
|
||||
#include "androidfw/DynamicLibManager.h"
|
||||
#include "androidfw/ResourceTypes.h"
|
||||
#include "androidfw/Util.h"
|
||||
|
||||
@@ -95,7 +94,6 @@ class AssetManager2 {
|
||||
};
|
||||
|
||||
AssetManager2();
|
||||
explicit AssetManager2(DynamicLibManager* dynamic_lib_manager);
|
||||
|
||||
// Sets/resets the underlying ApkAssets for this AssetManager. The ApkAssets
|
||||
// are not owned by the AssetManager, and must have a longer lifetime.
|
||||
@@ -126,6 +124,9 @@ class AssetManager2 {
|
||||
// This may be nullptr if the APK represented by `cookie` has no resource table.
|
||||
std::shared_ptr<const DynamicRefTable> GetDynamicRefTableForCookie(ApkAssetsCookie cookie) const;
|
||||
|
||||
// Retrieve the assigned package id of the package if loaded into this AssetManager
|
||||
uint8_t GetAssignedPackageId(const LoadedPackage* package) const;
|
||||
|
||||
// Returns a string representation of the overlayable API of a package.
|
||||
bool GetOverlayablesToString(const android::StringPiece& package_name,
|
||||
std::string* out) const;
|
||||
@@ -370,11 +371,6 @@ class AssetManager2 {
|
||||
// been seen while traversing bag parents.
|
||||
const ResolvedBag* GetBag(uint32_t resid, std::vector<uint32_t>& child_resids);
|
||||
|
||||
// Retrieve the assigned package id of the package if loaded into this AssetManager
|
||||
uint8_t GetAssignedPackageId(const LoadedPackage* package) const;
|
||||
|
||||
DynamicLibManager* GetDynamicLibManager() const;
|
||||
|
||||
// The ordered list of ApkAssets to search. These are not owned by the AssetManager, and must
|
||||
// have a longer lifetime.
|
||||
std::vector<const ApkAssets*> apk_assets_;
|
||||
@@ -393,9 +389,6 @@ class AssetManager2 {
|
||||
// may need to be purged.
|
||||
ResTable_config configuration_;
|
||||
|
||||
// Component responsible for assigning package ids to shared libraries.
|
||||
std::variant<std::unique_ptr<DynamicLibManager>, DynamicLibManager*> dynamic_lib_manager_;
|
||||
|
||||
// Cached set of bags. These are cached because they can inherit keys from parent bags,
|
||||
// which involves some calculation.
|
||||
std::unordered_map<uint32_t, util::unique_cptr<ResolvedBag>> cached_bags_;
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROIDFW_DYNAMICLIBMANAGER_H
|
||||
#define ANDROIDFW_DYNAMICLIBMANAGER_H
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "android-base/macros.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
// Manages assigning resource ids for dynamic resources.
|
||||
class DynamicLibManager {
|
||||
public:
|
||||
DynamicLibManager() = default;
|
||||
|
||||
// Retrieves the assigned package id for the library.
|
||||
uint8_t GetAssignedId(const std::string& library_package_name);
|
||||
|
||||
// Queries in ascending order for the first available package id that is not currently assigned to
|
||||
// a library.
|
||||
uint8_t FindUnassignedId(uint8_t start_package_id);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(DynamicLibManager);
|
||||
|
||||
uint8_t next_package_id_ = 0x02;
|
||||
std::unordered_map<std::string, uint8_t> shared_lib_package_ids_;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif //ANDROIDFW_DYNAMICLIBMANAGER_H
|
||||
@@ -47,8 +47,7 @@ class Guarded {
|
||||
static_assert(!std::is_pointer<T>::value, "T must not be a raw pointer");
|
||||
|
||||
public:
|
||||
template <typename ...Args>
|
||||
explicit Guarded(Args&& ...args) : guarded_(std::forward<Args>(args)...) {
|
||||
explicit Guarded() : guarded_() {
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
#include "androidfw/AssetManager2.h"
|
||||
#include "androidfw/AssetManager.h"
|
||||
|
||||
#include "android-base/logging.h"
|
||||
|
||||
#include "TestHelpers.h"
|
||||
#include "android-base/file.h"
|
||||
#include "android-base/logging.h"
|
||||
#include "androidfw/ResourceUtils.h"
|
||||
#include "data/appaslib/R.h"
|
||||
#include "data/basic/R.h"
|
||||
@@ -45,37 +45,43 @@ namespace android {
|
||||
class AssetManager2Test : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
basic_assets_ = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
|
||||
// Move to the test data directory so the idmap can locate the overlay APK.
|
||||
std::string original_path = base::GetExecutableDirectory();
|
||||
chdir(GetTestDataPath().c_str());
|
||||
|
||||
basic_assets_ = ApkAssets::Load("basic/basic.apk");
|
||||
ASSERT_NE(nullptr, basic_assets_);
|
||||
|
||||
basic_de_fr_assets_ = ApkAssets::Load(GetTestDataPath() + "/basic/basic_de_fr.apk");
|
||||
basic_de_fr_assets_ = ApkAssets::Load("basic/basic_de_fr.apk");
|
||||
ASSERT_NE(nullptr, basic_de_fr_assets_);
|
||||
|
||||
style_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
|
||||
style_assets_ = ApkAssets::Load("styles/styles.apk");
|
||||
ASSERT_NE(nullptr, style_assets_);
|
||||
|
||||
lib_one_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_one/lib_one.apk");
|
||||
lib_one_assets_ = ApkAssets::Load("lib_one/lib_one.apk");
|
||||
ASSERT_NE(nullptr, lib_one_assets_);
|
||||
|
||||
lib_two_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_two/lib_two.apk");
|
||||
lib_two_assets_ = ApkAssets::Load("lib_two/lib_two.apk");
|
||||
ASSERT_NE(nullptr, lib_two_assets_);
|
||||
|
||||
libclient_assets_ = ApkAssets::Load(GetTestDataPath() + "/libclient/libclient.apk");
|
||||
libclient_assets_ = ApkAssets::Load("libclient/libclient.apk");
|
||||
ASSERT_NE(nullptr, libclient_assets_);
|
||||
|
||||
appaslib_assets_ = ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk",
|
||||
PROPERTY_DYNAMIC);
|
||||
appaslib_assets_ = ApkAssets::Load("appaslib/appaslib.apk", PROPERTY_DYNAMIC);
|
||||
ASSERT_NE(nullptr, appaslib_assets_);
|
||||
|
||||
system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk",
|
||||
PROPERTY_SYSTEM);
|
||||
system_assets_ = ApkAssets::Load("system/system.apk", PROPERTY_SYSTEM);
|
||||
ASSERT_NE(nullptr, system_assets_);
|
||||
|
||||
app_assets_ = ApkAssets::Load(GetTestDataPath() + "/app/app.apk");
|
||||
app_assets_ = ApkAssets::Load("app/app.apk");
|
||||
ASSERT_THAT(app_assets_, NotNull());
|
||||
|
||||
overlayable_assets_ = ApkAssets::Load(GetTestDataPath() + "/overlayable/overlayable.apk");
|
||||
overlay_assets_ = ApkAssets::LoadOverlay("overlay/overlay.idmap");
|
||||
ASSERT_NE(nullptr, overlay_assets_);
|
||||
|
||||
overlayable_assets_ = ApkAssets::Load("overlayable/overlayable.apk");
|
||||
ASSERT_THAT(overlayable_assets_, NotNull());
|
||||
chdir(original_path.c_str());
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -88,6 +94,7 @@ class AssetManager2Test : public ::testing::Test {
|
||||
std::unique_ptr<const ApkAssets> appaslib_assets_;
|
||||
std::unique_ptr<const ApkAssets> system_assets_;
|
||||
std::unique_ptr<const ApkAssets> app_assets_;
|
||||
std::unique_ptr<const ApkAssets> overlay_assets_;
|
||||
std::unique_ptr<const ApkAssets> overlayable_assets_;
|
||||
};
|
||||
|
||||
@@ -216,23 +223,24 @@ TEST_F(AssetManager2Test, FindsResourceFromAppLoadedAsSharedLibrary) {
|
||||
EXPECT_EQ(fix_package_id(appaslib::R::array::integerArray1, 0x02), value.data);
|
||||
}
|
||||
|
||||
TEST_F(AssetManager2Test, AssignsUnchangingPackageIdToSharedLibrary) {
|
||||
DynamicLibManager lib_manager;
|
||||
AssetManager2 assetmanager(&lib_manager);
|
||||
TEST_F(AssetManager2Test, AssignsOverlayPackageIdLast) {
|
||||
AssetManager2 assetmanager;
|
||||
assetmanager.SetApkAssets(
|
||||
{lib_one_assets_.get(), lib_two_assets_.get(), libclient_assets_.get()});
|
||||
{overlayable_assets_.get(), overlay_assets_.get(), lib_one_assets_.get()});
|
||||
|
||||
AssetManager2 assetmanager2(&lib_manager);
|
||||
assetmanager2.SetApkAssets(
|
||||
{lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()});
|
||||
auto apk_assets = assetmanager.GetApkAssets();
|
||||
ASSERT_EQ(3, apk_assets.size());
|
||||
ASSERT_EQ(overlayable_assets_.get(), apk_assets[0]);
|
||||
ASSERT_EQ(overlay_assets_.get(), apk_assets[1]);
|
||||
ASSERT_EQ(lib_one_assets_.get(), apk_assets[2]);
|
||||
|
||||
uint32_t res_id = assetmanager.GetResourceId("com.android.lib_one:string/foo");
|
||||
ASSERT_NE(0U, res_id);
|
||||
auto get_first_package_id = [&assetmanager](const ApkAssets* apkAssets) -> uint8_t {
|
||||
return assetmanager.GetAssignedPackageId(apkAssets->GetLoadedArsc()->GetPackages()[0].get());
|
||||
};
|
||||
|
||||
uint32_t res_id_2 = assetmanager2.GetResourceId("com.android.lib_one:string/foo");
|
||||
ASSERT_NE(0U, res_id_2);
|
||||
|
||||
ASSERT_EQ(res_id, res_id_2);
|
||||
ASSERT_EQ(get_first_package_id(overlayable_assets_.get()), 0x7f);
|
||||
ASSERT_EQ(get_first_package_id(overlay_assets_.get()), 0x03);
|
||||
ASSERT_EQ(get_first_package_id(lib_one_assets_.get()), 0x02);
|
||||
}
|
||||
|
||||
TEST_F(AssetManager2Test, GetSharedLibraryResourceName) {
|
||||
@@ -770,7 +778,6 @@ TEST_F(AssetManager2Test, GetOverlayablesToString) {
|
||||
ASSERT_EQ(api.find("not_overlayable"), std::string::npos);
|
||||
ASSERT_NE(api.find("resource='com.android.overlayable:string/overlayable2' overlayable='OverlayableResources1' actor='overlay://theme' policy='0x0000000a'\n"),
|
||||
std::string::npos);
|
||||
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
Reference in New Issue
Block a user