diff options
Diffstat (limited to 'tools/aapt2/link/ManifestFixer.cpp')
-rw-r--r-- | tools/aapt2/link/ManifestFixer.cpp | 127 |
1 files changed, 88 insertions, 39 deletions
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp index de4fb736758c..713db5b7ed86 100644 --- a/tools/aapt2/link/ManifestFixer.cpp +++ b/tools/aapt2/link/ManifestFixer.cpp @@ -29,6 +29,22 @@ using android::StringPiece; namespace aapt { +static bool RequiredNameIsNotEmpty(xml::Element* el, SourcePathDiagnostics* diag) { + xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name"); + if (attr == nullptr) { + diag->Error(DiagMessage(el->line_number) + << "<" << el->name << "> is missing attribute 'android:name'"); + return false; + } + + if (attr->value.empty()) { + diag->Error(DiagMessage(el->line_number) + << "attribute 'android:name' in <" << el->name << "> tag must not be empty"); + return false; + } + return true; +} + // This is how PackageManager builds class names from AndroidManifest.xml entries. static bool NameIsJavaClassName(xml::Element* el, xml::Attribute* attr, SourcePathDiagnostics* diag) { @@ -59,21 +75,29 @@ static bool OptionalNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* } static bool RequiredNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) { - if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) { - return NameIsJavaClassName(el, attr, diag); + xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name"); + if (attr == nullptr) { + diag->Error(DiagMessage(el->line_number) + << "<" << el->name << "> is missing attribute 'android:name'"); + return false; } - diag->Error(DiagMessage(el->line_number) - << "<" << el->name << "> is missing attribute 'android:name'"); - return false; + return NameIsJavaClassName(el, attr, diag); } static bool RequiredNameIsJavaPackage(xml::Element* el, SourcePathDiagnostics* diag) { - if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) { - return util::IsJavaPackageName(attr->value); + xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name"); + if (attr == nullptr) { + diag->Error(DiagMessage(el->line_number) + << "<" << el->name << "> is missing attribute 'android:name'"); + return false; } - diag->Error(DiagMessage(el->line_number) - << "<" << el->name << "> is missing attribute 'android:name'"); - return false; + + if (!util::IsJavaPackageName(attr->value)) { + diag->Error(DiagMessage(el->line_number) << "attribute 'android:name' in <" << el->name + << "> tag must be a valid Java package name"); + return false; + } + return true; } static xml::XmlNodeAction::ActionFuncWithDiag RequiredAndroidAttribute(const std::string& attr) { @@ -213,8 +237,8 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, // Common <intent-filter> actions. xml::XmlNodeAction intent_filter_action; - intent_filter_action["action"]; - intent_filter_action["category"]; + intent_filter_action["action"].Action(RequiredNameIsNotEmpty); + intent_filter_action["category"].Action(RequiredNameIsNotEmpty); intent_filter_action["data"]; // Common <meta-data> actions. @@ -295,6 +319,7 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, manifest_action["original-package"]; manifest_action["overlay"]; manifest_action["protected-broadcast"]; + manifest_action["adopt-permissions"]; manifest_action["uses-permission"]; manifest_action["uses-permission-sdk-23"]; manifest_action["permission"]; @@ -317,8 +342,8 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, xml::XmlNodeAction& application_action = manifest_action["application"]; application_action.Action(OptionalNameIsJavaClassName); - application_action["uses-library"].Action(RequiredNameIsJavaPackage); - application_action["library"].Action(RequiredNameIsJavaPackage); + application_action["uses-library"].Action(RequiredNameIsNotEmpty); + application_action["library"].Action(RequiredNameIsNotEmpty); xml::XmlNodeAction& static_library_action = application_action["static-library"]; static_library_action.Action(RequiredNameIsJavaPackage); @@ -346,30 +371,15 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, return true; } -class FullyQualifiedClassNameVisitor : public xml::Visitor { - public: - using xml::Visitor::Visit; - - explicit FullyQualifiedClassNameVisitor(const StringPiece& package) : package_(package) {} - - void Visit(xml::Element* el) override { - for (xml::Attribute& attr : el->attributes) { - if (attr.namespace_uri == xml::kSchemaAndroid && - class_attributes_.find(attr.name) != class_attributes_.end()) { - if (Maybe<std::string> new_value = util::GetFullyQualifiedClassName(package_, attr.value)) { - attr.value = std::move(new_value.value()); - } - } +static void FullyQualifyClassName(const StringPiece& package, const StringPiece& attr_ns, + const StringPiece& attr_name, xml::Element* el) { + xml::Attribute* attr = el->FindAttribute(attr_ns, attr_name); + if (attr != nullptr) { + if (Maybe<std::string> new_value = util::GetFullyQualifiedClassName(package, attr->value)) { + attr->value = std::move(new_value.value()); } - - // Super implementation to iterate over the children. - xml::Visitor::Visit(el); } - - private: - StringPiece package_; - std::unordered_set<StringPiece> class_attributes_ = {"name"}; -}; +} static bool RenameManifestPackage(const StringPiece& package_override, xml::Element* manifest_el) { xml::Attribute* attr = manifest_el->FindAttribute({}, "package"); @@ -381,8 +391,25 @@ static bool RenameManifestPackage(const StringPiece& package_override, xml::Elem std::string original_package = std::move(attr->value); attr->value = package_override.to_string(); - FullyQualifiedClassNameVisitor visitor(original_package); - manifest_el->Accept(&visitor); + xml::Element* application_el = manifest_el->FindChild({}, "application"); + if (application_el != nullptr) { + FullyQualifyClassName(original_package, xml::kSchemaAndroid, "name", application_el); + FullyQualifyClassName(original_package, xml::kSchemaAndroid, "backupAgent", application_el); + + for (xml::Element* child_el : application_el->GetChildElements()) { + if (child_el->namespace_uri.empty()) { + if (child_el->name == "activity" || child_el->name == "activity-alias" || + child_el->name == "provider" || child_el->name == "receiver" || + child_el->name == "service") { + FullyQualifyClassName(original_package, xml::kSchemaAndroid, "name", child_el); + } + + if (child_el->name == "activity-alias") { + FullyQualifyClassName(original_package, xml::kSchemaAndroid, "targetActivity", child_el); + } + } + } + } return true; } @@ -404,12 +431,34 @@ bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) { root->InsertChild(0, std::move(uses_sdk)); } + if (options_.compile_sdk_version) { + xml::Attribute* attr = root->FindOrCreateAttribute(xml::kSchemaAndroid, "compileSdkVersion"); + + // Make sure we un-compile the value if it was set to something else. + attr->compiled_value = {}; + + attr->value = options_.compile_sdk_version.value(); + } + + if (options_.compile_sdk_version_codename) { + xml::Attribute* attr = + root->FindOrCreateAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename"); + + // Make sure we un-compile the value if it was set to something else. + attr->compiled_value = {}; + + attr->value = options_.compile_sdk_version_codename.value(); + } + xml::XmlActionExecutor executor; if (!BuildRules(&executor, context->GetDiagnostics())) { return false; } - if (!executor.Execute(xml::XmlActionExecutorPolicy::kWhitelist, context->GetDiagnostics(), doc)) { + xml::XmlActionExecutorPolicy policy = options_.warn_validation + ? xml::XmlActionExecutorPolicy::kWhitelistWarning + : xml::XmlActionExecutorPolicy::kWhitelist; + if (!executor.Execute(policy, context->GetDiagnostics(), doc)) { return false; } |