summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorRyan Mitchell <rtmitchell@google.com>2021-03-29 14:47:02 -0700
committerRyan Mitchell <rtmitchell@google.com>2021-03-31 23:04:57 -0700
commitca3b4f76335fcb2ecf09a244f8f95baf56969a12 (patch)
treee13eb5c5b966510c0dc37842b007a7b339829051 /tools
parentb50914c52441216f27b7a6d789f00be62f7cd5f2 (diff)
Use staging-public-group in framework SDK
To make S finalization easier, this changes the framework SDK so that apps linking against it will be able to continue working as expected after the first phase of SDK finalization. During the first phase of SDK finalization, the resource ids of resources that have not been removed are finalized. staging-public-group tags are converted to staging-public-group-final tags in order to encode into the framework what the staged resource id of a finalized resource was. When an app recompiles, it will use the finalized resource id. Then after all apps recompile, phase 2 of finalization begins, in which the staging-public-group-final tags are removed so apps can no longer use the staged resource ids. Apps that link against the SDK (provided they are using a recent version of aapt) will encode references to staged resources as TYPE_DYNAMIC_REFERENCE and TYPE_DYNAMIC_ATTRIBUTE. The values of R fields for staged resources are defined out-of-line to prevent them from being inlined into apps linking agsint the SDK. This allows the resource ids to change during phase 1 of API finalization. Bug: 183413192 Test: `aapt2 diff` and resource ids stayed the same Test: `aapt2 dump` of framework-res.apk and observe staged resources Change-Id: Ie2275c608297a5f63dde8b1cf795415112cbcc24
Diffstat (limited to 'tools')
-rw-r--r--tools/aapt2/cmd/Link_test.cpp18
-rw-r--r--tools/aapt2/format/binary/BinaryResourceParser.cpp9
-rw-r--r--tools/aapt2/java/ClassDefinition.h12
3 files changed, 31 insertions, 8 deletions
diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp
index dfdac6b9d93e..d1e6d3922f3f 100644
--- a/tools/aapt2/cmd/Link_test.cpp
+++ b/tools/aapt2/cmd/Link_test.cpp
@@ -466,11 +466,19 @@ TEST_F(LinkTest, StagedAndroidApi) {
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;"));
+ EXPECT_THAT(android_r_contents, HasSubstr("public static final int finalized_res=0x01010001;"));
+ EXPECT_THAT(
+ android_r_contents,
+ HasSubstr("public static final int staged_s_res; static { staged_s_res=0x01010050; }"));
+ EXPECT_THAT(
+ android_r_contents,
+ HasSubstr("public static final int staged_s2_res; static { staged_s2_res=0x01ff0049; }"));
+ EXPECT_THAT(
+ android_r_contents,
+ HasSubstr("public static final int staged_t_res; static { staged_t_res=0x01fe0063; }"));
+ EXPECT_THAT(
+ android_r_contents,
+ HasSubstr("public static final int staged_t_string; static { staged_t_string=0x01fd0072; }"));
// Build an app that uses the framework attribute in a declare-styleable
const std::string client_res = GetTestPath("app-res");
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp
index bfb8d5854d6d..f1b350fe90f7 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.cpp
+++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp
@@ -393,8 +393,15 @@ bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
.SetAllowMangled(true);
if (entry->flags & ResTable_entry::FLAG_PUBLIC) {
- res_builder.SetVisibility(Visibility{Visibility::Level::kPublic});
+ Visibility visibility{Visibility::Level::kPublic};
+ auto spec_flags = entry_type_spec_flags_.find(res_id);
+ if (spec_flags != entry_type_spec_flags_.end() &&
+ spec_flags->second & ResTable_typeSpec::SPEC_STAGED_API) {
+ visibility.staged_api = true;
+ }
+
+ res_builder.SetVisibility(visibility);
// Erase the ID from the map once processed, so that we don't mark the same symbol more than
// once.
entry_type_spec_flags_.erase(res_id);
diff --git a/tools/aapt2/java/ClassDefinition.h b/tools/aapt2/java/ClassDefinition.h
index d3648c8aae52..2acdadb3c034 100644
--- a/tools/aapt2/java/ClassDefinition.h
+++ b/tools/aapt2/java/ClassDefinition.h
@@ -78,10 +78,18 @@ class PrimitiveMember : public ClassMember {
ClassMember::Print(final, printer, strip_api_annotations);
printer->Print("public static ");
- if (final && !staged_api_) {
+ if (final) {
printer->Print("final ");
}
- printer->Print("int ").Print(name_).Print("=").Print(to_string(val_)).Print(";");
+ printer->Print("int ").Print(name_);
+ if (staged_api_) {
+ // Prevent references to staged apis from being inline by setting their value out-of-line.
+ printer->Print("; static { ").Print(name_);
+ }
+ printer->Print("=").Print(to_string(val_)).Print(";");
+ if (staged_api_) {
+ printer->Print(" }");
+ }
}
private: