summaryrefslogtreecommitdiff
path: root/tools/aapt2/cmd/Link_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/cmd/Link_test.cpp')
-rw-r--r--tools/aapt2/cmd/Link_test.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp
index 27cbe88fde38..dfdac6b9d93e 100644
--- a/tools/aapt2/cmd/Link_test.cpp
+++ b/tools/aapt2/cmd/Link_test.cpp
@@ -25,6 +25,7 @@
using testing::Eq;
using testing::HasSubstr;
using testing::Ne;
+using testing::NotNull;
namespace aapt {
@@ -400,4 +401,127 @@ TEST_F(LinkTest, SharedLibraryAttributeRJava) {
EXPECT_THAT(client_r_contents, HasSubstr(" com.example.lib.R.attr.foo, 0x7f010000"));
}
+TEST_F(LinkTest, StagedAndroidApi) {
+ StdErrDiagnostics diag;
+ const std::string android_values =
+ R"(<resources>
+ <public type="attr" name="finalized_res" id="0x01010001"/>
+
+ <!-- S staged attributes (support staged resources in the same type id) -->
+ <staging-public-group type="attr" first-id="0x01010050">
+ <public name="staged_s_res" />
+ </staging-public-group>
+
+ <!-- SV2 staged attributes (support staged resources in a separate type id) -->
+ <staging-public-group type="attr" first-id="0x01ff0049">
+ <public name="staged_s2_res" />
+ </staging-public-group>
+
+ <!-- T staged attributes (support staged resources in multiple separate type ids) -->
+ <staging-public-group type="attr" first-id="0x01fe0063">
+ <public name="staged_t_res" />
+ </staging-public-group>
+
+ <staging-public-group type="string" first-id="0x01fd0072">
+ <public name="staged_t_string" />
+ </staging-public-group>
+
+ <attr name="finalized_res" />
+ <attr name="staged_s_res" />
+ <attr name="staged_s2_res" />
+ <attr name="staged_t_res" />
+ <string name="staged_t_string">Hello</string>
+ </resources>)";
+
+ const std::string app_values =
+ R"(<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <attr name="bar" />
+ <declare-styleable name="ClientStyleable">
+ <attr name="android:finalized_res" />
+ <attr name="android:staged_s_res" />
+ <attr name="bar" />
+ </declare-styleable>
+ </resources>)";
+
+ const std::string android_res = GetTestPath("android-res");
+ ASSERT_TRUE(
+ CompileFile(GetTestPath("res/values/values.xml"), android_values, android_res, &diag));
+
+ const std::string android_apk = GetTestPath("android.apk");
+ const std::string android_java = GetTestPath("android_java");
+ // clang-format off
+ auto android_manifest = ManifestBuilder(this)
+ .SetPackageName("android")
+ .Build();
+
+ auto android_link_args = LinkCommandBuilder(this)
+ .SetManifestFile(android_manifest)
+ .AddParameter("--private-symbols", "com.android.internal")
+ .AddParameter("--java", android_java)
+ .AddCompiledResDir(android_res, &diag)
+ .Build(android_apk);
+ // clang-format on
+ ASSERT_TRUE(Link(android_link_args, &diag));
+
+ const std::string android_r_java = android_java + "/android/R.java";
+ std::string android_r_contents;
+ ASSERT_TRUE(android::base::ReadFileToString(android_r_java, &android_r_contents));
+ EXPECT_THAT(android_r_contents, HasSubstr(" public static final int finalized_res=0x01010001;"));
+ EXPECT_THAT(android_r_contents, HasSubstr(" public static int staged_s_res=0x01010050;"));
+ EXPECT_THAT(android_r_contents, HasSubstr(" public static int staged_s2_res=0x01ff0049;"));
+ EXPECT_THAT(android_r_contents, HasSubstr(" public static int staged_t_res=0x01fe0063;"));
+ EXPECT_THAT(android_r_contents, HasSubstr(" public static int staged_t_string=0x01fd0072;"));
+
+ // Build an app that uses the framework attribute in a declare-styleable
+ const std::string client_res = GetTestPath("app-res");
+ ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"), app_values, client_res, &diag));
+
+ const std::string app_apk = GetTestPath("app.apk");
+ const std::string app_java = GetTestPath("app_java");
+ // clang-format off
+ auto app_manifest = ManifestBuilder(this)
+ .SetPackageName("com.example.app")
+ .Build();
+
+ auto app_link_args = LinkCommandBuilder(this)
+ .SetManifestFile(app_manifest)
+ .AddParameter("--java", app_java)
+ .AddParameter("-I", android_apk)
+ .AddCompiledResDir(client_res, &diag)
+ .Build(app_apk);
+ // clang-format on
+ ASSERT_TRUE(Link(app_link_args, &diag));
+
+ const std::string client_r_java = app_java + "/com/example/app/R.java";
+ std::string client_r_contents;
+ ASSERT_TRUE(android::base::ReadFileToString(client_r_java, &client_r_contents));
+ EXPECT_THAT(client_r_contents, HasSubstr(" 0x01010001, android.R.attr.staged_s_res, 0x7f010000"));
+
+ // Test that the resource ids of staged and non-staged resource can be retrieved
+ android::AssetManager2 am;
+ auto android_asset = android::ApkAssets::Load(android_apk);
+ ASSERT_THAT(android_asset, NotNull());
+ ASSERT_TRUE(am.SetApkAssets({android_asset.get()}));
+
+ auto result = am.GetResourceId("android:attr/finalized_res");
+ ASSERT_TRUE(result.has_value());
+ EXPECT_THAT(*result, Eq(0x01010001));
+
+ result = am.GetResourceId("android:attr/staged_s_res");
+ ASSERT_TRUE(result.has_value());
+ EXPECT_THAT(*result, Eq(0x01010050));
+
+ result = am.GetResourceId("android:attr/staged_s2_res");
+ ASSERT_TRUE(result.has_value());
+ EXPECT_THAT(*result, Eq(0x01ff0049));
+
+ result = am.GetResourceId("android:attr/staged_t_res");
+ ASSERT_TRUE(result.has_value());
+ EXPECT_THAT(*result, Eq(0x01fe0063));
+
+ result = am.GetResourceId("android:string/staged_t_string");
+ ASSERT_TRUE(result.has_value());
+ EXPECT_THAT(*result, Eq(0x01fd0072));
+}
+
} // namespace aapt