summaryrefslogtreecommitdiff
path: root/cmds/idmap2
diff options
context:
space:
mode:
author Ryan Mitchell <rtmitchell@google.com> 2020-02-04 10:18:53 -0800
committer Ryan Mitchell <rtmitchell@google.com> 2020-02-18 16:13:22 -0800
commit9b93942a801cd042d0486d13f4a25fdf644990e0 (patch)
treefe57d05bedc029fd9d4291ebd8c2f1c2047dc87a /cmds/idmap2
parent76e669069c68e73d6f5404f415cc5fb0cc0e02af (diff)
Add xml configuration of RROs
This change adds the ability to configure the priority, default enable state, and mutability (previously know as staticness) of an overlay. Rather than overlays configuring themselves, the system can configure overlays relative to each other. An example configuration file looks like: <config> <merge path="auto-generated.xml" /> <overlay package="com.example.one" mutable="false" enabled="true"/> <overlay package="com.example.two" mutable="false" enabled="true"/> <overlay package="com.example.three" enabled="true"/> </config> The <overlay> tag configures the overlay while the <merge> tag allows additional configuration files to be included at a position within the configuration file. If the configuration file is not present for a partition, the legacy android:isStatic and android:priority will continue to configure the overlays in the partition. Once at least one configuration file has been defined in any partition, strict partition precedence will be enforced and overlays on separate partitions will no longer be able to use android:priority to reorder themselves conversely from the overlay partition precedence. The order of the system partitions from least to greatest precedence is system, vendor, odm, oem, product, system_ext. Bug: 135048762 Test: atest OverlayConfigTest Change-Id: If57e8caa9b881f9d424ef48bba80b18cc8b7b943
Diffstat (limited to 'cmds/idmap2')
-rw-r--r--cmds/idmap2/Android.bp1
-rw-r--r--cmds/idmap2/idmap2/Commands.h1
-rw-r--r--cmds/idmap2/idmap2/CreateMultiple.cpp144
-rw-r--r--cmds/idmap2/idmap2/Main.cpp4
4 files changed, 149 insertions, 1 deletions
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 41a17064c3ba..66f5c3908e4b 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -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",
diff --git a/cmds/idmap2/idmap2/Commands.h b/cmds/idmap2/idmap2/Commands.h
index 718e361b38ab..e626738a2895 100644
--- a/cmds/idmap2/idmap2/Commands.h
+++ b/cmds/idmap2/idmap2/Commands.h
@@ -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);
diff --git a/cmds/idmap2/idmap2/CreateMultiple.cpp b/cmds/idmap2/idmap2/CreateMultiple.cpp
new file mode 100644
index 000000000000..0b0541fb6221
--- /dev/null
+++ b/cmds/idmap2/idmap2/CreateMultiple.cpp
@@ -0,0 +1,144 @@
+/*
+ * 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{};
+}
diff --git a/cmds/idmap2/idmap2/Main.cpp b/cmds/idmap2/idmap2/Main.cpp
index 87949085cf1d..a07e793d9f47 100644
--- a/cmds/idmap2/idmap2/Main.cpp
+++ b/cmds/idmap2/idmap2/Main.cpp
@@ -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);