Loading cmds/idmap2/include/idmap2/Idmap.h +2 −2 Original line number Diff line number Diff line Loading @@ -178,8 +178,8 @@ class IdmapHeader { }; struct IdmapConstraint { // Constraint type can be TYPE_DISPLAY_ID or TYP_DEVICE_ID, please refer // to ConstraintType in OverlayConstraint.java // Constraint type can be android::kOverlayConstraintTypeDisplayId or // android::kOverlayConstraintTypeDeviceId uint32_t constraint_type; uint32_t constraint_value; Loading core/java/android/app/ContextImpl.java +12 −1 Original line number Diff line number Diff line Loading @@ -2976,6 +2976,13 @@ class ContextImpl extends Context { if (display != null) { updateDeviceIdIfChanged(display.getDisplayId()); } updateResourceOverlayConstraints(); } private void updateResourceOverlayConstraints() { if (mResources != null) { mResources.getAssets().setOverlayConstraints(getDisplayId(), getDeviceId()); } } @Override Loading @@ -2988,9 +2995,11 @@ class ContextImpl extends Context { } } return new ContextImpl(this, mMainThread, mPackageInfo, mParams, final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag(), mAttributionSource.getNext(), mSplitName, mToken, mUser, mFlags, mClassLoader, null, deviceId, true); context.updateResourceOverlayConstraints(); return context; } @NonNull Loading Loading @@ -3285,6 +3294,7 @@ class ContextImpl extends Context { mDeviceId = updatedDeviceId; mAttributionSource = createAttributionSourceWithDeviceId(mAttributionSource, mDeviceId); notifyOnDeviceChangedListeners(updatedDeviceId); updateResourceOverlayConstraints(); } } Loading Loading @@ -3700,6 +3710,7 @@ class ContextImpl extends Context { mResourcesManager.setLocaleConfig(lc); } } updateResourceOverlayConstraints(); } void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { Loading core/java/android/content/res/AssetManager.java +20 −2 Original line number Diff line number Diff line Loading @@ -148,8 +148,8 @@ public final class AssetManager implements AutoCloseable { * @hide */ public static class Builder { private ArrayList<ApkAssets> mUserApkAssets = new ArrayList<>(); private ArrayList<ResourcesLoader> mLoaders = new ArrayList<>(); private final ArrayList<ApkAssets> mUserApkAssets = new ArrayList<>(); private final ArrayList<ResourcesLoader> mLoaders = new ArrayList<>(); private boolean mNoInit = false; Loading Loading @@ -1624,6 +1624,23 @@ public final class AssetManager implements AutoCloseable { } } /** * Passes the display id and device id to AssetManager, to filter out overlays based on * any {@link android.content.om.OverlayConstraint}. * * @hide */ public void setOverlayConstraints(int displayId, int deviceId) { if (!Flags.rroConstraints()) { return; } synchronized (this) { ensureValidLocked(); nativeSetOverlayConstraints(mObject, displayId, deviceId); } } /** * @hide */ Loading Loading @@ -1717,6 +1734,7 @@ public final class AssetManager implements AutoCloseable { int screenWidth, int screenHeight, int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, int screenLayout, int uiMode, int colorMode, int grammaticalGender, int majorVersion, boolean forceRefresh); private static native void nativeSetOverlayConstraints(long ptr, int displayId, int deviceId); private static native @NonNull SparseArray<String> nativeGetAssignedPackageIdentifiers( long ptr, boolean includeOverlays, boolean includeLoaders); Loading core/jni/android_util_AssetManager.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -424,6 +424,15 @@ static void NativeSetConfiguration(JNIEnv* env, jclass /*clazz*/, jlong ptr, jin assetmanager->SetDefaultLocale(default_locale_int); } static void NativeSetOverlayConstraints(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr, jint displayId, jint deviceId) { ATRACE_NAME("AssetManager::SetDisplayIdAndDeviceId"); auto assetmanager = LockAndStartAssetManager(ptr); assetmanager->SetOverlayConstraints(static_cast<int32_t>(displayId), static_cast<int32_t>(deviceId)); } static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/, jlong ptr, jboolean includeOverlays, jboolean includeLoaders) { Loading Loading @@ -1554,6 +1563,7 @@ static const JNINativeMethod gAssetManagerMethods[] = { {"nativeSetApkAssets", "(J[Landroid/content/res/ApkAssets;ZZ)V", (void*)NativeSetApkAssets}, {"nativeSetConfiguration", "(JIILjava/lang/String;[Ljava/lang/String;IIIIIIIIIIIIIIIIZ)V", (void*)NativeSetConfiguration}, {"nativeSetOverlayConstraints", "(JII)V", (void*)NativeSetOverlayConstraints}, {"nativeGetAssignedPackageIdentifiers", "(JZZ)Landroid/util/SparseArray;", (void*)NativeGetAssignedPackageIdentifiers}, Loading libs/androidfw/AssetManager2.cpp +65 −17 Original line number Diff line number Diff line Loading @@ -44,6 +44,9 @@ namespace android { namespace { constexpr int32_t kDefaultDisplayId = 0; constexpr int32_t kDefaultDeviceId = 0; using EntryValue = std::variant<Res_value, incfs::verified_map_ptr<ResTable_map_entry>>; /* NOTE: table_entry has been verified in LoadedPackage::GetEntryFromOffset(), Loading Loading @@ -99,14 +102,15 @@ struct Theme::Entry { Res_value value; }; AssetManager2::AssetManager2(ApkAssetsList apk_assets, const ResTable_config& configuration) { AssetManager2::AssetManager2(ApkAssetsList apk_assets, const ResTable_config& configuration) : display_id_(kDefaultDisplayId), device_id_(kDefaultDeviceId) { configurations_.push_back(configuration); // Don't invalidate caches here as there's nothing cached yet. SetApkAssets(apk_assets, false); } AssetManager2::AssetManager2() { AssetManager2::AssetManager2() : display_id_(kDefaultDisplayId), device_id_(kDefaultDeviceId) { configurations_.emplace_back(); } Loading Loading @@ -172,8 +176,7 @@ void AssetManager2::BuildDynamicRefTable(ApkAssetsList apk_assets) { // to take effect. auto iter = target_assets_package_ids.find(loaded_idmap->TargetApkPath()); if (iter == target_assets_package_ids.end()) { LOG(INFO) << "failed to find target package for overlay " << loaded_idmap->OverlayApkPath(); LOG(INFO) << "failed to find target package for overlay " << loaded_idmap->OverlayApkPath(); } else { uint8_t target_package_id = iter->second; Loading @@ -189,10 +192,11 @@ void AssetManager2::BuildDynamicRefTable(ApkAssetsList apk_assets) { << " assigned package group"; PackageGroup& target_package_group = package_groups_[target_idx]; target_package_group.overlays_.push_back( ConfiguredOverlay{loaded_idmap->GetTargetResourcesMap(target_package_id, overlay_ref_table.get()), apk_assets_cookies[apk_assets]}); target_package_group.overlays_.push_back(ConfiguredOverlay{ loaded_idmap->GetTargetResourcesMap(target_package_id, overlay_ref_table.get()), apk_assets_cookies[apk_assets], IsAnyOverlayConstraintSatisfied(loaded_idmap->GetConstraints()) }); } } Loading Loading @@ -347,7 +351,6 @@ std::shared_ptr<const DynamicRefTable> AssetManager2::GetDynamicRefTableForCooki const std::unordered_map<std::string, std::string>* AssetManager2::GetOverlayableMapForPackage(uint32_t package_id) const { if (package_id >= package_ids_.size()) { return nullptr; } Loading Loading @@ -462,6 +465,28 @@ void AssetManager2::SetConfigurations(std::span<const ResTable_config> configura } } void AssetManager2::SetOverlayConstraints(int32_t display_id, int32_t device_id) { bool changed = false; if (display_id_ != display_id) { display_id_ = display_id; changed = true; } if (device_id_ != device_id) { device_id_ = device_id; changed = true; } if (changed) { // Enable/disable overlays based on current constraints for (PackageGroup& group : package_groups_) { for (auto &overlay: group.overlays_) { overlay.enabled = IsAnyOverlayConstraintSatisfied( overlay.overlay_res_maps_.GetConstraints()); } } InvalidateCaches(static_cast<uint32_t>(-1)); } } std::set<AssetManager2::ApkAssetsPtr> AssetManager2::GetNonSystemOverlays() const { std::set<ApkAssetsPtr> non_system_overlays; for (const PackageGroup& package_group : package_groups_) { Loading @@ -475,6 +500,8 @@ std::set<AssetManager2::ApkAssetsPtr> AssetManager2::GetNonSystemOverlays() cons if (!found_system_package) { auto op = StartOperation(); // Return all overlays, including the disabled ones as this is used for static info // collection only. for (const ConfiguredOverlay& overlay : package_group.overlays_) { if (const auto& asset = GetApkAssets(overlay.cookie)) { non_system_overlays.insert(std::move(asset)); Loading Loading @@ -651,7 +678,6 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( auto op = StartOperation(); // Retrieve the package group from the package id of the resource id. if (UNLIKELY(!is_valid_resid(resid))) { LOG(ERROR) << base::StringPrintf("Invalid resource ID 0x%08x.", resid); Loading Loading @@ -698,7 +724,8 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( } if (!assets->IsLoader()) { for (const auto& id_map : package_group.overlays_) { auto overlay_entry = id_map.overlay_res_maps_.Lookup(resid); auto overlay_entry = id_map.enabled ? id_map.overlay_res_maps_.Lookup(resid) : IdmapResMap::Result(); if (!overlay_entry) { // No id map entry exists for this target resource. continue; Loading Loading @@ -1521,6 +1548,27 @@ void AssetManager2::RebuildFilterList() { } } bool AssetManager2::IsAnyOverlayConstraintSatisfied(const Idmap_constraints& constraints) const { if (constraints.constraint_count == 0) { // There are no constraints, return true. return true; } for (uint32_t i = 0; i < constraints.constraint_count; i++) { auto constraint = constraints.constraint_entries[i]; if (constraint.constraint_type == kOverlayConstraintTypeDisplayId && constraint.constraint_value == display_id_) { return true; } if (constraint.constraint_type == kOverlayConstraintTypeDeviceId && constraint.constraint_value == device_id_) { return true; } } return false; } void AssetManager2::InvalidateCaches(uint32_t diff) { cached_resolved_values_.clear(); Loading Loading
cmds/idmap2/include/idmap2/Idmap.h +2 −2 Original line number Diff line number Diff line Loading @@ -178,8 +178,8 @@ class IdmapHeader { }; struct IdmapConstraint { // Constraint type can be TYPE_DISPLAY_ID or TYP_DEVICE_ID, please refer // to ConstraintType in OverlayConstraint.java // Constraint type can be android::kOverlayConstraintTypeDisplayId or // android::kOverlayConstraintTypeDeviceId uint32_t constraint_type; uint32_t constraint_value; Loading
core/java/android/app/ContextImpl.java +12 −1 Original line number Diff line number Diff line Loading @@ -2976,6 +2976,13 @@ class ContextImpl extends Context { if (display != null) { updateDeviceIdIfChanged(display.getDisplayId()); } updateResourceOverlayConstraints(); } private void updateResourceOverlayConstraints() { if (mResources != null) { mResources.getAssets().setOverlayConstraints(getDisplayId(), getDeviceId()); } } @Override Loading @@ -2988,9 +2995,11 @@ class ContextImpl extends Context { } } return new ContextImpl(this, mMainThread, mPackageInfo, mParams, final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams, mAttributionSource.getAttributionTag(), mAttributionSource.getNext(), mSplitName, mToken, mUser, mFlags, mClassLoader, null, deviceId, true); context.updateResourceOverlayConstraints(); return context; } @NonNull Loading Loading @@ -3285,6 +3294,7 @@ class ContextImpl extends Context { mDeviceId = updatedDeviceId; mAttributionSource = createAttributionSourceWithDeviceId(mAttributionSource, mDeviceId); notifyOnDeviceChangedListeners(updatedDeviceId); updateResourceOverlayConstraints(); } } Loading Loading @@ -3700,6 +3710,7 @@ class ContextImpl extends Context { mResourcesManager.setLocaleConfig(lc); } } updateResourceOverlayConstraints(); } void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { Loading
core/java/android/content/res/AssetManager.java +20 −2 Original line number Diff line number Diff line Loading @@ -148,8 +148,8 @@ public final class AssetManager implements AutoCloseable { * @hide */ public static class Builder { private ArrayList<ApkAssets> mUserApkAssets = new ArrayList<>(); private ArrayList<ResourcesLoader> mLoaders = new ArrayList<>(); private final ArrayList<ApkAssets> mUserApkAssets = new ArrayList<>(); private final ArrayList<ResourcesLoader> mLoaders = new ArrayList<>(); private boolean mNoInit = false; Loading Loading @@ -1624,6 +1624,23 @@ public final class AssetManager implements AutoCloseable { } } /** * Passes the display id and device id to AssetManager, to filter out overlays based on * any {@link android.content.om.OverlayConstraint}. * * @hide */ public void setOverlayConstraints(int displayId, int deviceId) { if (!Flags.rroConstraints()) { return; } synchronized (this) { ensureValidLocked(); nativeSetOverlayConstraints(mObject, displayId, deviceId); } } /** * @hide */ Loading Loading @@ -1717,6 +1734,7 @@ public final class AssetManager implements AutoCloseable { int screenWidth, int screenHeight, int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, int screenLayout, int uiMode, int colorMode, int grammaticalGender, int majorVersion, boolean forceRefresh); private static native void nativeSetOverlayConstraints(long ptr, int displayId, int deviceId); private static native @NonNull SparseArray<String> nativeGetAssignedPackageIdentifiers( long ptr, boolean includeOverlays, boolean includeLoaders); Loading
core/jni/android_util_AssetManager.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -424,6 +424,15 @@ static void NativeSetConfiguration(JNIEnv* env, jclass /*clazz*/, jlong ptr, jin assetmanager->SetDefaultLocale(default_locale_int); } static void NativeSetOverlayConstraints(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr, jint displayId, jint deviceId) { ATRACE_NAME("AssetManager::SetDisplayIdAndDeviceId"); auto assetmanager = LockAndStartAssetManager(ptr); assetmanager->SetOverlayConstraints(static_cast<int32_t>(displayId), static_cast<int32_t>(deviceId)); } static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/, jlong ptr, jboolean includeOverlays, jboolean includeLoaders) { Loading Loading @@ -1554,6 +1563,7 @@ static const JNINativeMethod gAssetManagerMethods[] = { {"nativeSetApkAssets", "(J[Landroid/content/res/ApkAssets;ZZ)V", (void*)NativeSetApkAssets}, {"nativeSetConfiguration", "(JIILjava/lang/String;[Ljava/lang/String;IIIIIIIIIIIIIIIIZ)V", (void*)NativeSetConfiguration}, {"nativeSetOverlayConstraints", "(JII)V", (void*)NativeSetOverlayConstraints}, {"nativeGetAssignedPackageIdentifiers", "(JZZ)Landroid/util/SparseArray;", (void*)NativeGetAssignedPackageIdentifiers}, Loading
libs/androidfw/AssetManager2.cpp +65 −17 Original line number Diff line number Diff line Loading @@ -44,6 +44,9 @@ namespace android { namespace { constexpr int32_t kDefaultDisplayId = 0; constexpr int32_t kDefaultDeviceId = 0; using EntryValue = std::variant<Res_value, incfs::verified_map_ptr<ResTable_map_entry>>; /* NOTE: table_entry has been verified in LoadedPackage::GetEntryFromOffset(), Loading Loading @@ -99,14 +102,15 @@ struct Theme::Entry { Res_value value; }; AssetManager2::AssetManager2(ApkAssetsList apk_assets, const ResTable_config& configuration) { AssetManager2::AssetManager2(ApkAssetsList apk_assets, const ResTable_config& configuration) : display_id_(kDefaultDisplayId), device_id_(kDefaultDeviceId) { configurations_.push_back(configuration); // Don't invalidate caches here as there's nothing cached yet. SetApkAssets(apk_assets, false); } AssetManager2::AssetManager2() { AssetManager2::AssetManager2() : display_id_(kDefaultDisplayId), device_id_(kDefaultDeviceId) { configurations_.emplace_back(); } Loading Loading @@ -172,8 +176,7 @@ void AssetManager2::BuildDynamicRefTable(ApkAssetsList apk_assets) { // to take effect. auto iter = target_assets_package_ids.find(loaded_idmap->TargetApkPath()); if (iter == target_assets_package_ids.end()) { LOG(INFO) << "failed to find target package for overlay " << loaded_idmap->OverlayApkPath(); LOG(INFO) << "failed to find target package for overlay " << loaded_idmap->OverlayApkPath(); } else { uint8_t target_package_id = iter->second; Loading @@ -189,10 +192,11 @@ void AssetManager2::BuildDynamicRefTable(ApkAssetsList apk_assets) { << " assigned package group"; PackageGroup& target_package_group = package_groups_[target_idx]; target_package_group.overlays_.push_back( ConfiguredOverlay{loaded_idmap->GetTargetResourcesMap(target_package_id, overlay_ref_table.get()), apk_assets_cookies[apk_assets]}); target_package_group.overlays_.push_back(ConfiguredOverlay{ loaded_idmap->GetTargetResourcesMap(target_package_id, overlay_ref_table.get()), apk_assets_cookies[apk_assets], IsAnyOverlayConstraintSatisfied(loaded_idmap->GetConstraints()) }); } } Loading Loading @@ -347,7 +351,6 @@ std::shared_ptr<const DynamicRefTable> AssetManager2::GetDynamicRefTableForCooki const std::unordered_map<std::string, std::string>* AssetManager2::GetOverlayableMapForPackage(uint32_t package_id) const { if (package_id >= package_ids_.size()) { return nullptr; } Loading Loading @@ -462,6 +465,28 @@ void AssetManager2::SetConfigurations(std::span<const ResTable_config> configura } } void AssetManager2::SetOverlayConstraints(int32_t display_id, int32_t device_id) { bool changed = false; if (display_id_ != display_id) { display_id_ = display_id; changed = true; } if (device_id_ != device_id) { device_id_ = device_id; changed = true; } if (changed) { // Enable/disable overlays based on current constraints for (PackageGroup& group : package_groups_) { for (auto &overlay: group.overlays_) { overlay.enabled = IsAnyOverlayConstraintSatisfied( overlay.overlay_res_maps_.GetConstraints()); } } InvalidateCaches(static_cast<uint32_t>(-1)); } } std::set<AssetManager2::ApkAssetsPtr> AssetManager2::GetNonSystemOverlays() const { std::set<ApkAssetsPtr> non_system_overlays; for (const PackageGroup& package_group : package_groups_) { Loading @@ -475,6 +500,8 @@ std::set<AssetManager2::ApkAssetsPtr> AssetManager2::GetNonSystemOverlays() cons if (!found_system_package) { auto op = StartOperation(); // Return all overlays, including the disabled ones as this is used for static info // collection only. for (const ConfiguredOverlay& overlay : package_group.overlays_) { if (const auto& asset = GetApkAssets(overlay.cookie)) { non_system_overlays.insert(std::move(asset)); Loading Loading @@ -651,7 +678,6 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( auto op = StartOperation(); // Retrieve the package group from the package id of the resource id. if (UNLIKELY(!is_valid_resid(resid))) { LOG(ERROR) << base::StringPrintf("Invalid resource ID 0x%08x.", resid); Loading Loading @@ -698,7 +724,8 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( } if (!assets->IsLoader()) { for (const auto& id_map : package_group.overlays_) { auto overlay_entry = id_map.overlay_res_maps_.Lookup(resid); auto overlay_entry = id_map.enabled ? id_map.overlay_res_maps_.Lookup(resid) : IdmapResMap::Result(); if (!overlay_entry) { // No id map entry exists for this target resource. continue; Loading Loading @@ -1521,6 +1548,27 @@ void AssetManager2::RebuildFilterList() { } } bool AssetManager2::IsAnyOverlayConstraintSatisfied(const Idmap_constraints& constraints) const { if (constraints.constraint_count == 0) { // There are no constraints, return true. return true; } for (uint32_t i = 0; i < constraints.constraint_count; i++) { auto constraint = constraints.constraint_entries[i]; if (constraint.constraint_type == kOverlayConstraintTypeDisplayId && constraint.constraint_value == display_id_) { return true; } if (constraint.constraint_type == kOverlayConstraintTypeDeviceId && constraint.constraint_value == device_id_) { return true; } } return false; } void AssetManager2::InvalidateCaches(uint32_t diff) { cached_resolved_values_.clear(); Loading