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 Change-Id: If357c6df09491fa1bec5fe1a00a682d634af69b7
This commit is contained in:
@@ -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_);
|
||||
|
||||
@@ -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>},
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user