Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7290ef5f authored by Biswarup Pal's avatar Biswarup Pal Committed by Android (Google) Code Review
Browse files

Merge "Filter overlays based on constraints during resource resolution" into main

parents 3a032ce3 bc306b4c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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;

+12 −1
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -3285,6 +3294,7 @@ class ContextImpl extends Context {
            mDeviceId = updatedDeviceId;
            mAttributionSource = createAttributionSourceWithDeviceId(mAttributionSource, mDeviceId);
            notifyOnDeviceChangedListeners(updatedDeviceId);
            updateResourceOverlayConstraints();
        }
    }

@@ -3700,6 +3710,7 @@ class ContextImpl extends Context {
                mResourcesManager.setLocaleConfig(lc);
            }
        }
        updateResourceOverlayConstraints();
    }

    void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
+20 −2
Original line number Diff line number Diff line
@@ -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;

@@ -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
     */
@@ -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);

+10 −0
Original line number Diff line number Diff line
@@ -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) {
@@ -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},

+65 −17
Original line number Diff line number Diff line
@@ -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(),
@@ -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();
}

@@ -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;

@@ -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())
        });
      }
    }

@@ -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;
  }
@@ -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_) {
@@ -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));
@@ -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);
@@ -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;
@@ -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