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

Commit af54b363 authored by Kevin Jeon's avatar Kevin Jeon
Browse files

Merge idmap verify/create calls during boot

StartOverlayManagerService currently makes many binder round trips (at
least 1 per package) when verifying resource idmaps and creating them if
necessary. This change adds an idmap AIDL API for verifying+creating
idmaps for mulitple packages so that this work can be done in a single
binder transaction.

In general, the information needed to verify/create an idmap is
accumulated in lists (in the same order as before) before being sent
over in one batch. This saves ~25ms in StartOverlayManagerService.
(173.8ms -> 146ms, avg. over 5 runs).

Test: - atest OverlayManagerImplTest
      - atest OverlayManagerTest
      - atest OverlayManagerServiceImplTests
Bug: 422474410
Flag: android.content.res.merge_idmap_binder_transactions
Change-Id: Ifb0ee1615af1f16c3f75e14d2a650c6e98e01e66
parent 89cf6d42
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -373,6 +373,7 @@ filegroup {
        "idmap2d/aidl/core/android/os/FabricatedOverlayInternal.aidl",
        "idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl",
        "idmap2d/aidl/core/android/os/FabricatedOverlayInfo.aidl",
        "idmap2d/aidl/core/android/os/IdmapParams.aidl",
        "idmap2d/aidl/core/android/os/OverlayConstraint.aidl",
    ],
    path: "idmap2d/aidl/core/",
+39 −0
Original line number Diff line number Diff line
@@ -248,6 +248,45 @@ Status Idmap2Service::createIdmap(const std::string& target_path, const std::str
  return ok();
}

Status Idmap2Service::verifyOrCreateIdmap(const os::IdmapParams& params,
                                          std::optional<std::string>* _aidl_return) {
  bool verified = false;
  verifyIdmap(params.targetPath, params.overlayPath, params.overlayName,
              params.fulfilledPolicies, params.enforceOverlayable, params.userId,
              params.constraints, &verified);
  if (verified) {
      *_aidl_return = "";
      return ok();
  }

  return createIdmap(params.targetPath, params.overlayPath, params.overlayName,
                     params.fulfilledPolicies, params.enforceOverlayable, params.userId,
                     params.constraints, _aidl_return);
}

Status Idmap2Service::verifyOrCreateIdmaps(const std::vector<os::IdmapParams>& params,
                                           std::vector<std::string>* _aidl_return) {
  assert(_aidl_return);
  SYSTRACE << "Idmap2Service::verifyOrCreateIdmaps";

  std::vector<std::string> idmap_paths;
  for (const auto& param : params) {
      std::optional<std::string> idmap_path;
      verifyOrCreateIdmap(param, &idmap_path);

      /*
       * There are three possible idmap_path values:
       * - empty ("") -> existing idmap was verified
       * - non-empty  -> idmap was created
       * - nullptr    -> idmap could not be created
       * We need to append a value for the third case so the caller has a result for each input.
       */
      idmap_paths.emplace_back(std::move(idmap_path).value_or("INVALID"));
  }
  *_aidl_return = idmap_paths;
  return ok();
}

idmap2::Result<Idmap2Service::TargetResourceContainerPtr> Idmap2Service::GetTargetContainer(
    const std::string& target_path) {
  const bool is_framework = target_path == kFrameworkPath;
+7 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <android-base/unique_fd.h>
#include <android/os/BnIdmap2.h>
#include <android/os/FabricatedOverlayInfo.h>
#include <android/os/IdmapParams.h>
#include <android/os/OverlayConstraint.h>
#include <binder/BinderService.h>
#include <idmap2/ResourceContainer.h>
@@ -59,6 +60,9 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 {
                             const std::vector<os::OverlayConstraint>& constraints,
                             std::optional<std::string>* _aidl_return) override;

  binder::Status verifyOrCreateIdmaps(const std::vector<os::IdmapParams>& params,
                                      std::vector<std::string>* _aidl_return) override;

  binder::Status createFabricatedOverlay(
      const os::FabricatedOverlayInternal& overlay,
      std::optional<os::FabricatedOverlayInfo>* _aidl_return) override;
@@ -100,6 +104,9 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 {
  template <typename T>
  using OwningPtr = std::variant<std::unique_ptr<T>, std::shared_ptr<T>>;

  binder::Status verifyOrCreateIdmap(const os::IdmapParams& params,
                                     std::optional<std::string>* _aidl_return);

  using TargetResourceContainerPtr = OwningPtr<idmap2::TargetResourceContainer>;
  idmap2::Result<TargetResourceContainerPtr> GetTargetContainer(const std::string& target_path);

+32 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.
 */

package android.os;

import android.os.OverlayConstraint;

/**
 * @hide
 */
parcelable IdmapParams {
    @utf8InCpp String targetPath;
    @utf8InCpp String overlayPath;
    @utf8InCpp String overlayName;
    int fulfilledPolicies;
    boolean enforceOverlayable;
    int userId;
    OverlayConstraint[] constraints;
}
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.os;

import android.os.FabricatedOverlayInfo;
import android.os.FabricatedOverlayInternal;
import android.os.IdmapParams;
import android.os.OverlayConstraint;

/**
@@ -40,6 +41,7 @@ interface IIdmap2 {
                                          boolean enforceOverlayable,
                                          int userId,
                                          in OverlayConstraint[] constraints);
  @utf8InCpp String[] verifyOrCreateIdmaps(in IdmapParams[] params);

  @nullable FabricatedOverlayInfo createFabricatedOverlay(in FabricatedOverlayInternal overlay);
  boolean deleteFabricatedOverlay(@utf8InCpp String path);
Loading