blob: 313fe453dff521ba773c9a6ebf015a783bdd6fa4 [file] [log] [blame]
Adam Lesinski2ae4a872015-11-02 16:10:55 -08001/*
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
Adam Lesinski2ae4a872015-11-02 16:10:55 -080017#include "link/ManifestFixer.h"
Adam Lesinskice5e56e2016-10-21 17:56:45 -070018
19#include <unordered_set>
20
21#include "android-base/logging.h"
22
Adam Lesinskicacb28f2016-10-19 12:18:14 -070023#include "ResourceUtils.h"
Adam Lesinski2ae4a872015-11-02 16:10:55 -080024#include "util/Util.h"
Adam Lesinskicc5609d2016-04-05 12:41:07 -070025#include "xml/XmlActionExecutor.h"
Adam Lesinski467f1712015-11-16 17:35:44 -080026#include "xml/XmlDom.h"
Adam Lesinski2ae4a872015-11-02 16:10:55 -080027
Adam Lesinskid5083f62017-01-16 15:07:21 -080028using android::StringPiece;
29
Adam Lesinski2ae4a872015-11-02 16:10:55 -080030namespace aapt {
31
Adam Lesinskicc5609d2016-04-05 12:41:07 -070032/**
Adam Lesinskicacb28f2016-10-19 12:18:14 -070033 * This is how PackageManager builds class names from AndroidManifest.xml
34 * entries.
Adam Lesinskicc5609d2016-04-05 12:41:07 -070035 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -070036static bool NameIsJavaClassName(xml::Element* el, xml::Attribute* attr,
Adam Lesinskicc5609d2016-04-05 12:41:07 -070037 SourcePathDiagnostics* diag) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070038 // We allow unqualified class names (ie: .HelloActivity)
39 // Since we don't know the package name, we can just make a fake one here and
40 // the test will be identical as long as the real package name is valid too.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070041 Maybe<std::string> fully_qualified_class_name =
42 util::GetFullyQualifiedClassName("a", attr->value);
Adam Lesinskicc5609d2016-04-05 12:41:07 -070043
Adam Lesinskice5e56e2016-10-21 17:56:45 -070044 StringPiece qualified_class_name = fully_qualified_class_name
45 ? fully_qualified_class_name.value()
46 : attr->value;
Adam Lesinskid0f116b2016-07-08 15:00:32 -070047
Adam Lesinskice5e56e2016-10-21 17:56:45 -070048 if (!util::IsJavaClassName(qualified_class_name)) {
49 diag->Error(DiagMessage(el->line_number)
Adam Lesinskicacb28f2016-10-19 12:18:14 -070050 << "attribute 'android:name' in <" << el->name
51 << "> tag must be a valid Java class name");
Adam Lesinski52364f72016-01-11 13:10:24 -080052 return false;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070053 }
54 return true;
55}
56
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080057static bool OptionalNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -070058 if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
59 return NameIsJavaClassName(el, attr, diag);
Adam Lesinskicacb28f2016-10-19 12:18:14 -070060 }
61 return true;
62}
63
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080064static bool RequiredNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -070065 if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
66 return NameIsJavaClassName(el, attr, diag);
Adam Lesinskicacb28f2016-10-19 12:18:14 -070067 }
Adam Lesinskice5e56e2016-10-21 17:56:45 -070068 diag->Error(DiagMessage(el->line_number)
Adam Lesinskicacb28f2016-10-19 12:18:14 -070069 << "<" << el->name << "> is missing attribute 'android:name'");
70 return false;
Adam Lesinski52364f72016-01-11 13:10:24 -080071}
72
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080073static bool RequiredNameIsJavaPackage(xml::Element* el, SourcePathDiagnostics* diag) {
74 if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
75 return util::IsJavaPackageName(attr->value);
76 }
77 diag->Error(DiagMessage(el->line_number)
78 << "<" << el->name << "> is missing attribute 'android:name'");
79 return false;
80}
81
Adam Lesinskib5dc4bd2017-02-22 19:29:29 -080082static xml::XmlNodeAction::ActionFuncWithDiag RequiredAndroidAttribute(const std::string& attr) {
83 return [=](xml::Element* el, SourcePathDiagnostics* diag) -> bool {
84 if (el->FindAttribute(xml::kSchemaAndroid, attr) == nullptr) {
85 diag->Error(DiagMessage(el->line_number)
86 << "<" << el->name << "> is missing required attribute 'android:" << attr << "'");
87 return false;
88 }
89 return true;
90 };
91}
92
Adam Lesinskice5e56e2016-10-21 17:56:45 -070093static bool VerifyManifest(xml::Element* el, SourcePathDiagnostics* diag) {
94 xml::Attribute* attr = el->FindAttribute({}, "package");
Adam Lesinskicacb28f2016-10-19 12:18:14 -070095 if (!attr) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -070096 diag->Error(DiagMessage(el->line_number)
Adam Lesinskicacb28f2016-10-19 12:18:14 -070097 << "<manifest> tag is missing 'package' attribute");
98 return false;
Adam Lesinskice5e56e2016-10-21 17:56:45 -070099 } else if (ResourceUtils::IsReference(attr->value)) {
100 diag->Error(
101 DiagMessage(el->line_number)
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700102 << "attribute 'package' in <manifest> tag must not be a reference");
103 return false;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700104 } else if (!util::IsJavaPackageName(attr->value)) {
105 diag->Error(DiagMessage(el->line_number)
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700106 << "attribute 'package' in <manifest> tag is not a valid Java "
107 "package name: '"
108 << attr->value << "'");
109 return false;
110 }
111 return true;
Adam Lesinski52364f72016-01-11 13:10:24 -0800112}
113
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700114/**
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700115 * The coreApp attribute in <manifest> is not a regular AAPT attribute, so type
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700116 * checking on it is manual.
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700117 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700118static bool FixCoreAppAttribute(xml::Element* el, SourcePathDiagnostics* diag) {
119 if (xml::Attribute* attr = el->FindAttribute("", "coreApp")) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700120 std::unique_ptr<BinaryPrimitive> result =
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700121 ResourceUtils::TryParseBool(attr->value);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700122 if (!result) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700123 diag->Error(DiagMessage(el->line_number)
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700124 << "attribute coreApp must be a boolean");
125 return false;
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700126 }
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700127 attr->compiled_value = std::move(result);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700128 }
129 return true;
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700130}
131
Adam Lesinski86d67df2017-01-31 13:47:27 -0800132// Checks that <uses-feature> has android:glEsVersion or android:name, not both (or neither).
133static bool VerifyUsesFeature(xml::Element* el, SourcePathDiagnostics* diag) {
134 bool has_name = false;
135 if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
136 if (attr->value.empty()) {
137 diag->Error(DiagMessage(el->line_number)
138 << "android:name in <uses-feature> must not be empty");
139 return false;
140 }
141 has_name = true;
142 }
143
144 bool has_gl_es_version = false;
145 if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "glEsVersion")) {
146 if (has_name) {
147 diag->Error(DiagMessage(el->line_number)
148 << "cannot define both android:name and android:glEsVersion in <uses-feature>");
149 return false;
150 }
151 has_gl_es_version = true;
152 }
153
154 if (!has_name && !has_gl_es_version) {
155 diag->Error(DiagMessage(el->line_number)
156 << "<uses-feature> must have either android:name or android:glEsVersion attribute");
157 return false;
158 }
159 return true;
160}
161
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700162bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700163 IDiagnostics* diag) {
164 // First verify some options.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700165 if (options_.rename_manifest_package) {
166 if (!util::IsJavaPackageName(options_.rename_manifest_package.value())) {
167 diag->Error(DiagMessage() << "invalid manifest package override '"
168 << options_.rename_manifest_package.value()
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700169 << "'");
170 return false;
171 }
172 }
173
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700174 if (options_.rename_instrumentation_target_package) {
175 if (!util::IsJavaPackageName(
176 options_.rename_instrumentation_target_package.value())) {
177 diag->Error(DiagMessage()
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700178 << "invalid instrumentation target package override '"
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700179 << options_.rename_instrumentation_target_package.value()
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700180 << "'");
181 return false;
182 }
183 }
184
Adam Lesinski86d67df2017-01-31 13:47:27 -0800185 // Common <intent-filter> actions.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700186 xml::XmlNodeAction intent_filter_action;
187 intent_filter_action["action"];
188 intent_filter_action["category"];
189 intent_filter_action["data"];
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700190
Adam Lesinski86d67df2017-01-31 13:47:27 -0800191 // Common <meta-data> actions.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700192 xml::XmlNodeAction meta_data_action;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700193
Adam Lesinski86d67df2017-01-31 13:47:27 -0800194 // Common <uses-feature> actions.
195 xml::XmlNodeAction uses_feature_action;
196 uses_feature_action.Action(VerifyUsesFeature);
197
198 // Common component actions.
199 xml::XmlNodeAction component_action;
200 component_action.Action(RequiredNameIsJavaClassName);
201 component_action["intent-filter"] = intent_filter_action;
202 component_action["meta-data"] = meta_data_action;
203
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700204 // Manifest actions.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700205 xml::XmlNodeAction& manifest_action = (*executor)["manifest"];
206 manifest_action.Action(VerifyManifest);
207 manifest_action.Action(FixCoreAppAttribute);
208 manifest_action.Action([&](xml::Element* el) -> bool {
209 if (options_.version_name_default) {
210 if (el->FindAttribute(xml::kSchemaAndroid, "versionName") == nullptr) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700211 el->attributes.push_back(
212 xml::Attribute{xml::kSchemaAndroid, "versionName",
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700213 options_.version_name_default.value()});
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700214 }
Adam Lesinskicc5609d2016-04-05 12:41:07 -0700215 }
216
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700217 if (options_.version_code_default) {
218 if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700219 el->attributes.push_back(
220 xml::Attribute{xml::kSchemaAndroid, "versionCode",
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700221 options_.version_code_default.value()});
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700222 }
Adam Lesinskicc5609d2016-04-05 12:41:07 -0700223 }
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800224 return true;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700225 });
226
227 // Meta tags.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700228 manifest_action["eat-comment"];
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700229
230 // Uses-sdk actions.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700231 manifest_action["uses-sdk"].Action([&](xml::Element* el) -> bool {
232 if (options_.min_sdk_version_default &&
233 el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion") == nullptr) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700234 // There was no minSdkVersion defined and we have a default to assign.
235 el->attributes.push_back(
236 xml::Attribute{xml::kSchemaAndroid, "minSdkVersion",
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700237 options_.min_sdk_version_default.value()});
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700238 }
239
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700240 if (options_.target_sdk_version_default &&
241 el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion") == nullptr) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700242 // There was no targetSdkVersion defined and we have a default to assign.
243 el->attributes.push_back(
244 xml::Attribute{xml::kSchemaAndroid, "targetSdkVersion",
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700245 options_.target_sdk_version_default.value()});
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700246 }
247 return true;
248 });
249
250 // Instrumentation actions.
Adam Lesinski86d67df2017-01-31 13:47:27 -0800251 manifest_action["instrumentation"].Action(RequiredNameIsJavaClassName);
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700252 manifest_action["instrumentation"].Action([&](xml::Element* el) -> bool {
253 if (!options_.rename_instrumentation_target_package) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700254 return true;
255 }
256
257 if (xml::Attribute* attr =
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700258 el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) {
259 attr->value = options_.rename_instrumentation_target_package.value();
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700260 }
261 return true;
262 });
Adam Lesinski86d67df2017-01-31 13:47:27 -0800263 manifest_action["instrumentation"]["meta-data"] = meta_data_action;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700264
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700265 manifest_action["original-package"];
266 manifest_action["protected-broadcast"];
267 manifest_action["uses-permission"];
268 manifest_action["permission"];
269 manifest_action["permission-tree"];
270 manifest_action["permission-group"];
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700271 manifest_action["uses-configuration"];
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700272 manifest_action["supports-screens"];
Adam Lesinski86d67df2017-01-31 13:47:27 -0800273 manifest_action["uses-feature"] = uses_feature_action;
274 manifest_action["feature-group"]["uses-feature"] = uses_feature_action;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700275 manifest_action["compatible-screens"];
276 manifest_action["compatible-screens"]["screen"];
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700277 manifest_action["supports-gl-texture"];
Adam Lesinski5119e512016-12-05 19:48:20 -0800278 manifest_action["meta-data"] = meta_data_action;
279
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700280 // Application actions.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700281 xml::XmlNodeAction& application_action = manifest_action["application"];
282 application_action.Action(OptionalNameIsJavaClassName);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700283
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -0800284 application_action["uses-library"].Action(RequiredNameIsJavaPackage);
285 application_action["library"].Action(RequiredNameIsJavaPackage);
Adam Lesinskib5dc4bd2017-02-22 19:29:29 -0800286
287 xml::XmlNodeAction& static_library_action = application_action["static-library"];
288 static_library_action.Action(RequiredNameIsJavaPackage);
289 static_library_action.Action(RequiredAndroidAttribute("version"));
290
291 xml::XmlNodeAction& uses_static_library_action = application_action["uses-static-library"];
292 uses_static_library_action.Action(RequiredNameIsJavaPackage);
293 uses_static_library_action.Action(RequiredAndroidAttribute("version"));
294 uses_static_library_action.Action(RequiredAndroidAttribute("certDigest"));
295
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700296 application_action["meta-data"] = meta_data_action;
Adam Lesinski86d67df2017-01-31 13:47:27 -0800297 application_action["activity"] = component_action;
298 application_action["activity-alias"] = component_action;
299 application_action["service"] = component_action;
300 application_action["receiver"] = component_action;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700301
302 // Provider actions.
Adam Lesinski86d67df2017-01-31 13:47:27 -0800303 application_action["provider"] = component_action;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700304 application_action["provider"]["grant-uri-permissions"];
305 application_action["provider"]["path-permissions"];
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700306
307 return true;
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800308}
309
Adam Lesinski52364f72016-01-11 13:10:24 -0800310class FullyQualifiedClassNameVisitor : public xml::Visitor {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700311 public:
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700312 using xml::Visitor::Visit;
Adam Lesinski52364f72016-01-11 13:10:24 -0800313
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700314 explicit FullyQualifiedClassNameVisitor(const StringPiece& package)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700315 : package_(package) {}
Adam Lesinski52364f72016-01-11 13:10:24 -0800316
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700317 void Visit(xml::Element* el) override {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700318 for (xml::Attribute& attr : el->attributes) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700319 if (attr.namespace_uri == xml::kSchemaAndroid &&
320 class_attributes_.find(attr.name) != class_attributes_.end()) {
321 if (Maybe<std::string> new_value =
322 util::GetFullyQualifiedClassName(package_, attr.value)) {
323 attr.value = std::move(new_value.value());
Adam Lesinski52364f72016-01-11 13:10:24 -0800324 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700325 }
Adam Lesinski52364f72016-01-11 13:10:24 -0800326 }
327
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700328 // Super implementation to iterate over the children.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700329 xml::Visitor::Visit(el);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700330 }
331
332 private:
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700333 StringPiece package_;
334 std::unordered_set<StringPiece> class_attributes_ = {"name"};
Adam Lesinski52364f72016-01-11 13:10:24 -0800335};
336
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700337static bool RenameManifestPackage(const StringPiece& package_override,
338 xml::Element* manifest_el) {
339 xml::Attribute* attr = manifest_el->FindAttribute({}, "package");
Adam Lesinski52364f72016-01-11 13:10:24 -0800340
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700341 // We've already verified that the manifest element is present, with a package
342 // name specified.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700343 CHECK(attr != nullptr);
Adam Lesinski52364f72016-01-11 13:10:24 -0800344
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700345 std::string original_package = std::move(attr->value);
Adam Lesinskid5083f62017-01-16 15:07:21 -0800346 attr->value = package_override.to_string();
Adam Lesinski52364f72016-01-11 13:10:24 -0800347
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700348 FullyQualifiedClassNameVisitor visitor(original_package);
349 manifest_el->Accept(&visitor);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700350 return true;
Adam Lesinski52364f72016-01-11 13:10:24 -0800351}
352
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700353bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) {
354 xml::Element* root = xml::FindRootElement(doc->root.get());
355 if (!root || !root->namespace_uri.empty() || root->name != "manifest") {
356 context->GetDiagnostics()->Error(DiagMessage(doc->file.source)
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700357 << "root tag must be <manifest>");
358 return false;
359 }
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800360
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700361 if ((options_.min_sdk_version_default ||
362 options_.target_sdk_version_default) &&
363 root->FindChild({}, "uses-sdk") == nullptr) {
Adam Lesinskie343eb12016-10-27 16:31:58 -0700364 // Auto insert a <uses-sdk> element. This must be inserted before the
365 // <application> tag. The device runtime PackageParser will make SDK version
366 // decisions while parsing <application>.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700367 std::unique_ptr<xml::Element> uses_sdk = util::make_unique<xml::Element>();
368 uses_sdk->name = "uses-sdk";
Adam Lesinskie343eb12016-10-27 16:31:58 -0700369 root->InsertChild(0, std::move(uses_sdk));
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700370 }
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800371
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700372 xml::XmlActionExecutor executor;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700373 if (!BuildRules(&executor, context->GetDiagnostics())) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700374 return false;
375 }
Adam Lesinskicc5609d2016-04-05 12:41:07 -0700376
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700377 if (!executor.Execute(xml::XmlActionExecutorPolicy::kWhitelist,
378 context->GetDiagnostics(), doc)) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700379 return false;
380 }
Adam Lesinskicc5609d2016-04-05 12:41:07 -0700381
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700382 if (options_.rename_manifest_package) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700383 // Rename manifest package outside of the XmlActionExecutor.
Adam Lesinskie343eb12016-10-27 16:31:58 -0700384 // We need to extract the old package name and FullyQualify all class
385 // names.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700386 if (!RenameManifestPackage(options_.rename_manifest_package.value(),
387 root)) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700388 return false;
Adam Lesinskicc5609d2016-04-05 12:41:07 -0700389 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700390 }
391 return true;
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800392}
393
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700394} // namespace aapt