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 "test/Test.h"
20 
21 using ::android::StringPiece;
22 using ::testing::Eq;
23 using ::testing::Gt;
24 using ::testing::IsNull;
25 using ::testing::Ne;
26 using ::testing::NotNull;
27 using ::testing::StrEq;
28 
29 namespace aapt {
30 
31 struct ManifestFixerTest : public ::testing::Test {
32   std::unique_ptr<IAaptContext> mContext;
33 
SetUpaapt::ManifestFixerTest34   void SetUp() override {
35     mContext =
36         test::ContextBuilder()
37             .SetCompilationPackage("android")
38             .SetPackageId(0x01)
39             .SetNameManglerPolicy(NameManglerPolicy{"android"})
40             .AddSymbolSource(
41                 test::StaticSymbolSourceBuilder()
42                     .AddSymbol(
43                         "android:attr/package", ResourceId(0x01010000),
44                         test::AttributeBuilder()
45                             .SetTypeMask(android::ResTable_map::TYPE_STRING)
46                             .Build())
47                     .AddSymbol(
48                         "android:attr/minSdkVersion", ResourceId(0x01010001),
49                         test::AttributeBuilder()
50                             .SetTypeMask(android::ResTable_map::TYPE_STRING |
51                                          android::ResTable_map::TYPE_INTEGER)
52                             .Build())
53                     .AddSymbol(
54                         "android:attr/targetSdkVersion", ResourceId(0x01010002),
55                         test::AttributeBuilder()
56                             .SetTypeMask(android::ResTable_map::TYPE_STRING |
57                                          android::ResTable_map::TYPE_INTEGER)
58                             .Build())
59                     .AddSymbol("android:string/str", ResourceId(0x01060000))
60                     .Build())
61             .Build();
62   }
63 
Verifyaapt::ManifestFixerTest64   std::unique_ptr<xml::XmlResource> Verify(const StringPiece& str) {
65     return VerifyWithOptions(str, {});
66   }
67 
VerifyWithOptionsaapt::ManifestFixerTest68   std::unique_ptr<xml::XmlResource> VerifyWithOptions(
69       const StringPiece& str, const ManifestFixerOptions& options) {
70     std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(str);
71     ManifestFixer fixer(options);
72     if (fixer.Consume(mContext.get(), doc.get())) {
73       return doc;
74     }
75     return {};
76   }
77 };
78 
TEST_F(ManifestFixerTest,EnsureManifestIsRootTag)79 TEST_F(ManifestFixerTest, EnsureManifestIsRootTag) {
80   EXPECT_THAT(Verify("<other-tag />"), IsNull());
81   EXPECT_THAT(Verify("<ns:manifest xmlns:ns=\"com\" />"), IsNull());
82   EXPECT_THAT(Verify("<manifest package=\"android\"></manifest>"), NotNull());
83 }
84 
TEST_F(ManifestFixerTest,EnsureManifestHasPackage)85 TEST_F(ManifestFixerTest, EnsureManifestHasPackage) {
86   EXPECT_THAT(Verify("<manifest package=\"android\" />"), NotNull());
87   EXPECT_THAT(Verify("<manifest package=\"com.android\" />"), NotNull());
88   EXPECT_THAT(Verify("<manifest package=\"com.android.google\" />"), NotNull());
89   EXPECT_THAT(Verify("<manifest package=\"com.android.google.Class$1\" />"), IsNull());
90   EXPECT_THAT(Verify("<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" "
91                      "android:package=\"com.android\" />"),
92               IsNull());
93   EXPECT_THAT(Verify("<manifest package=\"@string/str\" />"), IsNull());
94 }
95 
TEST_F(ManifestFixerTest,AllowMetaData)96 TEST_F(ManifestFixerTest, AllowMetaData) {
97   auto doc = Verify(R"EOF(
98         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
99                   package="android">
100           <meta-data />
101           <application>
102             <meta-data />
103             <activity android:name=".Hi"><meta-data /></activity>
104             <activity-alias android:name=".Ho"><meta-data /></activity-alias>
105             <receiver android:name=".OffTo"><meta-data /></receiver>
106             <provider android:name=".Work"><meta-data /></provider>
107             <service android:name=".We"><meta-data /></service>
108           </application>
109           <instrumentation android:name=".Go"><meta-data /></instrumentation>
110         </manifest>)EOF");
111   ASSERT_THAT(doc, NotNull());
112 }
113 
114 TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) {
115   ManifestFixerOptions options;
116   options.min_sdk_version_default = std::string("8");
117   options.target_sdk_version_default = std::string("22");
118 
119   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
120       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
121                 package="android">
122         <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" />
123       </manifest>)EOF",
124                                                             options);
125   ASSERT_THAT(doc, NotNull());
126 
127   xml::Element* el;
128   xml::Attribute* attr;
129 
130   el = doc->root.get();
131   ASSERT_THAT(el, NotNull());
132   el = el->FindChild({}, "uses-sdk");
133   ASSERT_THAT(el, NotNull());
134   attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
135   ASSERT_THAT(attr, NotNull());
136   EXPECT_THAT(attr->value, StrEq("7"));
137   attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
138   ASSERT_THAT(attr, NotNull());
139   EXPECT_THAT(attr->value, StrEq("21"));
140 
141   doc = VerifyWithOptions(R"EOF(
142       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
143                 package="android">
144         <uses-sdk android:targetSdkVersion="21" />
145       </manifest>)EOF",
146                           options);
147   ASSERT_THAT(doc, NotNull());
148 
149   el = doc->root.get();
150   ASSERT_THAT(el, NotNull());
151   el = el->FindChild({}, "uses-sdk");
152   ASSERT_THAT(el, NotNull());
153   attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
154   ASSERT_THAT(attr, NotNull());
155   EXPECT_THAT(attr->value, StrEq("8"));
156   attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
157   ASSERT_THAT(attr, NotNull());
158   EXPECT_THAT(attr->value, StrEq("21"));
159 
160   doc = VerifyWithOptions(R"EOF(
161       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
162                 package="android">
163         <uses-sdk />
164       </manifest>)EOF",
165                           options);
166   ASSERT_THAT(doc, NotNull());
167 
168   el = doc->root.get();
169   ASSERT_THAT(el, NotNull());
170   el = el->FindChild({}, "uses-sdk");
171   ASSERT_THAT(el, NotNull());
172   attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
173   ASSERT_THAT(attr, NotNull());
174   EXPECT_THAT(attr->value, StrEq("8"));
175   attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
176   ASSERT_THAT(attr, NotNull());
177   EXPECT_THAT(attr->value, StrEq("22"));
178 
179   doc = VerifyWithOptions(R"EOF(
180       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
181                 package="android" />)EOF",
182                           options);
183   ASSERT_THAT(doc, NotNull());
184 
185   el = doc->root.get();
186   ASSERT_THAT(el, NotNull());
187   el = el->FindChild({}, "uses-sdk");
188   ASSERT_THAT(el, NotNull());
189   attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
190   ASSERT_THAT(attr, NotNull());
191   EXPECT_THAT(attr->value, StrEq("8"));
192   attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
193   ASSERT_THAT(attr, NotNull());
194   EXPECT_THAT(attr->value, StrEq("22"));
195 }
196 
197 TEST_F(ManifestFixerTest, UsesSdkMustComeBeforeApplication) {
198   ManifestFixerOptions options;
199   options.min_sdk_version_default = std::string("8");
200   options.target_sdk_version_default = std::string("22");
201   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
202           <manifest xmlns:android="http://schemas.android.com/apk/res/android"
203                     package="android">
204             <application android:name=".MainApplication" />
205           </manifest>)EOF",
206                                                             options);
207   ASSERT_THAT(doc, NotNull());
208 
209   xml::Element* manifest_el = doc->root.get();
210   ASSERT_THAT(manifest_el, NotNull());
211   ASSERT_EQ("manifest", manifest_el->name);
212 
213   xml::Element* application_el = manifest_el->FindChild("", "application");
214   ASSERT_THAT(application_el, NotNull());
215 
216   xml::Element* uses_sdk_el = manifest_el->FindChild("", "uses-sdk");
217   ASSERT_THAT(uses_sdk_el, NotNull());
218 
219   // Check that the uses_sdk_el comes before application_el in the children
220   // vector.
221   // Since there are no namespaces here, these children are direct descendants
222   // of manifest.
223   auto uses_sdk_iter =
224       std::find_if(manifest_el->children.begin(), manifest_el->children.end(),
225                    [&](const std::unique_ptr<xml::Node>& child) {
226                      return child.get() == uses_sdk_el;
227                    });
228 
229   auto application_iter =
230       std::find_if(manifest_el->children.begin(), manifest_el->children.end(),
231                    [&](const std::unique_ptr<xml::Node>& child) {
232                      return child.get() == application_el;
233                    });
234 
235   ASSERT_THAT(uses_sdk_iter, Ne(manifest_el->children.end()));
236   ASSERT_THAT(application_iter, Ne(manifest_el->children.end()));
237 
238   // The distance should be positive, meaning uses_sdk_iter comes before
239   // application_iter.
240   EXPECT_THAT(std::distance(uses_sdk_iter, application_iter), Gt(0));
241 }
242 
243 TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) {
244   ManifestFixerOptions options;
245   options.rename_manifest_package = std::string("com.android");
246 
247   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
248       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
249                 package="android">
250         <uses-split android:name="feature_a" />
251         <application android:name=".MainApplication" text="hello">
252           <activity android:name=".activity.Start" />
253           <receiver android:name="com.google.android.Receiver" />
254         </application>
255       </manifest>)EOF",
256                                                             options);
257   ASSERT_THAT(doc, NotNull());
258 
259   xml::Element* manifest_el = doc->root.get();
260   ASSERT_THAT(manifest_el, NotNull());
261 
262   xml::Attribute* attr = nullptr;
263 
264   attr = manifest_el->FindAttribute({}, "package");
265   ASSERT_THAT(attr, NotNull());
266   EXPECT_THAT(attr->value, StrEq("com.android"));
267 
268   xml::Element* uses_split_el = manifest_el->FindChild({}, "uses-split");
269   ASSERT_THAT(uses_split_el, NotNull());
270   attr = uses_split_el->FindAttribute(xml::kSchemaAndroid, "name");
271   ASSERT_THAT(attr, NotNull());
272   // This should NOT have been affected.
273   EXPECT_THAT(attr->value, StrEq("feature_a"));
274 
275   xml::Element* application_el = manifest_el->FindChild({}, "application");
276   ASSERT_THAT(application_el, NotNull());
277 
278   attr = application_el->FindAttribute(xml::kSchemaAndroid, "name");
279   ASSERT_THAT(attr, NotNull());
280   EXPECT_THAT(attr->value, StrEq("android.MainApplication"));
281 
282   attr = application_el->FindAttribute({}, "text");
283   ASSERT_THAT(attr, NotNull());
284   EXPECT_THAT(attr->value, StrEq("hello"));
285 
286   xml::Element* el;
287   el = application_el->FindChild({}, "activity");
288   ASSERT_THAT(el, NotNull());
289 
290   attr = el->FindAttribute(xml::kSchemaAndroid, "name");
291   ASSERT_THAT(el, NotNull());
292   EXPECT_THAT(attr->value, StrEq("android.activity.Start"));
293 
294   el = application_el->FindChild({}, "receiver");
295   ASSERT_THAT(el, NotNull());
296 
297   attr = el->FindAttribute(xml::kSchemaAndroid, "name");
298   ASSERT_THAT(el, NotNull());
299   EXPECT_THAT(attr->value, StrEq("com.google.android.Receiver"));
300 }
301 
302 TEST_F(ManifestFixerTest,
303        RenameManifestInstrumentationPackageAndFullyQualifyTarget) {
304   ManifestFixerOptions options;
305   options.rename_instrumentation_target_package = std::string("com.android");
306 
307   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
308       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
309                 package="android">
310         <instrumentation android:name=".TestRunner" android:targetPackage="android" />
311       </manifest>)EOF",
312                                                             options);
313   ASSERT_THAT(doc, NotNull());
314 
315   xml::Element* manifest_el = doc->root.get();
316   ASSERT_THAT(manifest_el, NotNull());
317 
318   xml::Element* instrumentation_el =
319       manifest_el->FindChild({}, "instrumentation");
320   ASSERT_THAT(instrumentation_el, NotNull());
321 
322   xml::Attribute* attr =
323       instrumentation_el->FindAttribute(xml::kSchemaAndroid, "targetPackage");
324   ASSERT_THAT(attr, NotNull());
325   EXPECT_THAT(attr->value, StrEq("com.android"));
326 }
327 
328 TEST_F(ManifestFixerTest,
329        RenameManifestOverlayPackageAndFullyQualifyTarget) {
330   ManifestFixerOptions options;
331   options.rename_overlay_target_package = std::string("com.android");
332 
333   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
334       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
335                 package="android">
336         <overlay android:targetName="Customization" android:targetPackage="android" />
337       </manifest>)EOF",
338                                                             options);
339   ASSERT_THAT(doc, NotNull());
340 
341   xml::Element* manifest_el = doc->root.get();
342   ASSERT_THAT(manifest_el, NotNull());
343 
344   xml::Element* overlay_el =
345       manifest_el->FindChild({}, "overlay");
346   ASSERT_THAT(overlay_el, NotNull());
347 
348   xml::Attribute* attr =
349       overlay_el->FindAttribute(xml::kSchemaAndroid, "targetPackage");
350   ASSERT_THAT(attr, NotNull());
351   EXPECT_THAT(attr->value, StrEq("com.android"));
352 }
353 
354 TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) {
355   ManifestFixerOptions options;
356   options.version_name_default = std::string("Beta");
357   options.version_code_default = std::string("0x10000000");
358   options.version_code_major_default = std::string("0x20000000");
359 
360   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
361       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
362                 package="android" />)EOF",
363                                                             options);
364   ASSERT_THAT(doc, NotNull());
365 
366   xml::Element* manifest_el = doc->root.get();
367   ASSERT_THAT(manifest_el, NotNull());
368 
369   xml::Attribute* attr =
370       manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
371   ASSERT_THAT(attr, NotNull());
372   EXPECT_THAT(attr->value, StrEq("Beta"));
373 
374   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
375   ASSERT_THAT(attr, NotNull());
376   EXPECT_THAT(attr->value, StrEq("0x10000000"));
377 
378   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
379   ASSERT_THAT(attr, NotNull());
380   EXPECT_THAT(attr->value, StrEq("0x20000000"));
381 }
382 
383 TEST_F(ManifestFixerTest, DontUseDefaultVersionNameAndCode) {
384   ManifestFixerOptions options;
385   options.version_name_default = std::string("Beta");
386   options.version_code_default = std::string("0x10000000");
387   options.version_code_major_default = std::string("0x20000000");
388 
389   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
390         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
391                   package="android"
392                   android:versionCode="0x00000001"
393                   android:versionCodeMajor="0x00000002"
394                   android:versionName="Alpha" />)EOF",
395                                                             options);
396   ASSERT_THAT(doc, NotNull());
397 
398   xml::Element* manifest_el = doc->root.get();
399   ASSERT_THAT(manifest_el, NotNull());
400 
401   xml::Attribute* attr =
402       manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
403   ASSERT_THAT(attr, NotNull());
404   EXPECT_THAT(attr->value, StrEq("Alpha"));
405 
406   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
407   ASSERT_THAT(attr, NotNull());
408   EXPECT_THAT(attr->value, StrEq("0x00000001"));
409 
410   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
411   ASSERT_THAT(attr, NotNull());
412   EXPECT_THAT(attr->value, StrEq("0x00000002"));
413 }
414 
415 TEST_F(ManifestFixerTest, ReplaceVersionNameAndCode) {
416   ManifestFixerOptions options;
417   options.replace_version = true;
418   options.version_name_default = std::string("Beta");
419   options.version_code_default = std::string("0x10000000");
420   options.version_code_major_default = std::string("0x20000000");
421 
422   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
423       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
424                 package="android"
425                 android:versionCode="0x00000001"
426                 android:versionCodeMajor="0x00000002"
427                 android:versionName="Alpha" />)EOF",
428                                                             options);
429   ASSERT_THAT(doc, NotNull());
430 
431   xml::Element* manifest_el = doc->root.get();
432   ASSERT_THAT(manifest_el, NotNull());
433 
434   xml::Attribute* attr =
435       manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
436   ASSERT_THAT(attr, NotNull());
437   EXPECT_THAT(attr->value, StrEq("Beta"));
438 
439   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
440   ASSERT_THAT(attr, NotNull());
441   EXPECT_THAT(attr->value, StrEq("0x10000000"));
442 
443   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
444   ASSERT_THAT(attr, NotNull());
445   EXPECT_THAT(attr->value, StrEq("0x20000000"));
446 }
447 
448 TEST_F(ManifestFixerTest, UseDefaultRevisionCode) {
449   ManifestFixerOptions options;
450   options.revision_code_default = std::string("0x10000000");
451 
452   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
453       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
454                 package="android"
455                 android:versionCode="0x00000001" />)EOF",
456                                                             options);
457   ASSERT_THAT(doc, NotNull());
458 
459   xml::Element* manifest_el = doc->root.get();
460   ASSERT_THAT(manifest_el, NotNull());
461 
462   xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode");
463   ASSERT_THAT(attr, NotNull());
464   EXPECT_THAT(attr->value, StrEq("0x10000000"));
465 }
466 
467 TEST_F(ManifestFixerTest, DontUseDefaultRevisionCode) {
468   ManifestFixerOptions options;
469   options.revision_code_default = std::string("0x10000000");
470 
471   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
472         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
473                   package="android"
474                   android:versionCode="0x00000001"
475                   android:revisionCode="0x00000002" />)EOF",
476                                                             options);
477   ASSERT_THAT(doc, NotNull());
478 
479   xml::Element* manifest_el = doc->root.get();
480   ASSERT_THAT(manifest_el, NotNull());
481 
482   xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode");
483   ASSERT_THAT(attr, NotNull());
484   EXPECT_THAT(attr->value, StrEq("0x00000002"));
485 }
486 
487 TEST_F(ManifestFixerTest, ReplaceRevisionCode) {
488   ManifestFixerOptions options;
489   options.replace_version = true;
490   options.revision_code_default = std::string("0x10000000");
491 
492   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
493         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
494                   package="android"
495                   android:versionCode="0x00000001"
496                   android:revisionCode="0x00000002" />)EOF",
497                                                             options);
498   ASSERT_THAT(doc, NotNull());
499 
500   xml::Element* manifest_el = doc->root.get();
501   ASSERT_THAT(manifest_el, NotNull());
502 
503   xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode");
504   ASSERT_THAT(attr, NotNull());
505   EXPECT_THAT(attr->value, StrEq("0x10000000"));
506 }
507 
508 TEST_F(ManifestFixerTest, ReplaceVersionName) {
509   ManifestFixerOptions options;
510   options.replace_version = true;
511   options.version_name_default = std::string("Beta");
512 
513 
514   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
515     <manifest xmlns:android="http://schemas.android.com/apk/res/android"
516               package="android"
517               android:versionCode="0x00000001"
518               android:versionCodeMajor="0x00000002"
519               android:versionName="Alpha" />)EOF",
520                                                             options);
521   ASSERT_THAT(doc, NotNull());
522 
523   xml::Element* manifest_el = doc->root.get();
524   ASSERT_THAT(manifest_el, NotNull());
525 
526   xml::Attribute* attr =
527       manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
528   ASSERT_THAT(attr, NotNull());
529   EXPECT_THAT(attr->value, StrEq("Beta"));
530 
531   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
532   ASSERT_THAT(attr, NotNull());
533   EXPECT_THAT(attr->value, StrEq("0x00000001"));
534 
535   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
536   ASSERT_THAT(attr, NotNull());
537   EXPECT_THAT(attr->value, StrEq("0x00000002"));
538 }
539 
540 TEST_F(ManifestFixerTest, ReplaceVersionCode) {
541   ManifestFixerOptions options;
542   options.replace_version = true;
543   options.version_code_default = std::string("0x10000000");
544 
545   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
546     <manifest xmlns:android="http://schemas.android.com/apk/res/android"
547               package="android"
548               android:versionCode="0x00000001"
549               android:versionCodeMajor="0x00000002"
550               android:versionName="Alpha" />)EOF",
551                                                             options);
552   ASSERT_THAT(doc, NotNull());
553 
554   xml::Element* manifest_el = doc->root.get();
555   ASSERT_THAT(manifest_el, NotNull());
556 
557   xml::Attribute* attr =
558       manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
559   ASSERT_THAT(attr, NotNull());
560   EXPECT_THAT(attr->value, StrEq("Alpha"));
561 
562   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
563   ASSERT_THAT(attr, NotNull());
564   EXPECT_THAT(attr->value, StrEq("0x10000000"));
565 
566   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
567   ASSERT_THAT(attr, NotNull());
568   EXPECT_THAT(attr->value, StrEq("0x00000002"));
569 }
570 
571 TEST_F(ManifestFixerTest, ReplaceVersionCodeMajor) {
572   ManifestFixerOptions options;
573   options.replace_version = true;
574   options.version_code_major_default = std::string("0x20000000");
575 
576   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
577   <manifest xmlns:android="http://schemas.android.com/apk/res/android"
578           package="android"
579           android:versionCode="0x00000001"
580           android:versionCodeMajor="0x00000002"
581           android:versionName="Alpha" />)EOF",
582                                                             options);
583   ASSERT_THAT(doc, NotNull());
584 
585   xml::Element* manifest_el = doc->root.get();
586   ASSERT_THAT(manifest_el, NotNull());
587 
588   xml::Attribute* attr =
589       manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
590   ASSERT_THAT(attr, NotNull());
591   EXPECT_THAT(attr->value, StrEq("Alpha"));
592 
593   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
594   ASSERT_THAT(attr, NotNull());
595   EXPECT_THAT(attr->value, StrEq("0x00000001"));
596 
597   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
598   ASSERT_THAT(attr, NotNull());
599   EXPECT_THAT(attr->value, StrEq("0x20000000"));
600 }
601 
602 TEST_F(ManifestFixerTest, DontReplaceVersionNameOrCode) {
603   ManifestFixerOptions options;
604   options.replace_version = true;
605 
606   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
607   <manifest xmlns:android="http://schemas.android.com/apk/res/android"
608             package="android"
609             android:versionCode="0x00000001"
610             android:versionCodeMajor="0x00000002"
611             android:versionName="Alpha" />)EOF",
612                                                             options);
613   ASSERT_THAT(doc, NotNull());
614 
615   xml::Element* manifest_el = doc->root.get();
616   ASSERT_THAT(manifest_el, NotNull());
617 
618   xml::Attribute* attr =
619       manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
620   ASSERT_THAT(attr, NotNull());
621   EXPECT_THAT(attr->value, StrEq("Alpha"));
622 
623   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
624   ASSERT_THAT(attr, NotNull());
625   EXPECT_THAT(attr->value, StrEq("0x00000001"));
626 
627   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
628   ASSERT_THAT(attr, NotNull());
629   EXPECT_THAT(attr->value, StrEq("0x00000002"));
630 }
631 
632 TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) {
633   EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"hello\" />"), IsNull());
634   EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"1dp\" />"), IsNull());
635 
636   std::unique_ptr<xml::XmlResource> doc =
637       Verify("<manifest package=\"android\" coreApp=\"true\" />");
638   ASSERT_THAT(doc, NotNull());
639 
640   xml::Element* el = doc->root.get();
641   ASSERT_THAT(el, NotNull());
642 
643   EXPECT_THAT(el->name, StrEq("manifest"));
644 
645   xml::Attribute* attr = el->FindAttribute("", "coreApp");
646   ASSERT_THAT(attr, NotNull());
647 
648   EXPECT_THAT(attr->compiled_value, NotNull());
649   EXPECT_THAT(ValueCast<BinaryPrimitive>(attr->compiled_value.get()), NotNull());
650 }
651 
TEST_F(ManifestFixerTest,UsesFeatureMustHaveNameOrGlEsVersion)652 TEST_F(ManifestFixerTest, UsesFeatureMustHaveNameOrGlEsVersion) {
653   std::string input = R"EOF(
654         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
655                   package="android">
656           <uses-feature android:name="feature" />
657           <uses-feature android:glEsVersion="1" />
658           <feature-group />
659           <feature-group>
660             <uses-feature android:name="feature_in_group" />
661             <uses-feature android:glEsVersion="2" />
662           </feature-group>
663         </manifest>)EOF";
664   EXPECT_THAT(Verify(input), NotNull());
665 
666   input = R"EOF(
667         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
668                   package="android">
669           <uses-feature android:name="feature" android:glEsVersion="1" />
670         </manifest>)EOF";
671   EXPECT_THAT(Verify(input), IsNull());
672 
673   input = R"EOF(
674         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
675                   package="android">
676           <uses-feature />
677         </manifest>)EOF";
678   EXPECT_THAT(Verify(input), IsNull());
679 
680   input = R"EOF(
681         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
682                   package="android">
683           <feature-group>
684             <uses-feature android:name="feature" android:glEsVersion="1" />
685           </feature-group>
686         </manifest>)EOF";
687   EXPECT_THAT(Verify(input), IsNull());
688 
689   input = R"EOF(
690         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
691                   package="android">
692           <feature-group>
693             <uses-feature />
694           </feature-group>
695         </manifest>)EOF";
696   EXPECT_THAT(Verify(input), IsNull());
697 }
698 
699 TEST_F(ManifestFixerTest, ApplicationInjectDebuggable) {
700   ManifestFixerOptions options;
701   options.debug_mode = true;
702 
703   std::string no_d = R"(
704       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
705           package="android">
706         <application>
707         </application>
708       </manifest>)";
709 
710   std::string false_d = R"(
711       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
712           package="android">
713         <application android:debuggable="false">
714         </application>
715       </manifest>)";
716 
717   std::string true_d = R"(
718       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
719           package="android">
720         <application android:debuggable="true">
721         </application>
722       </manifest>)";
723 
724   // Inject the debuggable attribute when the attribute is not present and the
725   // flag is present
726   std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(no_d, options);
727   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
728       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
729 
730   // Set the debuggable flag to true if the attribute is false and the flag is
731   // present
732   manifest = VerifyWithOptions(false_d, options);
733   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
734       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
735 
736   // Keep debuggable flag true if the attribute is true and the flag is present
737   manifest = VerifyWithOptions(true_d, options);
738   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
739       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
740 
741   // Do not inject the debuggable attribute when the attribute is not present
742   // and the flag is not present
743   manifest = Verify(no_d);
744   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
745       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), IsNull());
746 
747   // Do not set the debuggable flag to true if the attribute is false and the
748   // flag is not present
749   manifest = Verify(false_d);
750   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
751       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), IsNull());
752 
753   // Keep debuggable flag true if the attribute is true and the flag is not
754   // present
755   manifest = Verify(true_d);
756   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
757       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
758 }
759 
760 TEST_F(ManifestFixerTest, ApplicationProfileable) {
761   std::string shell = R"(
762       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
763           package="android">
764         <application>
765           <profileable android:shell="true"/>
766         </application>
767       </manifest>)";
768   EXPECT_THAT(Verify(shell), NotNull());
769   std::string noshell = R"(
770       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
771           package="android">
772         <application>
773           <profileable/>
774         </application>
775       </manifest>)";
776   EXPECT_THAT(Verify(noshell), NotNull());
777 }
778 
779 TEST_F(ManifestFixerTest, IgnoreNamespacedElements) {
780   std::string input = R"EOF(
781       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
782                 package="android">
783         <special:tag whoo="true" xmlns:special="http://google.com" />
784       </manifest>)EOF";
785   EXPECT_THAT(Verify(input), NotNull());
786 }
787 
788 TEST_F(ManifestFixerTest, DoNotIgnoreNonNamespacedElements) {
789   std::string input = R"EOF(
790       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
791                 package="android">
792         <tag whoo="true" />
793       </manifest>)EOF";
794   EXPECT_THAT(Verify(input), IsNull());
795 }
796 
797 TEST_F(ManifestFixerTest, SupportKeySets) {
798   std::string input = R"(
799       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
800           package="android">
801         <key-sets>
802           <key-set android:name="old-set">
803             <public-key android:name="old-key" android:value="some+old+key" />
804           </key-set>
805           <key-set android:name="new-set">
806             <public-key android:name="new-key" android:value="some+new+key" />
807           </key-set>
808           <upgrade-key-set android:name="old-set" />
809           <upgrade-key-set android:name="new-set" />
810         </key-sets>
811       </manifest>)";
812   EXPECT_THAT(Verify(input), NotNull());
813 }
814 
815 TEST_F(ManifestFixerTest, InsertCompileSdkVersions) {
816   std::string input = R"(<manifest package="com.pkg" />)";
817   ManifestFixerOptions options;
818   options.compile_sdk_version = {"28"};
819   options.compile_sdk_version_codename = {"P"};
820 
821   std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
822   ASSERT_THAT(manifest, NotNull());
823 
824   // There should be a declaration of kSchemaAndroid, even when the input
825   // didn't have one.
826   EXPECT_EQ(manifest->root->namespace_decls.size(), 1);
827   EXPECT_EQ(manifest->root->namespace_decls[0].prefix, "android");
828   EXPECT_EQ(manifest->root->namespace_decls[0].uri, xml::kSchemaAndroid);
829 
830   xml::Attribute* attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersion");
831   ASSERT_THAT(attr, NotNull());
832   EXPECT_THAT(attr->value, StrEq("28"));
833 
834   attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename");
835   ASSERT_THAT(attr, NotNull());
836   EXPECT_THAT(attr->value, StrEq("P"));
837 
838   attr = manifest->root->FindAttribute("", "platformBuildVersionCode");
839   ASSERT_THAT(attr, NotNull());
840   EXPECT_THAT(attr->value, StrEq("28"));
841 
842   attr = manifest->root->FindAttribute("", "platformBuildVersionName");
843   ASSERT_THAT(attr, NotNull());
844   EXPECT_THAT(attr->value, StrEq("P"));
845 }
846 
847 TEST_F(ManifestFixerTest, OverrideCompileSdkVersions) {
848   std::string input = R"(
849       <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"
850           compileSdkVersion="27" compileSdkVersionCodename="O"
851           platformBuildVersionCode="27" platformBuildVersionName="O"/>)";
852   ManifestFixerOptions options;
853   options.compile_sdk_version = {"28"};
854   options.compile_sdk_version_codename = {"P"};
855 
856   std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
857   ASSERT_THAT(manifest, NotNull());
858 
859   xml::Attribute* attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersion");
860   ASSERT_THAT(attr, NotNull());
861   EXPECT_THAT(attr->value, StrEq("28"));
862 
863   attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename");
864   ASSERT_THAT(attr, NotNull());
865   EXPECT_THAT(attr->value, StrEq("P"));
866 
867   attr = manifest->root->FindAttribute("", "platformBuildVersionCode");
868   ASSERT_THAT(attr, NotNull());
869   EXPECT_THAT(attr->value, StrEq("28"));
870 
871   attr = manifest->root->FindAttribute("", "platformBuildVersionName");
872   ASSERT_THAT(attr, NotNull());
873   EXPECT_THAT(attr->value, StrEq("P"));
874 }
875 
876 TEST_F(ManifestFixerTest, AndroidPrefixAlreadyUsed) {
877   std::string input =
878       R"(<manifest package="com.pkg"
879          xmlns:android="http://schemas.android.com/apk/prv/res/android"
880          android:private_attr="foo" />)";
881   ManifestFixerOptions options;
882   options.compile_sdk_version = {"28"};
883   options.compile_sdk_version_codename = {"P"};
884 
885   std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
886   ASSERT_THAT(manifest, NotNull());
887 
888   // Make sure that we don't redefine "android".
889   EXPECT_EQ(manifest->root->namespace_decls.size(), 2);
890   EXPECT_EQ(manifest->root->namespace_decls[0].prefix, "android");
891   EXPECT_EQ(manifest->root->namespace_decls[0].uri,
892             "http://schemas.android.com/apk/prv/res/android");
893   EXPECT_EQ(manifest->root->namespace_decls[1].prefix, "android0");
894   EXPECT_EQ(manifest->root->namespace_decls[1].uri, xml::kSchemaAndroid);
895 }
896 
TEST_F(ManifestFixerTest,UnexpectedElementsInManifest)897 TEST_F(ManifestFixerTest, UnexpectedElementsInManifest) {
898   std::string input = R"(
899       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
900           package="android">
901         <beep/>
902       </manifest>)";
903   ManifestFixerOptions options;
904   options.warn_validation = true;
905 
906   // Unexpected element should result in a warning if the flag is set to 'true'.
907   std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
908   ASSERT_THAT(manifest, NotNull());
909 
910   // Unexpected element should result in an error if the flag is set to 'false'.
911   options.warn_validation = false;
912   manifest = VerifyWithOptions(input, options);
913   ASSERT_THAT(manifest, IsNull());
914 
915   // By default the flag should be set to 'false'.
916   manifest = Verify(input);
917   ASSERT_THAT(manifest, IsNull());
918 }
919 
920 TEST_F(ManifestFixerTest, UsesLibraryMustHaveNonEmptyName) {
921   std::string input = R"(
922       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
923           package="android">
924         <application>
925           <uses-library android:name="" />
926         </application>
927       </manifest>)";
928   EXPECT_THAT(Verify(input), IsNull());
929 
930   input = R"(
931       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
932           package="android">
933         <application>
934           <uses-library />
935         </application>
936       </manifest>)";
937   EXPECT_THAT(Verify(input), IsNull());
938 
939   input = R"(
940        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
941            package="android">
942          <application>
943            <uses-library android:name="blahhh" />
944          </application>
945        </manifest>)";
946   EXPECT_THAT(Verify(input), NotNull());
947 }
948 
949 TEST_F(ManifestFixerTest, ApplicationPropertyAttributeRequired) {
950   std::string input = R"(
951       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
952           package="android">
953         <application>
954           <property android:name="" />
955         </application>
956       </manifest>)";
957   EXPECT_THAT(Verify(input), IsNull());
958 }
959 
960 TEST_F(ManifestFixerTest, ApplicationPropertyOnlyOneAttributeDefined) {
961   std::string input = R"(
962       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
963           package="android">
964         <application>
965           <property android:name="" android:value="" android:resource="" />
966         </application>
967       </manifest>)";
968   EXPECT_THAT(Verify(input), IsNull());
969 
970   input = R"(
971       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
972           package="android">
973         <application>
974           <property android:name="" android:resource="" />
975         </application>
976       </manifest>)";
977   EXPECT_THAT(Verify(input), NotNull());
978 
979   input = R"(
980       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
981           package="android">
982         <application>
983           <property android:name="" android:value="" />
984         </application>
985       </manifest>)";
986   EXPECT_THAT(Verify(input), NotNull());
987 }
988 
989 TEST_F(ManifestFixerTest, ComponentPropertyOnlyOneAttributeDefined) {
990   std::string input = R"(
991       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
992           package="android">
993         <application>
994           <activity android:name=".MyActivity">
995             <property android:name="" android:value="" android:resource="" />
996           </activity>
997         </application>
998       </manifest>)";
999   EXPECT_THAT(Verify(input), IsNull());
1000 
1001   input = R"(
1002       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
1003           package="android">
1004         <application>
1005           <activity android:name=".MyActivity">
1006             <property android:name="" android:value="" />
1007           </activity>
1008         </application>
1009       </manifest>)";
1010   EXPECT_THAT(Verify(input), NotNull());
1011 
1012   input = R"(
1013       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
1014           package="android">
1015         <application>
1016           <activity android:name=".MyActivity">
1017             <property android:name="" android:resource="" />
1018           </activity>
1019         </application>
1020       </manifest>)";
1021   EXPECT_THAT(Verify(input), NotNull());
1022 }
1023 }  // namespace aapt
1024