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

Commit b1608a95 authored by Biswarup Pal's avatar Biswarup Pal
Browse files

Add constraints for enabling RROs

This change introduces hidden API's for setting constraints
for enabling RROs. Currently, the constraints are of the following
types:
1. Display id constraint: This can be set for a RRO if the RRO is
desired to be applied on only the apps running on that specific
display.
2. Device id constraint: This can be set for a RRO if the RRO is
desired to be applied on only the apps running on that specific
device (for apps running on the default device, this would be
Context#DEVICE_ID_DEFAULT, and for apps running on a virtual device,
this would be the id of the virtual device).

An overlay would be enabled when any of the given constraints are met.
Constraints can only be set while enabling a RRO. Re-enabling a RRO
with different constraints updates the constraints for the RRO.

This change facilitates the writing of the constraints for RROs
into the correspodning idmap files, and also persists them as part
of the settings used by OverlayManagerService. The filtering of
resource overlays based on constraints during resource resolution
will be done in a follow-up CL.

Test: atest FrameworksServicesTests
Test: atest idmap2_tests
Test: atest libandroidfw_tests
Test: atest CtsResourcesTestCases
Bug: 371801644
Flag: android.content.res.rro_constraints
Change-Id: I0cad58bfb5b9b90105e2ef839c58147b9a50767c
parent 3dcc4555
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -348,6 +348,7 @@ filegroup {
        "idmap2d/aidl/core/android/os/FabricatedOverlayInternal.aidl",
        "idmap2d/aidl/core/android/os/FabricatedOverlayInternal.aidl",
        "idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl",
        "idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl",
        "idmap2d/aidl/core/android/os/FabricatedOverlayInfo.aidl",
        "idmap2d/aidl/core/android/os/FabricatedOverlayInfo.aidl",
        "idmap2d/aidl/core/android/os/OverlayConstraint.aidl",
    ],
    ],
    path: "idmap2d/aidl/core/",
    path: "idmap2d/aidl/core/",
}
}
+4 −1
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@ using android::idmap2::BinaryStreamVisitor;
using android::idmap2::CommandLineOptions;
using android::idmap2::CommandLineOptions;
using android::idmap2::Error;
using android::idmap2::Error;
using android::idmap2::Idmap;
using android::idmap2::Idmap;
using android::idmap2::IdmapConstraints;
using android::idmap2::OverlayResourceContainer;
using android::idmap2::OverlayResourceContainer;
using android::idmap2::Result;
using android::idmap2::Result;
using android::idmap2::TargetResourceContainer;
using android::idmap2::TargetResourceContainer;
@@ -104,8 +105,10 @@ Result<Unit> Create(const std::vector<std::string>& args) {
    return Error("failed to load apk overlay '%s'", overlay_apk_path.c_str());
    return Error("failed to load apk overlay '%s'", overlay_apk_path.c_str());
  }
  }


  // TODO(b/371801644): Add command-line support for RRO constraints.
  auto constraints = std::make_unique<const IdmapConstraints>();
  const auto idmap = Idmap::FromContainers(**target, **overlay, overlay_name, fulfilled_policies,
  const auto idmap = Idmap::FromContainers(**target, **overlay, overlay_name, fulfilled_policies,
                                           !ignore_overlayable);
                                           !ignore_overlayable, std::move(constraints));
  if (!idmap) {
  if (!idmap) {
    return Error(idmap.GetError(), "failed to create idmap");
    return Error(idmap.GetError(), "failed to create idmap");
  }
  }
+5 −1
Original line number Original line Diff line number Diff line
@@ -39,6 +39,7 @@ using android::idmap2::BinaryStreamVisitor;
using android::idmap2::CommandLineOptions;
using android::idmap2::CommandLineOptions;
using android::idmap2::Error;
using android::idmap2::Error;
using android::idmap2::Idmap;
using android::idmap2::Idmap;
using android::idmap2::IdmapConstraints;
using android::idmap2::OverlayResourceContainer;
using android::idmap2::OverlayResourceContainer;
using android::idmap2::Result;
using android::idmap2::Result;
using android::idmap2::TargetResourceContainer;
using android::idmap2::TargetResourceContainer;
@@ -115,8 +116,11 @@ Result<Unit> CreateMultiple(const std::vector<std::string>& args) {
        continue;
        continue;
      }
      }


      // TODO(b/371801644): Add command-line support for RRO constraints.
      auto constraints = std::make_unique<const IdmapConstraints>();
      const auto idmap =
      const auto idmap =
          Idmap::FromContainers(**target, **overlay, "", fulfilled_policies, !ignore_overlayable);
          Idmap::FromContainers(**target, **overlay, "", fulfilled_policies, !ignore_overlayable,
                                std::move(constraints));
      if (!idmap) {
      if (!idmap) {
        LOG(WARNING) << "failed to create idmap";
        LOG(WARNING) << "failed to create idmap";
        continue;
        continue;
+31 −2
Original line number Original line Diff line number Diff line
@@ -46,6 +46,8 @@ using android::binder::Status;
using android::idmap2::BinaryStreamVisitor;
using android::idmap2::BinaryStreamVisitor;
using android::idmap2::FabricatedOverlayContainer;
using android::idmap2::FabricatedOverlayContainer;
using android::idmap2::Idmap;
using android::idmap2::Idmap;
using android::idmap2::IdmapConstraint;
using android::idmap2::IdmapConstraints;
using android::idmap2::IdmapHeader;
using android::idmap2::IdmapHeader;
using android::idmap2::OverlayResourceContainer;
using android::idmap2::OverlayResourceContainer;
using android::idmap2::PrettyPrintVisitor;
using android::idmap2::PrettyPrintVisitor;
@@ -74,6 +76,18 @@ PolicyBitmask ConvertAidlArgToPolicyBitmask(int32_t arg) {
  return static_cast<PolicyBitmask>(arg);
  return static_cast<PolicyBitmask>(arg);
}
}


std::unique_ptr<const IdmapConstraints> ConvertAidlConstraintsToIdmapConstraints(
        const std::vector<android::os::OverlayConstraint>& constraints) {
  auto idmapConstraints = std::make_unique<IdmapConstraints>();
  for (const auto& constraint : constraints) {
    IdmapConstraint idmapConstraint{};
    idmapConstraint.constraint_type = constraint.type;
    idmapConstraint.constraint_value = constraint.value;
    idmapConstraints->constraints.insert(idmapConstraint);
  }
  return idmapConstraints;
}

}  // namespace
}  // namespace


namespace android::os {
namespace android::os {
@@ -113,6 +127,7 @@ Status Idmap2Service::removeIdmap(const std::string& overlay_path, int32_t user_
Status Idmap2Service::verifyIdmap(const std::string& target_path, const std::string& overlay_path,
Status Idmap2Service::verifyIdmap(const std::string& target_path, const std::string& overlay_path,
                                  const std::string& overlay_name, int32_t fulfilled_policies,
                                  const std::string& overlay_name, int32_t fulfilled_policies,
                                  bool enforce_overlayable, int32_t user_id ATTRIBUTE_UNUSED,
                                  bool enforce_overlayable, int32_t user_id ATTRIBUTE_UNUSED,
                                  const std::vector<os::OverlayConstraint>& constraints,
                                  bool* _aidl_return) {
                                  bool* _aidl_return) {
  SYSTRACE << "Idmap2Service::verifyIdmap " << overlay_path;
  SYSTRACE << "Idmap2Service::verifyIdmap " << overlay_path;
  assert(_aidl_return);
  assert(_aidl_return);
@@ -120,12 +135,19 @@ Status Idmap2Service::verifyIdmap(const std::string& target_path, const std::str
  const std::string idmap_path = Idmap::CanonicalIdmapPathFor(kIdmapCacheDir, overlay_path);
  const std::string idmap_path = Idmap::CanonicalIdmapPathFor(kIdmapCacheDir, overlay_path);
  std::ifstream fin(idmap_path);
  std::ifstream fin(idmap_path);
  const std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(fin);
  const std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(fin);
  const std::unique_ptr<const IdmapConstraints> oldConstraints =
          IdmapConstraints::FromBinaryStream(fin);
  fin.close();
  fin.close();
  if (!header) {
  if (!header) {
    *_aidl_return = false;
    *_aidl_return = false;
    LOG(WARNING) << "failed to parse idmap header of '" << idmap_path << "'";
    LOG(WARNING) << "failed to parse idmap header of '" << idmap_path << "'";
    return ok();
    return ok();
  }
  }
  if (!oldConstraints) {
    *_aidl_return = false;
    LOG(WARNING) << "failed to parse idmap constraints of '" << idmap_path << "'";
    return ok();
  }


  const auto target = GetTargetContainer(target_path);
  const auto target = GetTargetContainer(target_path);
  if (!target) {
  if (!target) {
@@ -145,7 +167,10 @@ Status Idmap2Service::verifyIdmap(const std::string& target_path, const std::str
      header->IsUpToDate(*GetPointer(*target), **overlay, overlay_name,
      header->IsUpToDate(*GetPointer(*target), **overlay, overlay_name,
                         ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable);
                         ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable);


  *_aidl_return = static_cast<bool>(up_to_date);
  std::unique_ptr<const IdmapConstraints> newConstraints =
          ConvertAidlConstraintsToIdmapConstraints(constraints);

  *_aidl_return = static_cast<bool>(up_to_date && (*oldConstraints == *newConstraints));
  if (!up_to_date) {
  if (!up_to_date) {
    LOG(WARNING) << "idmap '" << idmap_path
    LOG(WARNING) << "idmap '" << idmap_path
                 << "' not up to date : " << up_to_date.GetErrorMessage();
                 << "' not up to date : " << up_to_date.GetErrorMessage();
@@ -156,6 +181,7 @@ Status Idmap2Service::verifyIdmap(const std::string& target_path, const std::str
Status Idmap2Service::createIdmap(const std::string& target_path, const std::string& overlay_path,
Status Idmap2Service::createIdmap(const std::string& target_path, const std::string& overlay_path,
                                  const std::string& overlay_name, int32_t fulfilled_policies,
                                  const std::string& overlay_name, int32_t fulfilled_policies,
                                  bool enforce_overlayable, int32_t user_id ATTRIBUTE_UNUSED,
                                  bool enforce_overlayable, int32_t user_id ATTRIBUTE_UNUSED,
                                  const std::vector<os::OverlayConstraint>& constraints,
                                  std::optional<std::string>* _aidl_return) {
                                  std::optional<std::string>* _aidl_return) {
  assert(_aidl_return);
  assert(_aidl_return);
  SYSTRACE << "Idmap2Service::createIdmap " << target_path << " " << overlay_path;
  SYSTRACE << "Idmap2Service::createIdmap " << target_path << " " << overlay_path;
@@ -186,8 +212,11 @@ Status Idmap2Service::createIdmap(const std::string& target_path, const std::str
    return error("failed to load apk overlay '%s'" + overlay_path);
    return error("failed to load apk overlay '%s'" + overlay_path);
  }
  }


  std::unique_ptr<const IdmapConstraints> idmapConstraints =
          ConvertAidlConstraintsToIdmapConstraints(constraints);
  const auto idmap = Idmap::FromContainers(*GetPointer(*target), **overlay, overlay_name,
  const auto idmap = Idmap::FromContainers(*GetPointer(*target), **overlay, overlay_name,
                                           policy_bitmask, enforce_overlayable);
                                           policy_bitmask, enforce_overlayable,
                                           std::move(idmapConstraints));
  if (!idmap) {
  if (!idmap) {
    return error(idmap.GetErrorMessage());
    return error(idmap.GetErrorMessage());
  }
  }
+3 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <android-base/unique_fd.h>
#include <android-base/unique_fd.h>
#include <android/os/BnIdmap2.h>
#include <android/os/BnIdmap2.h>
#include <android/os/FabricatedOverlayInfo.h>
#include <android/os/FabricatedOverlayInfo.h>
#include <android/os/OverlayConstraint.h>
#include <binder/BinderService.h>
#include <binder/BinderService.h>
#include <idmap2/ResourceContainer.h>
#include <idmap2/ResourceContainer.h>
#include <idmap2/Result.h>
#include <idmap2/Result.h>
@@ -49,11 +50,13 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 {
  binder::Status verifyIdmap(const std::string& target_path, const std::string& overlay_path,
  binder::Status verifyIdmap(const std::string& target_path, const std::string& overlay_path,
                             const std::string& overlay_name, int32_t fulfilled_policies,
                             const std::string& overlay_name, int32_t fulfilled_policies,
                             bool enforce_overlayable, int32_t user_id,
                             bool enforce_overlayable, int32_t user_id,
                             const std::vector<os::OverlayConstraint>& constraints,
                             bool* _aidl_return) override;
                             bool* _aidl_return) override;


  binder::Status createIdmap(const std::string& target_path, const std::string& overlay_path,
  binder::Status createIdmap(const std::string& target_path, const std::string& overlay_path,
                             const std::string& overlay_name, int32_t fulfilled_policies,
                             const std::string& overlay_name, int32_t fulfilled_policies,
                             bool enforce_overlayable, int32_t user_id,
                             bool enforce_overlayable, int32_t user_id,
                             const std::vector<os::OverlayConstraint>& constraints,
                             std::optional<std::string>* _aidl_return) override;
                             std::optional<std::string>* _aidl_return) override;


  binder::Status createFabricatedOverlay(
  binder::Status createFabricatedOverlay(
Loading