• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, UseDefaultVersionNameAndCode) {
329   ManifestFixerOptions options;
330   options.version_name_default = std::string("Beta");
331   options.version_code_default = std::string("0x10000000");
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" />)EOF",
336                                                             options);
337   ASSERT_THAT(doc, NotNull());
338 
339   xml::Element* manifest_el = doc->root.get();
340   ASSERT_THAT(manifest_el, NotNull());
341 
342   xml::Attribute* attr =
343       manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
344   ASSERT_THAT(attr, NotNull());
345   EXPECT_THAT(attr->value, StrEq("Beta"));
346 
347   attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
348   ASSERT_THAT(attr, NotNull());
349   EXPECT_THAT(attr->value, StrEq("0x10000000"));
350 }
351 
352 TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) {
353   EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"hello\" />"), IsNull());
354   EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"1dp\" />"), IsNull());
355 
356   std::unique_ptr<xml::XmlResource> doc =
357       Verify("<manifest package=\"android\" coreApp=\"true\" />");
358   ASSERT_THAT(doc, NotNull());
359 
360   xml::Element* el = doc->root.get();
361   ASSERT_THAT(el, NotNull());
362 
363   EXPECT_THAT(el->name, StrEq("manifest"));
364 
365   xml::Attribute* attr = el->FindAttribute("", "coreApp");
366   ASSERT_THAT(attr, NotNull());
367 
368   EXPECT_THAT(attr->compiled_value, NotNull());
369   EXPECT_THAT(ValueCast<BinaryPrimitive>(attr->compiled_value.get()), NotNull());
370 }
371 
TEST_F(ManifestFixerTest,UsesFeatureMustHaveNameOrGlEsVersion)372 TEST_F(ManifestFixerTest, UsesFeatureMustHaveNameOrGlEsVersion) {
373   std::string input = R"EOF(
374         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
375                   package="android">
376           <uses-feature android:name="feature" />
377           <uses-feature android:glEsVersion="1" />
378           <feature-group />
379           <feature-group>
380             <uses-feature android:name="feature_in_group" />
381             <uses-feature android:glEsVersion="2" />
382           </feature-group>
383         </manifest>)EOF";
384   EXPECT_THAT(Verify(input), NotNull());
385 
386   input = R"EOF(
387         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
388                   package="android">
389           <uses-feature android:name="feature" android:glEsVersion="1" />
390         </manifest>)EOF";
391   EXPECT_THAT(Verify(input), IsNull());
392 
393   input = R"EOF(
394         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
395                   package="android">
396           <uses-feature />
397         </manifest>)EOF";
398   EXPECT_THAT(Verify(input), IsNull());
399 
400   input = R"EOF(
401         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
402                   package="android">
403           <feature-group>
404             <uses-feature android:name="feature" android:glEsVersion="1" />
405           </feature-group>
406         </manifest>)EOF";
407   EXPECT_THAT(Verify(input), IsNull());
408 
409   input = R"EOF(
410         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
411                   package="android">
412           <feature-group>
413             <uses-feature />
414           </feature-group>
415         </manifest>)EOF";
416   EXPECT_THAT(Verify(input), IsNull());
417 }
418 
419 TEST_F(ManifestFixerTest, ApplicationInjectDebuggable) {
420   ManifestFixerOptions options;
421   options.debug_mode = true;
422 
423   std::string no_d = R"(
424       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
425           package="android">
426         <application>
427         </application>
428       </manifest>)";
429 
430   std::string false_d = R"(
431       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
432           package="android">
433         <application android:debuggable="false">
434         </application>
435       </manifest>)";
436 
437   std::string true_d = R"(
438       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
439           package="android">
440         <application android:debuggable="true">
441         </application>
442       </manifest>)";
443 
444   // Inject the debuggable attribute when the attribute is not present and the
445   // flag is present
446   std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(no_d, options);
447   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
448       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
449 
450   // Set the debuggable flag to true if the attribute is false and the flag is
451   // present
452   manifest = VerifyWithOptions(false_d, options);
453   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
454       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
455 
456   // Keep debuggable flag true if the attribute is true and the flag is present
457   manifest = VerifyWithOptions(true_d, options);
458   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
459       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
460 
461   // Do not inject the debuggable attribute when the attribute is not present
462   // and the flag is not present
463   manifest = Verify(no_d);
464   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
465       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), IsNull());
466 
467   // Do not set the debuggable flag to true if the attribute is false and the
468   // flag is not present
469   manifest = Verify(false_d);
470   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
471       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), IsNull());
472 
473   // Keep debuggable flag true if the attribute is true and the flag is not
474   // present
475   manifest = Verify(true_d);
476   EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
477       {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
478 }
479 
480 
481 TEST_F(ManifestFixerTest, IgnoreNamespacedElements) {
482   std::string input = R"EOF(
483       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
484                 package="android">
485         <special:tag whoo="true" xmlns:special="http://google.com" />
486       </manifest>)EOF";
487   EXPECT_THAT(Verify(input), NotNull());
488 }
489 
490 TEST_F(ManifestFixerTest, DoNotIgnoreNonNamespacedElements) {
491   std::string input = R"EOF(
492       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
493                 package="android">
494         <tag whoo="true" />
495       </manifest>)EOF";
496   EXPECT_THAT(Verify(input), IsNull());
497 }
498 
499 TEST_F(ManifestFixerTest, SupportKeySets) {
500   std::string input = R"(
501       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
502           package="android">
503         <key-sets>
504           <key-set android:name="old-set">
505             <public-key android:name="old-key" android:value="some+old+key" />
506           </key-set>
507           <key-set android:name="new-set">
508             <public-key android:name="new-key" android:value="some+new+key" />
509           </key-set>
510           <upgrade-key-set android:name="old-set" />
511           <upgrade-key-set android:name="new-set" />
512         </key-sets>
513       </manifest>)";
514   EXPECT_THAT(Verify(input), NotNull());
515 }
516 
517 TEST_F(ManifestFixerTest, InsertCompileSdkVersions) {
518   std::string input = R"(
519       <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" />)";
520   ManifestFixerOptions options;
521   options.compile_sdk_version = {"28"};
522   options.compile_sdk_version_codename = {"P"};
523 
524   std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
525   ASSERT_THAT(manifest, NotNull());
526 
527   xml::Attribute* attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersion");
528   ASSERT_THAT(attr, NotNull());
529   EXPECT_THAT(attr->value, StrEq("28"));
530 
531   attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename");
532   ASSERT_THAT(attr, NotNull());
533   EXPECT_THAT(attr->value, StrEq("P"));
534 }
535 
536 TEST_F(ManifestFixerTest, UnexpectedElementsInManifest) {
537   std::string input = R"(
538       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
539           package="android">
540         <beep/>
541       </manifest>)";
542   ManifestFixerOptions options;
543   options.warn_validation = true;
544 
545   // Unexpected element should result in a warning if the flag is set to 'true'.
546   std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
547   ASSERT_THAT(manifest, NotNull());
548 
549   // Unexpected element should result in an error if the flag is set to 'false'.
550   options.warn_validation = false;
551   manifest = VerifyWithOptions(input, options);
552   ASSERT_THAT(manifest, IsNull());
553 
554   // By default the flag should be set to 'false'.
555   manifest = Verify(input);
556   ASSERT_THAT(manifest, IsNull());
557 }
558 
559 TEST_F(ManifestFixerTest, InsertPlatformBuildVersions) {
560   // Test for insertion when versionCode and versionName are included in the manifest
561   {
562     std::string input = R"(
563         <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"
564           android:versionCode="27" android:versionName="O"/>)";
565     std::unique_ptr<xml::XmlResource> manifest = Verify(input);
566     ASSERT_THAT(manifest, NotNull());
567 
568     xml::Attribute* attr = manifest->root->FindAttribute("", "platformBuildVersionCode");
569     ASSERT_THAT(attr, NotNull());
570     EXPECT_THAT(attr->value, StrEq("27"));
571     attr = manifest->root->FindAttribute("", "platformBuildVersionName");
572     ASSERT_THAT(attr, NotNull());
573     EXPECT_THAT(attr->value, StrEq("O"));
574   }
575 
576   // Test for insertion when versionCode and versionName defaults are specified
577   {
578     std::string input = R"(
579       <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"/>)";
580     ManifestFixerOptions options;
581     options.version_code_default = {"27"};
582     options.version_name_default = {"O"};
583     std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
584     ASSERT_THAT(manifest, NotNull());
585 
586     xml::Attribute* attr = manifest->root->FindAttribute("", "platformBuildVersionCode");
587     ASSERT_THAT(attr, NotNull());
588     EXPECT_THAT(attr->value, StrEq("27"));
589     attr = manifest->root->FindAttribute("", "platformBuildVersionName");
590     ASSERT_THAT(attr, NotNull());
591     EXPECT_THAT(attr->value, StrEq("O"));
592   }
593 
594   // Test that the platform build version attributes are not changed if they are currently present
595   {
596     std::string input = R"(
597         <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"
598           android:versionCode="28" android:versionName="P"
599           platformBuildVersionCode="27" platformBuildVersionName="O"/>)";
600     std::unique_ptr<xml::XmlResource> manifest = Verify(input);
601     ASSERT_THAT(manifest, NotNull());
602 
603     xml::Attribute* attr = manifest->root->FindAttribute("", "platformBuildVersionCode");
604     ASSERT_THAT(attr, NotNull());
605     EXPECT_THAT(attr->value, StrEq("27"));
606     attr = manifest->root->FindAttribute("", "platformBuildVersionName");
607     ASSERT_THAT(attr, NotNull());
608     EXPECT_THAT(attr->value, StrEq("O"));
609   }
610 }
611 
612 TEST_F(ManifestFixerTest, UsesLibraryMustHaveNonEmptyName) {
613   std::string input = R"(
614       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
615           package="android">
616         <application>
617           <uses-library android:name="" />
618         </application>
619       </manifest>)";
620   EXPECT_THAT(Verify(input), IsNull());
621 
622   input = R"(
623       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
624           package="android">
625         <application>
626           <uses-library />
627         </application>
628       </manifest>)";
629   EXPECT_THAT(Verify(input), IsNull());
630 
631   input = R"(
632        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
633            package="android">
634          <application>
635            <uses-library android:name="blahhh" />
636          </application>
637        </manifest>)";
638   EXPECT_THAT(Verify(input), NotNull());
639 }
640 
641 }  // namespace aapt
642