1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "link/ManifestFixer.h"
18 
19 #include <unordered_set>
20 
21 #include "android-base/logging.h"
22 
23 #include "ResourceUtils.h"
24 #include "trace/TraceBuffer.h"
25 #include "util/Util.h"
26 #include "xml/XmlActionExecutor.h"
27 #include "xml/XmlDom.h"
28 
29 using android::StringPiece;
30 
31 namespace aapt {
32 
RequiredNameIsNotEmpty(xml::Element * el,SourcePathDiagnostics * diag)33 static bool RequiredNameIsNotEmpty(xml::Element* el, SourcePathDiagnostics* diag) {
34   xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name");
35   if (attr == nullptr) {
36     diag->Error(DiagMessage(el->line_number)
37                 << "<" << el->name << "> is missing attribute 'android:name'");
38     return false;
39   }
40 
41   if (attr->value.empty()) {
42     diag->Error(DiagMessage(el->line_number)
43                 << "attribute 'android:name' in <" << el->name << "> tag must not be empty");
44     return false;
45   }
46   return true;
47 }
48 
49 // This is how PackageManager builds class names from AndroidManifest.xml entries.
NameIsJavaClassName(xml::Element * el,xml::Attribute * attr,SourcePathDiagnostics * diag)50 static bool NameIsJavaClassName(xml::Element* el, xml::Attribute* attr,
51                                 SourcePathDiagnostics* diag) {
52   // We allow unqualified class names (ie: .HelloActivity)
53   // Since we don't know the package name, we can just make a fake one here and
54   // the test will be identical as long as the real package name is valid too.
55   Maybe<std::string> fully_qualified_class_name =
56       util::GetFullyQualifiedClassName("a", attr->value);
57 
58   StringPiece qualified_class_name = fully_qualified_class_name
59                                          ? fully_qualified_class_name.value()
60                                          : attr->value;
61 
62   if (!util::IsJavaClassName(qualified_class_name)) {
63     diag->Error(DiagMessage(el->line_number)
64                 << "attribute 'android:name' in <" << el->name
65                 << "> tag must be a valid Java class name");
66     return false;
67   }
68   return true;
69 }
70 
OptionalNameIsJavaClassName(xml::Element * el,SourcePathDiagnostics * diag)71 static bool OptionalNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) {
72   if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
73     return NameIsJavaClassName(el, attr, diag);
74   }
75   return true;
76 }
77 
RequiredNameIsJavaClassName(xml::Element * el,SourcePathDiagnostics * diag)78 static bool RequiredNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) {
79   xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name");
80   if (attr == nullptr) {
81     diag->Error(DiagMessage(el->line_number)
82                 << "<" << el->name << "> is missing attribute 'android:name'");
83     return false;
84   }
85   return NameIsJavaClassName(el, attr, diag);
86 }
87 
RequiredNameIsJavaPackage(xml::Element * el,SourcePathDiagnostics * diag)88 static bool RequiredNameIsJavaPackage(xml::Element* el, SourcePathDiagnostics* diag) {
89   xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name");
90   if (attr == nullptr) {
91     diag->Error(DiagMessage(el->line_number)
92                 << "<" << el->name << "> is missing attribute 'android:name'");
93     return false;
94   }
95 
96   if (!util::IsJavaPackageName(attr->value)) {
97     diag->Error(DiagMessage(el->line_number) << "attribute 'android:name' in <" << el->name
98                                              << "> tag must be a valid Java package name");
99     return false;
100   }
101   return true;
102 }
103 
RequiredAndroidAttribute(const std::string & attr)104 static xml::XmlNodeAction::ActionFuncWithDiag RequiredAndroidAttribute(const std::string& attr) {
105   return [=](xml::Element* el, SourcePathDiagnostics* diag) -> bool {
106     if (el->FindAttribute(xml::kSchemaAndroid, attr) == nullptr) {
107       diag->Error(DiagMessage(el->line_number)
108                   << "<" << el->name << "> is missing required attribute 'android:" << attr << "'");
109       return false;
110     }
111     return true;
112   };
113 }
114 
AutoGenerateIsFeatureSplit(xml::Element * el,SourcePathDiagnostics * diag)115 static bool AutoGenerateIsFeatureSplit(xml::Element* el, SourcePathDiagnostics* diag) {
116   constexpr const char* kFeatureSplit = "featureSplit";
117   constexpr const char* kIsFeatureSplit = "isFeatureSplit";
118 
119   xml::Attribute* attr = el->FindAttribute({}, kFeatureSplit);
120   if (attr != nullptr) {
121     // Rewrite the featureSplit attribute to be "split". This is what the
122     // platform recognizes.
123     attr->name = "split";
124 
125     // Now inject the android:isFeatureSplit="true" attribute.
126     xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, kIsFeatureSplit);
127     if (attr != nullptr) {
128       if (!ResourceUtils::ParseBool(attr->value).value_or_default(false)) {
129         // The isFeatureSplit attribute is false, which conflicts with the use
130         // of "featureSplit".
131         diag->Error(DiagMessage(el->line_number)
132                     << "attribute 'featureSplit' used in <manifest> but 'android:isFeatureSplit' "
133                        "is not 'true'");
134         return false;
135       }
136 
137       // The attribute is already there and set to true, nothing to do.
138     } else {
139       el->attributes.push_back(xml::Attribute{xml::kSchemaAndroid, kIsFeatureSplit, "true"});
140     }
141   }
142   return true;
143 }
144 
VerifyManifest(xml::Element * el,SourcePathDiagnostics * diag)145 static bool VerifyManifest(xml::Element* el, SourcePathDiagnostics* diag) {
146   xml::Attribute* attr = el->FindAttribute({}, "package");
147   if (!attr) {
148     diag->Error(DiagMessage(el->line_number)
149                 << "<manifest> tag is missing 'package' attribute");
150     return false;
151   } else if (ResourceUtils::IsReference(attr->value)) {
152     diag->Error(DiagMessage(el->line_number)
153                 << "attribute 'package' in <manifest> tag must not be a reference");
154     return false;
155   } else if (!util::IsAndroidPackageName(attr->value)) {
156     diag->Error(DiagMessage(el->line_number)
157                 << "attribute 'package' in <manifest> tag is not a valid Android package name: '"
158                 << attr->value << "'");
159     return false;
160   }
161 
162   attr = el->FindAttribute({}, "split");
163   if (attr) {
164     if (!util::IsJavaPackageName(attr->value)) {
165       diag->Error(DiagMessage(el->line_number) << "attribute 'split' in <manifest> tag is not a "
166                                                   "valid split name");
167       return false;
168     }
169   }
170   return true;
171 }
172 
173 // The coreApp attribute in <manifest> is not a regular AAPT attribute, so type
174 // checking on it is manual.
FixCoreAppAttribute(xml::Element * el,SourcePathDiagnostics * diag)175 static bool FixCoreAppAttribute(xml::Element* el, SourcePathDiagnostics* diag) {
176   if (xml::Attribute* attr = el->FindAttribute("", "coreApp")) {
177     std::unique_ptr<BinaryPrimitive> result = ResourceUtils::TryParseBool(attr->value);
178     if (!result) {
179       diag->Error(DiagMessage(el->line_number) << "attribute coreApp must be a boolean");
180       return false;
181     }
182     attr->compiled_value = std::move(result);
183   }
184   return true;
185 }
186 
187 // Checks that <uses-feature> has android:glEsVersion or android:name, not both (or neither).
VerifyUsesFeature(xml::Element * el,SourcePathDiagnostics * diag)188 static bool VerifyUsesFeature(xml::Element* el, SourcePathDiagnostics* diag) {
189   bool has_name = false;
190   if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
191     if (attr->value.empty()) {
192       diag->Error(DiagMessage(el->line_number)
193                   << "android:name in <uses-feature> must not be empty");
194       return false;
195     }
196     has_name = true;
197   }
198 
199   bool has_gl_es_version = false;
200   if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "glEsVersion")) {
201     if (has_name) {
202       diag->Error(DiagMessage(el->line_number)
203                   << "cannot define both android:name and android:glEsVersion in <uses-feature>");
204       return false;
205     }
206     has_gl_es_version = true;
207   }
208 
209   if (!has_name && !has_gl_es_version) {
210     diag->Error(DiagMessage(el->line_number)
211                 << "<uses-feature> must have either android:name or android:glEsVersion attribute");
212     return false;
213   }
214   return true;
215 }
216 
217 // Ensure that 'ns_decls' contains a declaration for 'uri', using 'prefix' as
218 // the xmlns prefix if possible.
EnsureNamespaceIsDeclared(const std::string & prefix,const std::string & uri,std::vector<xml::NamespaceDecl> * ns_decls)219 static void EnsureNamespaceIsDeclared(const std::string& prefix, const std::string& uri,
220                                       std::vector<xml::NamespaceDecl>* ns_decls) {
221   if (std::find_if(ns_decls->begin(), ns_decls->end(), [&](const xml::NamespaceDecl& ns_decl) {
222         return ns_decl.uri == uri;
223       }) != ns_decls->end()) {
224     return;
225   }
226 
227   std::set<std::string> used_prefixes;
228   for (const auto& ns_decl : *ns_decls) {
229     used_prefixes.insert(ns_decl.prefix);
230   }
231 
232   // Make multiple attempts in the unlikely event that 'prefix' is already taken.
233   std::string disambiguator;
234   for (int i = 0; i < used_prefixes.size() + 1; i++) {
235     std::string attempted_prefix = prefix + disambiguator;
236     if (used_prefixes.find(attempted_prefix) == used_prefixes.end()) {
237       ns_decls->push_back(xml::NamespaceDecl{attempted_prefix, uri});
238       return;
239     }
240     disambiguator = std::to_string(i);
241   }
242 }
243 
BuildRules(xml::XmlActionExecutor * executor,IDiagnostics * diag)244 bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
245                                IDiagnostics* diag) {
246   // First verify some options.
247   if (options_.rename_manifest_package) {
248     if (!util::IsJavaPackageName(options_.rename_manifest_package.value())) {
249       diag->Error(DiagMessage() << "invalid manifest package override '"
250                                 << options_.rename_manifest_package.value()
251                                 << "'");
252       return false;
253     }
254   }
255 
256   if (options_.rename_instrumentation_target_package) {
257     if (!util::IsJavaPackageName(options_.rename_instrumentation_target_package.value())) {
258       diag->Error(DiagMessage()
259                   << "invalid instrumentation target package override '"
260                   << options_.rename_instrumentation_target_package.value()
261                   << "'");
262       return false;
263     }
264   }
265 
266   if (options_.rename_overlay_target_package) {
267     if (!util::IsJavaPackageName(options_.rename_overlay_target_package.value())) {
268       diag->Error(DiagMessage()
269                   << "invalid overlay target package override '"
270                   << options_.rename_overlay_target_package.value()
271                   << "'");
272       return false;
273     }
274   }
275 
276   // Common <intent-filter> actions.
277   xml::XmlNodeAction intent_filter_action;
278   intent_filter_action["action"].Action(RequiredNameIsNotEmpty);
279   intent_filter_action["category"].Action(RequiredNameIsNotEmpty);
280   intent_filter_action["data"];
281 
282   // Common <meta-data> actions.
283   xml::XmlNodeAction meta_data_action;
284 
285   // Common <uses-feature> actions.
286   xml::XmlNodeAction uses_feature_action;
287   uses_feature_action.Action(VerifyUsesFeature);
288 
289   // Common component actions.
290   xml::XmlNodeAction component_action;
291   component_action.Action(RequiredNameIsJavaClassName);
292   component_action["intent-filter"] = intent_filter_action;
293   component_action["preferred"] = intent_filter_action;
294   component_action["meta-data"] = meta_data_action;
295 
296   // Manifest actions.
297   xml::XmlNodeAction& manifest_action = (*executor)["manifest"];
298   manifest_action.Action(AutoGenerateIsFeatureSplit);
299   manifest_action.Action(VerifyManifest);
300   manifest_action.Action(FixCoreAppAttribute);
301   manifest_action.Action([&](xml::Element* el) -> bool {
302     EnsureNamespaceIsDeclared("android", xml::kSchemaAndroid, &el->namespace_decls);
303 
304     if (options_.version_name_default) {
305       if (options_.replace_version) {
306         el->RemoveAttribute(xml::kSchemaAndroid, "versionName");
307       }
308       if (el->FindAttribute(xml::kSchemaAndroid, "versionName") == nullptr) {
309         el->attributes.push_back(
310             xml::Attribute{xml::kSchemaAndroid, "versionName",
311                            options_.version_name_default.value()});
312       }
313     }
314 
315     if (options_.version_code_default) {
316       if (options_.replace_version) {
317         el->RemoveAttribute(xml::kSchemaAndroid, "versionCode");
318       }
319       if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) {
320         el->attributes.push_back(
321             xml::Attribute{xml::kSchemaAndroid, "versionCode",
322                            options_.version_code_default.value()});
323       }
324     }
325 
326     if (options_.version_code_major_default) {
327       if (options_.replace_version) {
328         el->RemoveAttribute(xml::kSchemaAndroid, "versionCodeMajor");
329       }
330       if (el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor") == nullptr) {
331         el->attributes.push_back(
332             xml::Attribute{xml::kSchemaAndroid, "versionCodeMajor",
333                            options_.version_code_major_default.value()});
334       }
335     }
336 
337     return true;
338   });
339 
340   // Meta tags.
341   manifest_action["eat-comment"];
342 
343   // Uses-sdk actions.
344   manifest_action["uses-sdk"].Action([&](xml::Element* el) -> bool {
345     if (options_.min_sdk_version_default &&
346         el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion") == nullptr) {
347       // There was no minSdkVersion defined and we have a default to assign.
348       el->attributes.push_back(
349           xml::Attribute{xml::kSchemaAndroid, "minSdkVersion",
350                          options_.min_sdk_version_default.value()});
351     }
352 
353     if (options_.target_sdk_version_default &&
354         el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion") == nullptr) {
355       // There was no targetSdkVersion defined and we have a default to assign.
356       el->attributes.push_back(
357           xml::Attribute{xml::kSchemaAndroid, "targetSdkVersion",
358                          options_.target_sdk_version_default.value()});
359     }
360     return true;
361   });
362   manifest_action["uses-sdk"]["extension-sdk"];
363 
364   // Instrumentation actions.
365   manifest_action["instrumentation"].Action(RequiredNameIsJavaClassName);
366   manifest_action["instrumentation"].Action([&](xml::Element* el) -> bool {
367     if (!options_.rename_instrumentation_target_package) {
368       return true;
369     }
370 
371     if (xml::Attribute* attr =
372             el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) {
373       attr->value = options_.rename_instrumentation_target_package.value();
374     }
375     return true;
376   });
377   manifest_action["instrumentation"]["meta-data"] = meta_data_action;
378 
379   // TODO moltmann: Remove
380   manifest_action["feature"];
381   manifest_action["feature"]["inherit-from"];
382 
383   manifest_action["attribution"];
384   manifest_action["attribution"]["inherit-from"];
385   manifest_action["original-package"];
386   manifest_action["overlay"].Action([&](xml::Element* el) -> bool {
387     if (!options_.rename_overlay_target_package) {
388       return true;
389     }
390 
391     if (xml::Attribute* attr =
392             el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) {
393       attr->value = options_.rename_overlay_target_package.value();
394     }
395     return true;
396   });
397   manifest_action["protected-broadcast"];
398   manifest_action["adopt-permissions"];
399   manifest_action["uses-permission"];
400   manifest_action["uses-permission-sdk-23"];
401   manifest_action["permission"];
402   manifest_action["permission"]["meta-data"] = meta_data_action;
403   manifest_action["permission-tree"];
404   manifest_action["permission-group"];
405   manifest_action["uses-configuration"];
406   manifest_action["supports-screens"];
407   manifest_action["uses-feature"] = uses_feature_action;
408   manifest_action["feature-group"]["uses-feature"] = uses_feature_action;
409   manifest_action["compatible-screens"];
410   manifest_action["compatible-screens"]["screen"];
411   manifest_action["supports-gl-texture"];
412   manifest_action["restrict-update"];
413   manifest_action["package-verifier"];
414   manifest_action["meta-data"] = meta_data_action;
415   manifest_action["uses-split"].Action(RequiredNameIsJavaPackage);
416   manifest_action["queries"]["package"].Action(RequiredNameIsJavaPackage);
417   manifest_action["queries"]["intent"] = intent_filter_action;
418   manifest_action["queries"]["provider"].Action(RequiredAndroidAttribute("authorities"));
419   // TODO: more complicated component name tag
420 
421   manifest_action["key-sets"]["key-set"]["public-key"];
422   manifest_action["key-sets"]["upgrade-key-set"];
423 
424   // Application actions.
425   xml::XmlNodeAction& application_action = manifest_action["application"];
426   application_action.Action(OptionalNameIsJavaClassName);
427 
428   application_action["uses-library"].Action(RequiredNameIsNotEmpty);
429   application_action["library"].Action(RequiredNameIsNotEmpty);
430   application_action["profileable"];
431 
432   xml::XmlNodeAction& static_library_action = application_action["static-library"];
433   static_library_action.Action(RequiredNameIsJavaPackage);
434   static_library_action.Action(RequiredAndroidAttribute("version"));
435 
436   xml::XmlNodeAction& uses_static_library_action = application_action["uses-static-library"];
437   uses_static_library_action.Action(RequiredNameIsJavaPackage);
438   uses_static_library_action.Action(RequiredAndroidAttribute("version"));
439   uses_static_library_action.Action(RequiredAndroidAttribute("certDigest"));
440   uses_static_library_action["additional-certificate"];
441 
442   xml::XmlNodeAction& uses_package_action = application_action["uses-package"];
443   uses_package_action.Action(RequiredNameIsJavaPackage);
444   uses_package_action["additional-certificate"];
445 
446   if (options_.debug_mode) {
447     application_action.Action([&](xml::Element* el) -> bool {
448       xml::Attribute *attr = el->FindOrCreateAttribute(xml::kSchemaAndroid, "debuggable");
449       attr->value = "true";
450       return true;
451     });
452   }
453 
454   application_action["meta-data"] = meta_data_action;
455 
456   application_action["processes"];
457   application_action["processes"]["deny-permission"];
458   application_action["processes"]["allow-permission"];
459   application_action["processes"]["process"]["deny-permission"];
460   application_action["processes"]["process"]["allow-permission"];
461 
462   application_action["activity"] = component_action;
463   application_action["activity"]["layout"];
464 
465   application_action["activity-alias"] = component_action;
466   application_action["service"] = component_action;
467   application_action["receiver"] = component_action;
468 
469   // Provider actions.
470   application_action["provider"] = component_action;
471   application_action["provider"]["grant-uri-permission"];
472   application_action["provider"]["path-permission"];
473 
474   manifest_action["package"] = manifest_action;
475 
476   return true;
477 }
478 
FullyQualifyClassName(const StringPiece & package,const StringPiece & attr_ns,const StringPiece & attr_name,xml::Element * el)479 static void FullyQualifyClassName(const StringPiece& package, const StringPiece& attr_ns,
480                                   const StringPiece& attr_name, xml::Element* el) {
481   xml::Attribute* attr = el->FindAttribute(attr_ns, attr_name);
482   if (attr != nullptr) {
483     if (Maybe<std::string> new_value = util::GetFullyQualifiedClassName(package, attr->value)) {
484       attr->value = std::move(new_value.value());
485     }
486   }
487 }
488 
RenameManifestPackage(const StringPiece & package_override,xml::Element * manifest_el)489 static bool RenameManifestPackage(const StringPiece& package_override, xml::Element* manifest_el) {
490   xml::Attribute* attr = manifest_el->FindAttribute({}, "package");
491 
492   // We've already verified that the manifest element is present, with a package
493   // name specified.
494   CHECK(attr != nullptr);
495 
496   std::string original_package = std::move(attr->value);
497   attr->value = package_override.to_string();
498 
499   xml::Element* application_el = manifest_el->FindChild({}, "application");
500   if (application_el != nullptr) {
501     FullyQualifyClassName(original_package, xml::kSchemaAndroid, "name", application_el);
502     FullyQualifyClassName(original_package, xml::kSchemaAndroid, "backupAgent", application_el);
503 
504     for (xml::Element* child_el : application_el->GetChildElements()) {
505       if (child_el->namespace_uri.empty()) {
506         if (child_el->name == "activity" || child_el->name == "activity-alias" ||
507             child_el->name == "provider" || child_el->name == "receiver" ||
508             child_el->name == "service") {
509           FullyQualifyClassName(original_package, xml::kSchemaAndroid, "name", child_el);
510         }
511 
512         if (child_el->name == "activity-alias") {
513           FullyQualifyClassName(original_package, xml::kSchemaAndroid, "targetActivity", child_el);
514         }
515       }
516     }
517   }
518   return true;
519 }
520 
Consume(IAaptContext * context,xml::XmlResource * doc)521 bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) {
522   TRACE_CALL();
523   xml::Element* root = xml::FindRootElement(doc->root.get());
524   if (!root || !root->namespace_uri.empty() || root->name != "manifest") {
525     context->GetDiagnostics()->Error(DiagMessage(doc->file.source)
526                                      << "root tag must be <manifest>");
527     return false;
528   }
529 
530   if ((options_.min_sdk_version_default || options_.target_sdk_version_default) &&
531       root->FindChild({}, "uses-sdk") == nullptr) {
532     // Auto insert a <uses-sdk> element. This must be inserted before the
533     // <application> tag. The device runtime PackageParser will make SDK version
534     // decisions while parsing <application>.
535     std::unique_ptr<xml::Element> uses_sdk = util::make_unique<xml::Element>();
536     uses_sdk->name = "uses-sdk";
537     root->InsertChild(0, std::move(uses_sdk));
538   }
539 
540   if (options_.compile_sdk_version) {
541     xml::Attribute* attr = root->FindOrCreateAttribute(xml::kSchemaAndroid, "compileSdkVersion");
542 
543     // Make sure we un-compile the value if it was set to something else.
544     attr->compiled_value = {};
545     attr->value = options_.compile_sdk_version.value();
546 
547     attr = root->FindOrCreateAttribute("", "platformBuildVersionCode");
548 
549     // Make sure we un-compile the value if it was set to something else.
550     attr->compiled_value = {};
551     attr->value = options_.compile_sdk_version.value();
552 
553   }
554 
555   if (options_.compile_sdk_version_codename) {
556     xml::Attribute* attr =
557         root->FindOrCreateAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename");
558 
559     // Make sure we un-compile the value if it was set to something else.
560     attr->compiled_value = {};
561     attr->value = options_.compile_sdk_version_codename.value();
562 
563     attr = root->FindOrCreateAttribute("", "platformBuildVersionName");
564 
565     // Make sure we un-compile the value if it was set to something else.
566     attr->compiled_value = {};
567     attr->value = options_.compile_sdk_version_codename.value();
568   }
569 
570   xml::XmlActionExecutor executor;
571   if (!BuildRules(&executor, context->GetDiagnostics())) {
572     return false;
573   }
574 
575   xml::XmlActionExecutorPolicy policy = options_.warn_validation
576                                             ? xml::XmlActionExecutorPolicy::kWhitelistWarning
577                                             : xml::XmlActionExecutorPolicy::kWhitelist;
578   if (!executor.Execute(policy, context->GetDiagnostics(), doc)) {
579     return false;
580   }
581 
582   if (options_.rename_manifest_package) {
583     // Rename manifest package outside of the XmlActionExecutor.
584     // We need to extract the old package name and FullyQualify all class
585     // names.
586     if (!RenameManifestPackage(options_.rename_manifest_package.value(), root)) {
587       return false;
588     }
589   }
590   return true;
591 }
592 
593 }  // namespace aapt
594