blob: d1e6d3922f3f278d426de47ecdbc7b063722b4b3 [file] [log] [blame]
Ryan Mitchell479fa392019-01-02 17:15:39 -08001/*
2 * Copyright (C) 2018 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.h"
18
Ryan Mitchell5855de72021-02-24 14:39:13 -080019#include <android-base/file.h>
20
21#include "AppInfo.h"
Ryan Mitchell479fa392019-01-02 17:15:39 -080022#include "LoadedApk.h"
23#include "test/Test.h"
24
25using testing::Eq;
Ryan Mitchell5855de72021-02-24 14:39:13 -080026using testing::HasSubstr;
Ryan Mitchell479fa392019-01-02 17:15:39 -080027using testing::Ne;
Ryan Mitchell2e9bec12021-03-22 09:31:00 -070028using testing::NotNull;
Ryan Mitchell479fa392019-01-02 17:15:39 -080029
30namespace aapt {
31
32using LinkTest = CommandTestFixture;
33
34TEST_F(LinkTest, RemoveRawXmlStrings) {
35 StdErrDiagnostics diag;
36 const std::string compiled_files_dir = GetTestPath("compiled");
37 ASSERT_TRUE(CompileFile(GetTestPath("res/xml/test.xml"), R"(<Item AgentCode="007"/>)",
38 compiled_files_dir, &diag));
39
40 const std::string out_apk = GetTestPath("out.apk");
41 std::vector<std::string> link_args = {
42 "--manifest", GetDefaultManifest(),
43 "-o", out_apk,
44 };
45
46 ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
47
48 // Load the binary xml tree
49 android::ResXMLTree tree;
50 std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
Ryan Mitchell1d008d12021-03-19 14:54:17 -070051 ASSERT_THAT(apk, Ne(nullptr));
52
Winsonb7be7932019-01-23 11:10:52 -080053 std::unique_ptr<io::IData> data = OpenFileAsData(apk.get(), "res/xml/test.xml");
54 ASSERT_THAT(data, Ne(nullptr));
Winsonb7be7932019-01-23 11:10:52 -080055 AssertLoadXml(apk.get(), data.get(), &tree);
Ryan Mitchell479fa392019-01-02 17:15:39 -080056
57 // Check that the raw string index has not been assigned
58 EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(-1));
59}
60
61TEST_F(LinkTest, KeepRawXmlStrings) {
62 StdErrDiagnostics diag;
63 const std::string compiled_files_dir = GetTestPath("compiled");
64 ASSERT_TRUE(CompileFile(GetTestPath("res/xml/test.xml"), R"(<Item AgentCode="007"/>)",
65 compiled_files_dir, &diag));
66
67 const std::string out_apk = GetTestPath("out.apk");
68 std::vector<std::string> link_args = {
69 "--manifest", GetDefaultManifest(),
70 "-o", out_apk,
71 "--keep-raw-values"
72 };
73
74 ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
75
76 // Load the binary xml tree
77 android::ResXMLTree tree;
78 std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
Ryan Mitchell1d008d12021-03-19 14:54:17 -070079 ASSERT_THAT(apk, Ne(nullptr));
80
Winsonb7be7932019-01-23 11:10:52 -080081 std::unique_ptr<io::IData> data = OpenFileAsData(apk.get(), "res/xml/test.xml");
82 ASSERT_THAT(data, Ne(nullptr));
Winsonb7be7932019-01-23 11:10:52 -080083 AssertLoadXml(apk.get(), data.get(), &tree);
Ryan Mitchell479fa392019-01-02 17:15:39 -080084
85 // Check that the raw string index has been set to the correct string pool entry
86 int32_t raw_index = tree.getAttributeValueStringID(0);
87 ASSERT_THAT(raw_index, Ne(-1));
88 EXPECT_THAT(util::GetString(tree.getStrings(), static_cast<size_t>(raw_index)), Eq("007"));
89}
90
Ryan Mitchell81dfca02019-06-07 10:20:27 -070091TEST_F(LinkTest, NoCompressAssets) {
92 StdErrDiagnostics diag;
93 std::string content(500, 'a');
94 WriteFile(GetTestPath("assets/testtxt"), content);
95 WriteFile(GetTestPath("assets/testtxt2"), content);
96 WriteFile(GetTestPath("assets/test.txt"), content);
97 WriteFile(GetTestPath("assets/test.hello.txt"), content);
98 WriteFile(GetTestPath("assets/test.hello.xml"), content);
99
100 const std::string out_apk = GetTestPath("out.apk");
101 std::vector<std::string> link_args = {
102 "--manifest", GetDefaultManifest(),
103 "-o", out_apk,
104 "-0", ".txt",
105 "-0", "txt2",
106 "-0", ".hello.txt",
107 "-0", "hello.xml",
108 "-A", GetTestPath("assets")
109 };
110
111 ASSERT_TRUE(Link(link_args, &diag));
112
113 std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
114 ASSERT_THAT(apk, Ne(nullptr));
115 io::IFileCollection* zip = apk->GetFileCollection();
116 ASSERT_THAT(zip, Ne(nullptr));
117
118 auto file = zip->FindFile("assets/testtxt");
119 ASSERT_THAT(file, Ne(nullptr));
120 EXPECT_TRUE(file->WasCompressed());
121
122 file = zip->FindFile("assets/testtxt2");
123 ASSERT_THAT(file, Ne(nullptr));
124 EXPECT_FALSE(file->WasCompressed());
125
126 file = zip->FindFile("assets/test.txt");
127 ASSERT_THAT(file, Ne(nullptr));
128 EXPECT_FALSE(file->WasCompressed());
129
130 file = zip->FindFile("assets/test.hello.txt");
131 ASSERT_THAT(file, Ne(nullptr));
132 EXPECT_FALSE(file->WasCompressed());
133
134 file = zip->FindFile("assets/test.hello.xml");
135 ASSERT_THAT(file, Ne(nullptr));
136 EXPECT_FALSE(file->WasCompressed());
137}
138
139TEST_F(LinkTest, NoCompressResources) {
140 StdErrDiagnostics diag;
141 std::string content(500, 'a');
142 const std::string compiled_files_dir = GetTestPath("compiled");
143 ASSERT_TRUE(CompileFile(GetTestPath("res/raw/testtxt"), content, compiled_files_dir, &diag));
144 ASSERT_TRUE(CompileFile(GetTestPath("res/raw/test.txt"), content, compiled_files_dir, &diag));
145 ASSERT_TRUE(CompileFile(GetTestPath("res/raw/test1.hello.txt"), content, compiled_files_dir,
146 &diag));
147 ASSERT_TRUE(CompileFile(GetTestPath("res/raw/test2.goodbye.xml"), content, compiled_files_dir,
148 &diag));
149
150 const std::string out_apk = GetTestPath("out.apk");
151 std::vector<std::string> link_args = {
152 "--manifest", GetDefaultManifest(),
153 "-o", out_apk,
154 "-0", ".txt",
155 "-0", ".hello.txt",
156 "-0", "goodbye.xml",
157 };
158
159 ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
160
161 std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
162 ASSERT_THAT(apk, Ne(nullptr));
163 io::IFileCollection* zip = apk->GetFileCollection();
164 ASSERT_THAT(zip, Ne(nullptr));
165
166 auto file = zip->FindFile("res/raw/testtxt");
167 ASSERT_THAT(file, Ne(nullptr));
168 EXPECT_TRUE(file->WasCompressed());
169
170 file = zip->FindFile("res/raw/test.txt");
171 ASSERT_THAT(file, Ne(nullptr));
172 EXPECT_FALSE(file->WasCompressed());
173
174 file = zip->FindFile("res/raw/test1.hello.hello.txt");
175 ASSERT_THAT(file, Ne(nullptr));
176 EXPECT_FALSE(file->WasCompressed());
177
178 file = zip->FindFile("res/raw/test2.goodbye.goodbye.xml");
179 ASSERT_THAT(file, Ne(nullptr));
180 EXPECT_FALSE(file->WasCompressed());
181}
182
Donald Chai121c6e82019-06-12 12:51:57 -0700183TEST_F(LinkTest, OverlayStyles) {
184 StdErrDiagnostics diag;
185 const std::string compiled_files_dir = GetTestPath("compiled");
186 const std::string override_files_dir = GetTestPath("compiled-override");
187 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"),
188 R"(<resources>
189 <style name="MyStyle">
190 <item name="android:textColor">#123</item>
191 </style>
192 </resources>)",
193 compiled_files_dir, &diag));
194 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values-override.xml"),
195 R"(<resources>
196 <style name="MyStyle">
197 <item name="android:background">#456</item>
198 </style>
199 </resources>)",
200 override_files_dir, &diag));
201
202
203 const std::string out_apk = GetTestPath("out.apk");
204 std::vector<std::string> link_args = {
205 "--manifest", GetDefaultManifest(kDefaultPackageName),
206 "-o", out_apk,
207 };
208 const auto override_files = file::FindFiles(override_files_dir, &diag);
209 for (const auto &override_file : override_files.value()) {
210 link_args.push_back("-R");
211 link_args.push_back(file::BuildPath({override_files_dir, override_file}));
212 }
213 ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
214
215 std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
Ryan Mitchell1d008d12021-03-19 14:54:17 -0700216 ASSERT_THAT(apk, Ne(nullptr));
217
Donald Chai121c6e82019-06-12 12:51:57 -0700218 const Style* actual_style = test::GetValue<Style>(
219 apk->GetResourceTable(), std::string(kDefaultPackageName) + ":style/MyStyle");
220 ASSERT_NE(actual_style, nullptr);
221 ASSERT_EQ(actual_style->entries.size(), 2);
222 EXPECT_EQ(actual_style->entries[0].key.id, 0x01010098); // android:textColor
223 EXPECT_EQ(actual_style->entries[1].key.id, 0x010100d4); // android:background
224}
225
226TEST_F(LinkTest, OverrideStylesInsteadOfOverlaying) {
227 StdErrDiagnostics diag;
228 const std::string compiled_files_dir = GetTestPath("compiled");
229 const std::string override_files_dir = GetTestPath("compiled-override");
230 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"),
231 R"(<resources>
232 <style name="MyStyle">
233 <item name="android:textColor">#123</item>
234 </style>
235 </resources>)",
236 compiled_files_dir, &diag));
237 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values-override.xml"),
238 R"(<resources>
239 <style name="MyStyle">
240 <item name="android:background">#456</item>
241 </style>
242 </resources>)",
243 override_files_dir, &diag));
244
245
246 const std::string out_apk = GetTestPath("out.apk");
247 std::vector<std::string> link_args = {
248 "--manifest", GetDefaultManifest(kDefaultPackageName),
249 "--override-styles-instead-of-overlaying",
250 "-o", out_apk,
251 };
252 const auto override_files = file::FindFiles(override_files_dir, &diag);
253 for (const auto &override_file : override_files.value()) {
254 link_args.push_back("-R");
255 link_args.push_back(file::BuildPath({override_files_dir, override_file}));
256 }
257 ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
258
259 std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
Ryan Mitchell1d008d12021-03-19 14:54:17 -0700260 ASSERT_THAT(apk, Ne(nullptr));
261
Donald Chai121c6e82019-06-12 12:51:57 -0700262 const Style* actual_style = test::GetValue<Style>(
263 apk->GetResourceTable(), std::string(kDefaultPackageName) + ":style/MyStyle");
264 ASSERT_NE(actual_style, nullptr);
265 ASSERT_EQ(actual_style->entries.size(), 1);
266 EXPECT_EQ(actual_style->entries[0].key.id, 0x010100d4); // android:background
267}
268
Udam Sainib228df32019-06-18 16:50:34 -0700269TEST_F(LinkTest, AppInfoWithUsesSplit) {
270 StdErrDiagnostics diag;
271 const std::string base_files_dir = GetTestPath("base");
272 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"),
273 R"(<resources>
274 <string name="bar">bar</string>
275 </resources>)",
276 base_files_dir, &diag));
277 const std::string base_apk = GetTestPath("base.apk");
278 std::vector<std::string> link_args = {
279 "--manifest", GetDefaultManifest("com.aapt2.app"),
280 "-o", base_apk,
281 };
282 ASSERT_TRUE(Link(link_args, base_files_dir, &diag));
283
284 const std::string feature_manifest = GetTestPath("feature_manifest.xml");
285 WriteFile(feature_manifest, android::base::StringPrintf(R"(
286 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
287 package="com.aapt2.app" split="feature1">
288 </manifest>)"));
289 const std::string feature_files_dir = GetTestPath("feature");
290 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"),
291 R"(<resources>
292 <string name="foo">foo</string>
293 </resources>)",
294 feature_files_dir, &diag));
295 const std::string feature_apk = GetTestPath("feature.apk");
296 const std::string feature_package_id = "0x80";
297 link_args = {
298 "--manifest", feature_manifest,
299 "-I", base_apk,
300 "--package-id", feature_package_id,
301 "-o", feature_apk,
302 };
303 ASSERT_TRUE(Link(link_args, feature_files_dir, &diag));
304
305 const std::string feature2_manifest = GetTestPath("feature2_manifest.xml");
306 WriteFile(feature2_manifest, android::base::StringPrintf(R"(
307 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
308 package="com.aapt2.app" split="feature2">
309 <uses-split android:name="feature1"/>
310 </manifest>)"));
311 const std::string feature2_files_dir = GetTestPath("feature2");
312 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"),
313 R"(<resources>
314 <string-array name="string_array">
315 <item>@string/bar</item>
316 <item>@string/foo</item>
317 </string-array>
318 </resources>)",
319 feature2_files_dir, &diag));
320 const std::string feature2_apk = GetTestPath("feature2.apk");
321 const std::string feature2_package_id = "0x81";
322 link_args = {
323 "--manifest", feature2_manifest,
324 "-I", base_apk,
325 "-I", feature_apk,
326 "--package-id", feature2_package_id,
327 "-o", feature2_apk,
328 };
329 ASSERT_TRUE(Link(link_args, feature2_files_dir, &diag));
330}
331
Ryan Mitchell5855de72021-02-24 14:39:13 -0800332TEST_F(LinkTest, SharedLibraryAttributeRJava) {
333 StdErrDiagnostics diag;
334 const std::string lib_values =
335 R"(<resources>
336 <attr name="foo"/>
337 <public type="attr" name="foo" id="0x00010001"/>
338 <declare-styleable name="LibraryStyleable">
339 <attr name="foo" />
340 </declare-styleable>
341 </resources>)";
342
343 const std::string client_values =
344 R"(<resources>
345 <attr name="bar" />
346 <declare-styleable name="ClientStyleable">
347 <attr name="com.example.lib:foo" />
348 <attr name="bar" />
349 </declare-styleable>
350 </resources>)";
351
352 // Build a library with a public attribute
353 const std::string lib_res = GetTestPath("library-res");
354 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"), lib_values, lib_res, &diag));
355
356 const std::string lib_apk = GetTestPath("library.apk");
357 const std::string lib_java = GetTestPath("library_java");
358 // clang-format off
359 auto lib_manifest = ManifestBuilder(this)
360 .SetPackageName("com.example.lib")
361 .Build();
362
363 auto lib_link_args = LinkCommandBuilder(this)
364 .SetManifestFile(lib_manifest)
365 .AddFlag("--shared-lib")
366 .AddParameter("--java", lib_java)
367 .AddCompiledResDir(lib_res, &diag)
368 .Build(lib_apk);
369 // clang-format on
370 ASSERT_TRUE(Link(lib_link_args, &diag));
371
372 const std::string lib_r_java = lib_java + "/com/example/lib/R.java";
373 std::string lib_r_contents;
374 ASSERT_TRUE(android::base::ReadFileToString(lib_r_java, &lib_r_contents));
375 EXPECT_THAT(lib_r_contents, HasSubstr(" public static int foo=0x00010001;"));
376 EXPECT_THAT(lib_r_contents, HasSubstr(" com.example.lib.R.attr.foo"));
377
378 // Build a client that uses the library attribute in a declare-styleable
379 const std::string client_res = GetTestPath("client-res");
380 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"), client_values, client_res, &diag));
381
382 const std::string client_apk = GetTestPath("client.apk");
383 const std::string client_java = GetTestPath("client_java");
384 // clang-format off
385 auto client_manifest = ManifestBuilder(this)
386 .SetPackageName("com.example.client")
387 .Build();
388
389 auto client_link_args = LinkCommandBuilder(this)
390 .SetManifestFile(client_manifest)
391 .AddParameter("--java", client_java)
392 .AddParameter("-I", lib_apk)
393 .AddCompiledResDir(client_res, &diag)
394 .Build(client_apk);
395 // clang-format on
396 ASSERT_TRUE(Link(client_link_args, &diag));
397
398 const std::string client_r_java = client_java + "/com/example/client/R.java";
399 std::string client_r_contents;
400 ASSERT_TRUE(android::base::ReadFileToString(client_r_java, &client_r_contents));
401 EXPECT_THAT(client_r_contents, HasSubstr(" com.example.lib.R.attr.foo, 0x7f010000"));
402}
403
Ryan Mitchell2e9bec12021-03-22 09:31:00 -0700404TEST_F(LinkTest, StagedAndroidApi) {
405 StdErrDiagnostics diag;
406 const std::string android_values =
407 R"(<resources>
408 <public type="attr" name="finalized_res" id="0x01010001"/>
409
410 <!-- S staged attributes (support staged resources in the same type id) -->
411 <staging-public-group type="attr" first-id="0x01010050">
412 <public name="staged_s_res" />
413 </staging-public-group>
414
415 <!-- SV2 staged attributes (support staged resources in a separate type id) -->
416 <staging-public-group type="attr" first-id="0x01ff0049">
417 <public name="staged_s2_res" />
418 </staging-public-group>
419
420 <!-- T staged attributes (support staged resources in multiple separate type ids) -->
421 <staging-public-group type="attr" first-id="0x01fe0063">
422 <public name="staged_t_res" />
423 </staging-public-group>
424
425 <staging-public-group type="string" first-id="0x01fd0072">
426 <public name="staged_t_string" />
427 </staging-public-group>
428
429 <attr name="finalized_res" />
430 <attr name="staged_s_res" />
431 <attr name="staged_s2_res" />
432 <attr name="staged_t_res" />
433 <string name="staged_t_string">Hello</string>
434 </resources>)";
435
436 const std::string app_values =
437 R"(<resources xmlns:android="http://schemas.android.com/apk/res/android">
438 <attr name="bar" />
439 <declare-styleable name="ClientStyleable">
440 <attr name="android:finalized_res" />
441 <attr name="android:staged_s_res" />
442 <attr name="bar" />
443 </declare-styleable>
444 </resources>)";
445
446 const std::string android_res = GetTestPath("android-res");
447 ASSERT_TRUE(
448 CompileFile(GetTestPath("res/values/values.xml"), android_values, android_res, &diag));
449
450 const std::string android_apk = GetTestPath("android.apk");
451 const std::string android_java = GetTestPath("android_java");
452 // clang-format off
453 auto android_manifest = ManifestBuilder(this)
454 .SetPackageName("android")
455 .Build();
456
457 auto android_link_args = LinkCommandBuilder(this)
458 .SetManifestFile(android_manifest)
459 .AddParameter("--private-symbols", "com.android.internal")
460 .AddParameter("--java", android_java)
461 .AddCompiledResDir(android_res, &diag)
462 .Build(android_apk);
463 // clang-format on
464 ASSERT_TRUE(Link(android_link_args, &diag));
465
466 const std::string android_r_java = android_java + "/android/R.java";
467 std::string android_r_contents;
468 ASSERT_TRUE(android::base::ReadFileToString(android_r_java, &android_r_contents));
Ryan Mitchellca3b4f72021-03-29 14:47:02 -0700469 EXPECT_THAT(android_r_contents, HasSubstr("public static final int finalized_res=0x01010001;"));
470 EXPECT_THAT(
471 android_r_contents,
472 HasSubstr("public static final int staged_s_res; static { staged_s_res=0x01010050; }"));
473 EXPECT_THAT(
474 android_r_contents,
475 HasSubstr("public static final int staged_s2_res; static { staged_s2_res=0x01ff0049; }"));
476 EXPECT_THAT(
477 android_r_contents,
478 HasSubstr("public static final int staged_t_res; static { staged_t_res=0x01fe0063; }"));
479 EXPECT_THAT(
480 android_r_contents,
481 HasSubstr("public static final int staged_t_string; static { staged_t_string=0x01fd0072; }"));
Ryan Mitchell2e9bec12021-03-22 09:31:00 -0700482
483 // Build an app that uses the framework attribute in a declare-styleable
484 const std::string client_res = GetTestPath("app-res");
485 ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"), app_values, client_res, &diag));
486
487 const std::string app_apk = GetTestPath("app.apk");
488 const std::string app_java = GetTestPath("app_java");
489 // clang-format off
490 auto app_manifest = ManifestBuilder(this)
491 .SetPackageName("com.example.app")
492 .Build();
493
494 auto app_link_args = LinkCommandBuilder(this)
495 .SetManifestFile(app_manifest)
496 .AddParameter("--java", app_java)
497 .AddParameter("-I", android_apk)
498 .AddCompiledResDir(client_res, &diag)
499 .Build(app_apk);
500 // clang-format on
501 ASSERT_TRUE(Link(app_link_args, &diag));
502
503 const std::string client_r_java = app_java + "/com/example/app/R.java";
504 std::string client_r_contents;
505 ASSERT_TRUE(android::base::ReadFileToString(client_r_java, &client_r_contents));
506 EXPECT_THAT(client_r_contents, HasSubstr(" 0x01010001, android.R.attr.staged_s_res, 0x7f010000"));
507
508 // Test that the resource ids of staged and non-staged resource can be retrieved
509 android::AssetManager2 am;
510 auto android_asset = android::ApkAssets::Load(android_apk);
511 ASSERT_THAT(android_asset, NotNull());
512 ASSERT_TRUE(am.SetApkAssets({android_asset.get()}));
513
514 auto result = am.GetResourceId("android:attr/finalized_res");
515 ASSERT_TRUE(result.has_value());
516 EXPECT_THAT(*result, Eq(0x01010001));
517
518 result = am.GetResourceId("android:attr/staged_s_res");
519 ASSERT_TRUE(result.has_value());
520 EXPECT_THAT(*result, Eq(0x01010050));
521
522 result = am.GetResourceId("android:attr/staged_s2_res");
523 ASSERT_TRUE(result.has_value());
524 EXPECT_THAT(*result, Eq(0x01ff0049));
525
526 result = am.GetResourceId("android:attr/staged_t_res");
527 ASSERT_TRUE(result.has_value());
528 EXPECT_THAT(*result, Eq(0x01fe0063));
529
530 result = am.GetResourceId("android:string/staged_t_string");
531 ASSERT_TRUE(result.has_value());
532 EXPECT_THAT(*result, Eq(0x01fd0072));
533}
534
Donald Chai121c6e82019-06-12 12:51:57 -0700535} // namespace aapt