12ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski/*
22ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski * Copyright (C) 2015 The Android Open Source Project
32ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski *
42ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
52ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski * you may not use this file except in compliance with the License.
62ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski * You may obtain a copy of the License at
72ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski *
82ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
92ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski *
102ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski * Unless required by applicable law or agreed to in writing, software
112ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
122ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski * See the License for the specific language governing permissions and
142ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski * limitations under the License.
152ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski */
162ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski
172ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski#include "ResourceUtils.h"
182ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski#include "link/ManifestFixer.h"
192ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski#include "util/Util.h"
20cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski#include "xml/XmlActionExecutor.h"
21467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski#include "xml/XmlDom.h"
222ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski
232ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinskinamespace aapt {
242ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski
25cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski/**
26cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski * This is how PackageManager builds class names from AndroidManifest.xml entries.
27cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski */
28cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinskistatic bool nameIsJavaClassName(xml::Element* el, xml::Attribute* attr,
29cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                                SourcePathDiagnostics* diag) {
30cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    std::u16string className = attr->value;
31cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    if (className.find(u'.') == std::u16string::npos) {
32cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        // There is no '.', so add one to the beginning.
33cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        className = u".";
34cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        className += attr->value;
3552364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    }
3652364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
37cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // We allow unqualified class names (ie: .HelloActivity)
38cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Since we don't know the package name, we can just make a fake one here and
39cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // the test will be identical as long as the real package name is valid too.
40cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    Maybe<std::u16string> fullyQualifiedClassName =
41cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            util::getFullyQualifiedClassName(u"a", className);
42cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
43cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    StringPiece16 qualifiedClassName = fullyQualifiedClassName
44cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            ? fullyQualifiedClassName.value() : className;
45cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    if (!util::isJavaClassName(qualifiedClassName)) {
46cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        diag->error(DiagMessage(el->lineNumber)
47cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                    << "attribute 'android:name' in <"
48cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                    << el->name << "> tag must be a valid Java class name");
49cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return false;
502ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski    }
51cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    return true;
52cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski}
532ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski
54cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinskistatic bool optionalNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) {
55cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    if (xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, u"name")) {
56cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return nameIsJavaClassName(el, attr, diag);
57cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    }
5852364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    return true;
5952364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski}
6052364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
61cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinskistatic bool requiredNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) {
62cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    if (xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, u"name")) {
63cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return nameIsJavaClassName(el, attr, diag);
6452364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    }
65cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    diag->error(DiagMessage(el->lineNumber)
66cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                << "<" << el->name << "> is missing attribute 'android:name'");
67cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    return false;
68cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski}
6952364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
70cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinskistatic bool verifyManifest(xml::Element* el, SourcePathDiagnostics* diag) {
71cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    xml::Attribute* attr = el->findAttribute({}, u"package");
72cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    if (!attr) {
73cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        diag->error(DiagMessage(el->lineNumber) << "<manifest> tag is missing 'package' attribute");
74cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return false;
75cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    } else if (ResourceUtils::isReference(attr->value)) {
76cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        diag->error(DiagMessage(el->lineNumber)
77cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                    << "attribute 'package' in <manifest> tag must not be a reference");
78cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return false;
79cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    } else if (!util::isJavaPackageName(attr->value)) {
80cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        diag->error(DiagMessage(el->lineNumber)
81cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                    << "attribute 'package' in <manifest> tag is not a valid Java package name: '"
82cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                    << attr->value << "'");
83cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return false;
84cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    }
8552364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    return true;
862ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski}
872ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski
88cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinskibool ManifestFixer::buildRules(xml::XmlActionExecutor* executor, IDiagnostics* diag) {
89cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // First verify some options.
90cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    if (mOptions.renameManifestPackage) {
91cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        if (!util::isJavaPackageName(mOptions.renameManifestPackage.value())) {
92cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            diag->error(DiagMessage() << "invalid manifest package override '"
93cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                        << mOptions.renameManifestPackage.value() << "'");
94cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            return false;
95cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        }
962ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski    }
972ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski
98cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    if (mOptions.renameInstrumentationTargetPackage) {
99cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        if (!util::isJavaPackageName(mOptions.renameInstrumentationTargetPackage.value())) {
100cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            diag->error(DiagMessage() << "invalid instrumentation target package override '"
101cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                        << mOptions.renameInstrumentationTargetPackage.value() << "'");
102cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            return false;
103cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        }
1042ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski    }
105cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
106cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Common intent-filter actions.
107cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    xml::XmlNodeAction intentFilterAction;
108cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    intentFilterAction[u"action"];
109cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    intentFilterAction[u"category"];
110cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    intentFilterAction[u"data"];
111cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
112cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Common meta-data actions.
113cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    xml::XmlNodeAction metaDataAction;
114cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
115cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Manifest actions.
116cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    xml::XmlNodeAction& manifestAction = (*executor)[u"manifest"];
117cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction.action(verifyManifest);
118cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction.action([&](xml::Element* el) -> bool {
119cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        if (mOptions.versionNameDefault) {
120cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            if (el->findAttribute(xml::kSchemaAndroid, u"versionName") == nullptr) {
121cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                el->attributes.push_back(xml::Attribute{
122cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                        xml::kSchemaAndroid,
123cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                        u"versionName",
124cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                        mOptions.versionNameDefault.value() });
125cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            }
126cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        }
127cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
128cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        if (mOptions.versionCodeDefault) {
129cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            if (el->findAttribute(xml::kSchemaAndroid, u"versionCode") == nullptr) {
130cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                el->attributes.push_back(xml::Attribute{
131cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                        xml::kSchemaAndroid,
132cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                        u"versionCode",
133cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                        mOptions.versionCodeDefault.value() });
134cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            }
135cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        }
136cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return true;
137cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    });
138cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
1395ff3ad6312086b87439bd8d3438a4476e2c14946Adam Lesinski    // Meta tags.
1405ff3ad6312086b87439bd8d3438a4476e2c14946Adam Lesinski    manifestAction[u"eat-comment"];
1415ff3ad6312086b87439bd8d3438a4476e2c14946Adam Lesinski
142cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Uses-sdk actions.
143cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"uses-sdk"].action([&](xml::Element* el) -> bool {
144cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        if (mOptions.minSdkVersionDefault &&
145cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                el->findAttribute(xml::kSchemaAndroid, u"minSdkVersion") == nullptr) {
146cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            // There was no minSdkVersion defined and we have a default to assign.
147cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            el->attributes.push_back(xml::Attribute{
148cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                    xml::kSchemaAndroid, u"minSdkVersion",
149cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                    mOptions.minSdkVersionDefault.value() });
150cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        }
151cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
152cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        if (mOptions.targetSdkVersionDefault &&
153cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                el->findAttribute(xml::kSchemaAndroid, u"targetSdkVersion") == nullptr) {
154cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            // There was no targetSdkVersion defined and we have a default to assign.
155cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            el->attributes.push_back(xml::Attribute{
156cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                    xml::kSchemaAndroid, u"targetSdkVersion",
157cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                    mOptions.targetSdkVersionDefault.value() });
158cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        }
159cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return true;
160cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    });
161cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
162cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Instrumentation actions.
163cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"instrumentation"].action([&](xml::Element* el) -> bool {
164cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        if (!mOptions.renameInstrumentationTargetPackage) {
165cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            return true;
166cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        }
167cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
168cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        if (xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, u"targetPackage")) {
169cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            attr->value = mOptions.renameInstrumentationTargetPackage.value();
170cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        }
171cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return true;
172cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    });
173cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
1745ff3ad6312086b87439bd8d3438a4476e2c14946Adam Lesinski    manifestAction[u"original-package"];
175c728c3daba5754467ef0c42a83247fdb4be1a4dbAdam Lesinski    manifestAction[u"protected-broadcast"];
176cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"uses-permission"];
177cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"permission"];
178cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"permission-tree"];
179cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"permission-group"];
180cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
181cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"uses-configuration"];
182cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"uses-feature"];
183cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"uses-library"];
184cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"supports-screens"];
185cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"compatible-screens"];
186cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    manifestAction[u"supports-gl-texture"];
187cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
188cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Application actions.
189cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    xml::XmlNodeAction& applicationAction = (*executor)[u"manifest"][u"application"];
190cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction.action(optionalNameIsJavaClassName);
191cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
192cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Activity actions.
193cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"activity"].action(requiredNameIsJavaClassName);
194cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"activity"][u"intent-filter"] = intentFilterAction;
195cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"activity"][u"meta-data"] = metaDataAction;
196cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
197cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Activity alias actions.
198cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"activity-alias"][u"intent-filter"] = intentFilterAction;
199cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"activity-alias"][u"meta-data"] = metaDataAction;
200cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
201cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Service actions.
202cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"service"].action(requiredNameIsJavaClassName);
203cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"service"][u"intent-filter"] = intentFilterAction;
204cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"service"][u"meta-data"] = metaDataAction;
205cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
206cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Receiver actions.
207cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"receiver"].action(requiredNameIsJavaClassName);
208cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"receiver"][u"intent-filter"] = intentFilterAction;
209cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"receiver"][u"meta-data"] = metaDataAction;
210cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski
211cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    // Provider actions.
212cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"provider"].action(requiredNameIsJavaClassName);
213cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"provider"][u"grant-uri-permissions"];
214cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"provider"][u"meta-data"] = metaDataAction;
215cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    applicationAction[u"provider"][u"path-permissions"];
2162ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski    return true;
2172ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski}
2182ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski
21952364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinskiclass FullyQualifiedClassNameVisitor : public xml::Visitor {
22052364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinskipublic:
22152364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    using xml::Visitor::visit;
22252364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
22352364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    FullyQualifiedClassNameVisitor(const StringPiece16& package) : mPackage(package) {
22452364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    }
22552364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
22652364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    void visit(xml::Element* el) override {
22752364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski        for (xml::Attribute& attr : el->attributes) {
22852364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski            if (Maybe<std::u16string> newValue =
22952364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski                    util::getFullyQualifiedClassName(mPackage, attr.value)) {
23052364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski                attr.value = std::move(newValue.value());
23152364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski            }
23252364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski        }
23352364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
23452364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski        // Super implementation to iterate over the children.
23552364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski        xml::Visitor::visit(el);
23652364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    }
23752364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
23852364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinskiprivate:
23952364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    StringPiece16 mPackage;
24052364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski};
24152364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
242cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinskistatic bool renameManifestPackage(const StringPiece16& packageOverride, xml::Element* manifestEl) {
24352364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    xml::Attribute* attr = manifestEl->findAttribute({}, u"package");
24452364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
24552364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    // We've already verified that the manifest element is present, with a package name specified.
24652364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    assert(attr);
24752364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
24852364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    std::u16string originalPackage = std::move(attr->value);
24952364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    attr->value = packageOverride.toString();
25052364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
25152364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    FullyQualifiedClassNameVisitor visitor(originalPackage);
25252364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    manifestEl->accept(&visitor);
25352364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    return true;
25452364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski}
25552364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
256467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinskibool ManifestFixer::consume(IAaptContext* context, xml::XmlResource* doc) {
2572ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski    xml::Element* root = xml::findRootElement(doc->root.get());
2582ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski    if (!root || !root->namespaceUri.empty() || root->name != u"manifest") {
2592ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski        context->getDiagnostics()->error(DiagMessage(doc->file.source)
2602ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski                                         << "root tag must be <manifest>");
2612ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski        return false;
2622ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski    }
2632ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski
264cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    if ((mOptions.minSdkVersionDefault || mOptions.targetSdkVersionDefault)
265cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski            && root->findChild({}, u"uses-sdk") == nullptr) {
266cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        // Auto insert a <uses-sdk> element.
267cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        std::unique_ptr<xml::Element> usesSdk = util::make_unique<xml::Element>();
268cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        usesSdk->name = u"uses-sdk";
269cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        root->addChild(std::move(usesSdk));
2702ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski    }
2712ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski
272cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    xml::XmlActionExecutor executor;
273cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    if (!buildRules(&executor, context->getDiagnostics())) {
274cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return false;
27552364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    }
27652364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
277cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski    if (!executor.execute(xml::XmlActionExecutorPolicy::Whitelist, context->getDiagnostics(),
278cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski                          doc)) {
279cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        return false;
28052364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    }
28152364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
28252364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    if (mOptions.renameManifestPackage) {
283cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        // Rename manifest package outside of the XmlActionExecutor.
284cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        // We need to extract the old package name and FullyQualify all class names.
285cc5609d8e484ec82ef1dced793af7f674f059b1cAdam Lesinski        if (!renameManifestPackage(mOptions.renameManifestPackage.value(), root)) {
28652364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski            return false;
28752364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski        }
28852364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    }
2892ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski    return true;
2902ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski}
2912ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski
2922ae4a877d1623f851040ce69239552c873f1abf0Adam Lesinski} // namespace aapt
293