diff options
author | 2020-02-04 10:18:53 -0800 | |
---|---|---|
committer | 2020-02-18 16:13:22 -0800 | |
commit | 9b93942a801cd042d0486d13f4a25fdf644990e0 (patch) | |
tree | fe57d05bedc029fd9d4291ebd8c2f1c2047dc87a /cmds/idmap2 | |
parent | 76e669069c68e73d6f5404f415cc5fb0cc0e02af (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.bp | 1 | ||||
-rw-r--r-- | cmds/idmap2/idmap2/Commands.h | 1 | ||||
-rw-r--r-- | cmds/idmap2/idmap2/CreateMultiple.cpp | 144 | ||||
-rw-r--r-- | cmds/idmap2/idmap2/Main.cpp | 4 |
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); |