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

Commit faec5869 authored by Andrei-Valentin Onea's avatar Andrei-Valentin Onea Committed by Android (Google) Code Review
Browse files

Merge "Add support for adding fingerprint prefix install constraints"

parents 06692e2b a10b8082
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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_);
+30 −1
Original line number Diff line number Diff line
@@ -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>},
+17 −0
Original line number Diff line number Diff line
@@ -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;
+4 −2
Original line number Diff line number Diff line
@@ -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.
+57 −0
Original line number Diff line number Diff line
@@ -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"