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

Commit f2392c6f authored by Ryan Mitchell's avatar Ryan Mitchell Committed by Android (Google) Code Review
Browse files

Merge changes from topic "rro_config"

* changes:
  Make overlay config work with immutable non-android overlays
  Add xml configuration of RROs
  Extract system partitions into standalone class
parents be0c0710 b538e5b0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ cc_binary {
    host_supported: true,
    srcs: [
        "idmap2/Create.cpp",
        "idmap2/CreateMultiple.cpp",
        "idmap2/Dump.cpp",
        "idmap2/Lookup.cpp",
        "idmap2/Main.cpp",
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "idmap2/Result.h"

android::idmap2::Result<android::idmap2::Unit> Create(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> CreateMultiple(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Dump(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Lookup(const std::vector<std::string>& args);
android::idmap2::Result<android::idmap2::Unit> Scan(const std::vector<std::string>& args);
+144 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 <sys/stat.h>   // umask
#include <sys/types.h>  // umask

#include <fstream>
#include <memory>
#include <ostream>
#include <sstream>
#include <string>
#include <vector>

#include "android-base/stringprintf.h"
#include "idmap2/BinaryStreamVisitor.h"
#include "idmap2/CommandLineOptions.h"
#include "idmap2/FileUtils.h"
#include "idmap2/Idmap.h"
#include "idmap2/Policies.h"
#include "idmap2/SysTrace.h"

using android::ApkAssets;
using android::base::StringPrintf;
using android::idmap2::BinaryStreamVisitor;
using android::idmap2::CommandLineOptions;
using android::idmap2::Error;
using android::idmap2::Idmap;
using android::idmap2::PoliciesToBitmask;
using android::idmap2::PolicyBitmask;
using android::idmap2::PolicyFlags;
using android::idmap2::Result;
using android::idmap2::Unit;
using android::idmap2::utils::kIdmapCacheDir;
using android::idmap2::utils::kIdmapFilePermissionMask;
using android::idmap2::utils::UidHasWriteAccessToPath;

Result<Unit> CreateMultiple(const std::vector<std::string>& args) {
  SYSTRACE << "CreateMultiple " << args;
  std::string target_apk_path;
  std::string idmap_dir = kIdmapCacheDir;
  std::vector<std::string> overlay_apk_paths;
  std::vector<std::string> policies;
  bool ignore_overlayable = false;

  const CommandLineOptions opts =
      CommandLineOptions("idmap2 create-multiple")
          .MandatoryOption("--target-apk-path",
                           "input: path to apk which will have its resources overlaid",
                           &target_apk_path)
          .MandatoryOption("--overlay-apk-path",
                           "input: path to apk which contains the new resource values",
                           &overlay_apk_paths)
          .OptionalOption("--idmap-dir",
                          StringPrintf("output: path to the directory in which to write idmap file"
                                       " (defaults to %s)",
                                       kIdmapCacheDir),
                          &idmap_dir)
          .OptionalOption("--policy",
                          "input: an overlayable policy this overlay fulfills"
                          " (if none or supplied, the overlay policy will default to \"public\")",
                          &policies)
          .OptionalFlag("--ignore-overlayable", "disables overlayable and policy checks",
                        &ignore_overlayable);
  const auto opts_ok = opts.Parse(args);
  if (!opts_ok) {
    return opts_ok.GetError();
  }

  PolicyBitmask fulfilled_policies = 0;
  auto conv_result = PoliciesToBitmask(policies);
  if (conv_result) {
    fulfilled_policies |= *conv_result;
  } else {
    return conv_result.GetError();
  }

  if (fulfilled_policies == 0) {
    fulfilled_policies |= PolicyFlags::POLICY_PUBLIC;
  }

  const std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
  if (!target_apk) {
    return Error("failed to load apk %s", target_apk_path.c_str());
  }

  std::vector<std::string> idmap_paths;
  for (const std::string& overlay_apk_path : overlay_apk_paths) {
    const std::string idmap_path = Idmap::CanonicalIdmapPathFor(idmap_dir, overlay_apk_path);
    const uid_t uid = getuid();
    if (!UidHasWriteAccessToPath(uid, idmap_path)) {
      LOG(WARNING) << "uid " << uid << "does not have write access to " << idmap_path.c_str();
      continue;
    }

    const std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
    if (!overlay_apk) {
      LOG(WARNING) << "failed to load apk " << overlay_apk_path.c_str();
      continue;
    }

    const auto idmap =
        Idmap::FromApkAssets(*target_apk, *overlay_apk, fulfilled_policies, !ignore_overlayable);
    if (!idmap) {
      LOG(WARNING) << "failed to create idmap";
      continue;
    }

    umask(kIdmapFilePermissionMask);
    std::ofstream fout(idmap_path);
    if (fout.fail()) {
      LOG(WARNING) << "failed to open idmap path " << idmap_path.c_str();
      continue;
    }

    BinaryStreamVisitor visitor(fout);
    (*idmap)->accept(&visitor);
    fout.close();
    if (fout.fail()) {
      LOG(WARNING) << "failed to write to idmap path %s" << idmap_path.c_str();
      continue;
    }

    idmap_paths.emplace_back(idmap_path);
  }

  for (const std::string& idmap_path : idmap_paths) {
    std::cout << idmap_path << std::endl;
  }

  return Unit{};
}
+3 −1
Original line number Diff line number Diff line
@@ -53,7 +53,9 @@ void PrintUsage(const NameToFunctionMap& commands, std::ostream& out) {
int main(int argc, char** argv) {
  SYSTRACE << "main";
  const NameToFunctionMap commands = {
      {"create", Create}, {"dump", Dump}, {"lookup", Lookup}, {"scan", Scan}, {"verify", Verify},
      {"create", Create}, {"create-multiple", CreateMultiple},
      {"dump", Dump},     {"lookup", Lookup},
      {"scan", Scan},     {"verify", Verify},
  };
  if (argc <= 1) {
    PrintUsage(commands, std::cerr);
+18 −17
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ public final class OverlayInfo implements Parcelable {
            STATE_NO_IDMAP,
            STATE_DISABLED,
            STATE_ENABLED,
            STATE_ENABLED_STATIC,
            STATE_ENABLED_IMMUTABLE,
            // @Deprecated STATE_TARGET_IS_BEING_REPLACED,
            STATE_OVERLAY_IS_BEING_REPLACED,
    })
@@ -117,11 +117,12 @@ public final class OverlayInfo implements Parcelable {

    /**
     * The overlay package is currently enabled because it is marked as
     * 'static'. It cannot be disabled but will change state if for instance
     * 'immutable'. It cannot be disabled but will change state if for instance
     * its target is uninstalled.
     * @hide
     */
    public static final int STATE_ENABLED_STATIC = 6;
    @Deprecated
    public static final int STATE_ENABLED_IMMUTABLE = 6;

    /**
     * Overlay category: theme.
@@ -180,21 +181,21 @@ public final class OverlayInfo implements Parcelable {
    public final int userId;

    /**
     * Priority as read from the manifest. Used if isStatic is true. Not
     * intended to be exposed to 3rd party.
     * Priority as configured by {@link com.android.internal.content.om.OverlayConfig}.
     * Not intended to be exposed to 3rd party.
     *
     * @hide
     */
    public final int priority;

    /**
     * isStatic as read from the manifest. If true, the overlay is
     * unconditionally loaded and cannot be unloaded. Not intended to be
     * isMutable as configured by {@link com.android.internal.content.om.OverlayConfig}.
     * If false, the overlay is unconditionally loaded and cannot be unloaded. Not intended to be
     * exposed to 3rd party.
     *
     * @hide
     */
    public final boolean isStatic;
    public final boolean isMutable;

    /**
     * Create a new OverlayInfo based on source with an updated state.
@@ -207,14 +208,14 @@ public final class OverlayInfo implements Parcelable {
    public OverlayInfo(@NonNull OverlayInfo source, @State int state) {
        this(source.packageName, source.targetPackageName, source.targetOverlayableName,
                source.category, source.baseCodePath, state, source.userId, source.priority,
                source.isStatic);
                source.isMutable);
    }

    /** @hide */
    public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName,
            @Nullable String targetOverlayableName, @Nullable String category,
            @NonNull String baseCodePath, int state, int userId,
            int priority, boolean isStatic) {
            int priority, boolean isMutable) {
        this.packageName = packageName;
        this.targetPackageName = targetPackageName;
        this.targetOverlayableName = targetOverlayableName;
@@ -223,7 +224,7 @@ public final class OverlayInfo implements Parcelable {
        this.state = state;
        this.userId = userId;
        this.priority = priority;
        this.isStatic = isStatic;
        this.isMutable = isMutable;
        ensureValidState();
    }

@@ -237,7 +238,7 @@ public final class OverlayInfo implements Parcelable {
        state = source.readInt();
        userId = source.readInt();
        priority = source.readInt();
        isStatic = source.readBoolean();
        isMutable = source.readBoolean();
        ensureValidState();
    }

@@ -307,7 +308,7 @@ public final class OverlayInfo implements Parcelable {
            case STATE_NO_IDMAP:
            case STATE_DISABLED:
            case STATE_ENABLED:
            case STATE_ENABLED_STATIC:
            case STATE_ENABLED_IMMUTABLE:
            case STATE_TARGET_IS_BEING_REPLACED:
            case STATE_OVERLAY_IS_BEING_REPLACED:
                break;
@@ -331,7 +332,7 @@ public final class OverlayInfo implements Parcelable {
        dest.writeInt(state);
        dest.writeInt(userId);
        dest.writeInt(priority);
        dest.writeBoolean(isStatic);
        dest.writeBoolean(isMutable);
    }

    public static final @android.annotation.NonNull Parcelable.Creator<OverlayInfo> CREATOR =
@@ -360,7 +361,7 @@ public final class OverlayInfo implements Parcelable {
    public boolean isEnabled() {
        switch (state) {
            case STATE_ENABLED:
            case STATE_ENABLED_STATIC:
            case STATE_ENABLED_IMMUTABLE:
                return true;
            default:
                return false;
@@ -386,8 +387,8 @@ public final class OverlayInfo implements Parcelable {
                return "STATE_DISABLED";
            case STATE_ENABLED:
                return "STATE_ENABLED";
            case STATE_ENABLED_STATIC:
                return "STATE_ENABLED_STATIC";
            case STATE_ENABLED_IMMUTABLE:
                return "STATE_ENABLED_IMMUTABLE";
            case STATE_TARGET_IS_BEING_REPLACED:
                return "STATE_TARGET_IS_BEING_REPLACED";
            case STATE_OVERLAY_IS_BEING_REPLACED:
Loading