diff options
| author | 2023-02-23 17:43:25 +0000 | |
|---|---|---|
| committer | 2023-03-15 16:29:55 +0000 | |
| commit | 7109b70e032d4ef36acac6d5cda0e823ebee9ab5 (patch) | |
| tree | 0655f963cb3d1367d42deac5c36e1b8513152294 | |
| parent | c1dfe6f64ff073913a14491873ab7aa76c25def6 (diff) | |
Add support for adding fingerprint prefix install constraints
Since more install constraints could be added in the future, add a new
option for inserting just fingerprint prefixes.
Bug: 270562509
Test: atest aapt2_tests
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a10b808220650f96ee2ce360e387ee9e2e1ddd69)
Merged-In: If357c6df09491fa1bec5fe1a00a682d634af69b7
Change-Id: Ic07239134a9445c2ec7e5e1cd2313ac1859111aa
| -rw-r--r-- | tools/aapt2/cmd/Link.h | 2 | ||||
| -rw-r--r-- | tools/aapt2/dump/DumpManifest.cpp | 31 | ||||
| -rw-r--r-- | tools/aapt2/link/ManifestFixer.cpp | 17 | ||||
| -rw-r--r-- | tools/aapt2/link/ManifestFixer.h | 6 | ||||
| -rw-r--r-- | tools/aapt2/link/ManifestFixer_test.cpp | 57 | 
5 files changed, 110 insertions, 3 deletions
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h index 5fdfb66bdf4e..2ce2167c1bf3 100644 --- a/tools/aapt2/cmd/Link.h +++ b/tools/aapt2/cmd/Link.h @@ -209,6 +209,8 @@ class LinkCommand : public Command {      AddOptionalFlag("--compile-sdk-version-name",          "Version name to inject into the AndroidManifest.xml if none is present.",          &options_.manifest_fixer_options.compile_sdk_version_codename); +    AddOptionalFlagList("--fingerprint-prefix", "Fingerprint prefix to add to install constraints.", +                        &options_.manifest_fixer_options.fingerprint_prefixes);      AddOptionalSwitch("--shared-lib", "Generates a shared Android runtime library.",          &shared_lib_);      AddOptionalSwitch("--static-lib", "Generate a static Android library.", &static_lib_); diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp index c66f4e5b7c30..a43bf1b60f42 100644 --- a/tools/aapt2/dump/DumpManifest.cpp +++ b/tools/aapt2/dump/DumpManifest.cpp @@ -2120,6 +2120,33 @@ class InputType : public ManifestExtractor::Element {    }  }; +/** Represents <install-constraints> elements. **/ +class InstallConstraints : public ManifestExtractor::Element { + public: +  InstallConstraints() = default; +  std::vector<std::string> fingerprint_prefixes; + +  void Extract(xml::Element* element) override { +    for (xml::Element* child : element->GetChildElements()) { +      if (child->name == "fingerprint-prefix") { +        xml::Attribute* attr = child->FindAttribute(kAndroidNamespace, "value"); +        if (attr) { +          fingerprint_prefixes.push_back(attr->value); +        } +      } +    } +  } + +  void Print(text::Printer* printer) override { +    if (!fingerprint_prefixes.empty()) { +      printer->Print(StringPrintf("install-constraints:\n")); +      for (const auto& prefix : fingerprint_prefixes) { +        printer->Print(StringPrintf("  fingerprint-prefix='%s'\n", prefix.c_str())); +      } +    } +  } +}; +  /** Represents <original-package> elements. **/  class OriginalPackage : public ManifestExtractor::Element {   public: @@ -2869,7 +2896,7 @@ template <typename T>  constexpr const char* GetExpectedTagForType() {    // This array does not appear at runtime, as GetExpectedTagForType function is used by compiler    // to inject proper 'expected_tag' into ElementCast. -  std::array<std::pair<const char*, bool>, 37> tags = { +  std::array<std::pair<const char*, bool>, 38> tags = {        std::make_pair("action", std::is_same<Action, T>::value),        std::make_pair("activity", std::is_same<Activity, T>::value),        std::make_pair("additional-certificate", std::is_same<AdditionalCertificate, T>::value), @@ -2878,6 +2905,7 @@ constexpr const char* GetExpectedTagForType() {        std::make_pair("compatible-screens", std::is_same<CompatibleScreens, T>::value),        std::make_pair("feature-group", std::is_same<FeatureGroup, T>::value),        std::make_pair("input-type", std::is_same<InputType, T>::value), +      std::make_pair("install-constraints", std::is_same<InstallConstraints, T>::value),        std::make_pair("intent-filter", std::is_same<IntentFilter, T>::value),        std::make_pair("meta-data", std::is_same<MetaData, T>::value),        std::make_pair("manifest", std::is_same<Manifest, T>::value), @@ -2948,6 +2976,7 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate(            {"compatible-screens", &CreateType<CompatibleScreens>},            {"feature-group", &CreateType<FeatureGroup>},            {"input-type", &CreateType<InputType>}, +          {"install-constraints", &CreateType<InstallConstraints>},            {"intent-filter", &CreateType<IntentFilter>},            {"manifest", &CreateType<Manifest>},            {"meta-data", &CreateType<MetaData>}, diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp index 56d90758ee73..53f0abee1cf2 100644 --- a/tools/aapt2/link/ManifestFixer.cpp +++ b/tools/aapt2/link/ManifestFixer.cpp @@ -749,6 +749,23 @@ bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) {      attr->value = options_.compile_sdk_version_codename.value();    } +  if (!options_.fingerprint_prefixes.empty()) { +    xml::Element* install_constraints_el = root->FindChild({}, "install-constraints"); +    if (install_constraints_el == nullptr) { +      std::unique_ptr<xml::Element> install_constraints = std::make_unique<xml::Element>(); +      install_constraints->name = "install-constraints"; +      install_constraints_el = install_constraints.get(); +      root->AppendChild(std::move(install_constraints)); +    } +    for (const std::string& prefix : options_.fingerprint_prefixes) { +      std::unique_ptr<xml::Element> prefix_el = std::make_unique<xml::Element>(); +      prefix_el->name = "fingerprint-prefix"; +      xml::Attribute* attr = prefix_el->FindOrCreateAttribute(xml::kSchemaAndroid, "value"); +      attr->value = prefix; +      install_constraints_el->AppendChild(std::move(prefix_el)); +    } +  } +    xml::XmlActionExecutor executor;    if (!BuildRules(&executor, context->GetDiagnostics())) {      return false; diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h index 90f5177e752e..175ab6f1cd7b 100644 --- a/tools/aapt2/link/ManifestFixer.h +++ b/tools/aapt2/link/ManifestFixer.h @@ -18,11 +18,10 @@  #define AAPT_LINK_MANIFESTFIXER_H  #include <string> +#include <vector>  #include "android-base/macros.h" -  #include "process/IResourceTableConsumer.h" -  #include "xml/XmlActionExecutor.h"  #include "xml/XmlDom.h" @@ -75,6 +74,9 @@ struct ManifestFixerOptions {    // 'android:compileSdkVersionCodename' in the <manifest> tag.    std::optional<std::string> compile_sdk_version_codename; +  // The fingerprint prefixes to be added to the <install-constraints> tag. +  std::vector<std::string> fingerprint_prefixes; +    // Whether validation errors should be treated only as warnings. If this is 'true', then an    // incorrect node will not result in an error, but only as a warning, and the parsing will    // continue. diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp index 7180ae6b8bc7..1b8f05b957a7 100644 --- a/tools/aapt2/link/ManifestFixer_test.cpp +++ b/tools/aapt2/link/ManifestFixer_test.cpp @@ -965,6 +965,63 @@ TEST_F(ManifestFixerTest, UnexpectedElementsInManifest) {    ASSERT_THAT(manifest, IsNull());  } +TEST_F(ManifestFixerTest, InsertFingerprintPrefixIfNotExist) { +  std::string input = R"( +      <manifest xmlns:android="http://schemas.android.com/apk/res/android" +          package="android"> +      </manifest>)"; +  ManifestFixerOptions options; +  options.fingerprint_prefixes = {"foo", "bar"}; + +  std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options); +  ASSERT_THAT(manifest, NotNull()); +  xml::Element* install_constraints = manifest->root.get()->FindChild({}, "install-constraints"); +  ASSERT_THAT(install_constraints, NotNull()); +  std::vector<xml::Element*> fingerprint_prefixes = install_constraints->GetChildElements(); +  EXPECT_EQ(fingerprint_prefixes.size(), 2); +  xml::Attribute* attr; +  EXPECT_THAT(fingerprint_prefixes[0]->name, StrEq("fingerprint-prefix")); +  attr = fingerprint_prefixes[0]->FindAttribute(xml::kSchemaAndroid, "value"); +  ASSERT_THAT(attr, NotNull()); +  EXPECT_THAT(attr->value, StrEq("foo")); +  EXPECT_THAT(fingerprint_prefixes[1]->name, StrEq("fingerprint-prefix")); +  attr = fingerprint_prefixes[1]->FindAttribute(xml::kSchemaAndroid, "value"); +  ASSERT_THAT(attr, NotNull()); +  EXPECT_THAT(attr->value, StrEq("bar")); +} + +TEST_F(ManifestFixerTest, AppendFingerprintPrefixIfExists) { +  std::string input = R"( +      <manifest xmlns:android="http://schemas.android.com/apk/res/android" +          package="android"> +          <install-constraints> +            <fingerprint-prefix android:value="foo" /> +          </install-constraints> +      </manifest>)"; +  ManifestFixerOptions options; +  options.fingerprint_prefixes = {"bar", "baz"}; + +  std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options); +  ASSERT_THAT(manifest, NotNull()); +  xml::Element* install_constraints = manifest->root.get()->FindChild({}, "install-constraints"); +  ASSERT_THAT(install_constraints, NotNull()); +  std::vector<xml::Element*> fingerprint_prefixes = install_constraints->GetChildElements(); +  EXPECT_EQ(fingerprint_prefixes.size(), 3); +  xml::Attribute* attr; +  EXPECT_THAT(fingerprint_prefixes[0]->name, StrEq("fingerprint-prefix")); +  attr = fingerprint_prefixes[0]->FindAttribute(xml::kSchemaAndroid, "value"); +  ASSERT_THAT(attr, NotNull()); +  EXPECT_THAT(attr->value, StrEq("foo")); +  EXPECT_THAT(fingerprint_prefixes[1]->name, StrEq("fingerprint-prefix")); +  attr = fingerprint_prefixes[1]->FindAttribute(xml::kSchemaAndroid, "value"); +  ASSERT_THAT(attr, NotNull()); +  EXPECT_THAT(attr->value, StrEq("bar")); +  EXPECT_THAT(fingerprint_prefixes[2]->name, StrEq("fingerprint-prefix")); +  attr = fingerprint_prefixes[2]->FindAttribute(xml::kSchemaAndroid, "value"); +  ASSERT_THAT(attr, NotNull()); +  EXPECT_THAT(attr->value, StrEq("baz")); +} +  TEST_F(ManifestFixerTest, UsesLibraryMustHaveNonEmptyName) {    std::string input = R"(        <manifest xmlns:android="http://schemas.android.com/apk/res/android"  |