Add <staging-public-group-final> to aapt2 To allow apps that compiled against a pre-release SDK to continue working for a period of time after API finalization, a new tag, <staging-public-group-final>, has been added to aapt2. When finalizing the framework resource API, converting <staging-public-group> tags to <staging-public-group-final> will cause aapt2 to generate the resource table so that there is a resource entry for the old non-finalized (staged) resource ID and another entry for the finalized resource ID of newly finalized resources. This allows an application that compiled against the pre-release SDK to continue resolving resources using pre-release resource IDs. All references to pre-release resource IDs will be rewritten to their finalized resource IDs through the information stored in the new staged alias chunk. This allows applications compiled against <staging-public-group> resources to use the newly finalized resource ID without re-compilation. When an application is re-compiled against the SDK with <staging-public-group-final> tags, the application will use the finalized resource IDs. This change limits the use of the alias chunk to the framework for S. Bug: 183411356 Test: aapt2_test Change-Id: Iba1c3033c3c2f32de8e4a19b58d3921c971092c4
diff --git a/tools/aapt2/cmd/Diff.cpp b/tools/aapt2/cmd/Diff.cpp index df31087..3950f33 100644 --- a/tools/aapt2/cmd/Diff.cpp +++ b/tools/aapt2/cmd/Diff.cpp
@@ -97,15 +97,15 @@ static bool EmitResourceConfigValueDiff( IAaptContext* context, LoadedApk* apk_a, const ResourceTablePackageView& pkg_a, - const ResourceTableTypeView& type_a, const ResourceEntry* entry_a, + const ResourceTableTypeView& type_a, const ResourceTableEntryView& entry_a, const ResourceConfigValue* config_value_a, LoadedApk* apk_b, const ResourceTablePackageView& pkg_b, const ResourceTableTypeView& type_b, - const ResourceEntry* entry_b, const ResourceConfigValue* config_value_b) { + const ResourceTableEntryView& entry_b, const ResourceConfigValue* config_value_b) { Value* value_a = config_value_a->value.get(); Value* value_b = config_value_b->value.get(); if (!value_a->Equals(value_b)) { std::stringstream str_stream; - str_stream << "value " << pkg_a.name << ":" << type_a.type << "/" << entry_a->name + str_stream << "value " << pkg_a.name << ":" << type_a.type << "/" << entry_a.name << " config=" << config_value_a->config << " does not match:\n"; value_a->Print(&str_stream); str_stream << "\n vs \n"; @@ -118,32 +118,32 @@ static bool EmitResourceEntryDiff(IAaptContext* context, LoadedApk* apk_a, const ResourceTablePackageView& pkg_a, - const ResourceTableTypeView& type_a, const ResourceEntry* entry_a, - LoadedApk* apk_b, const ResourceTablePackageView& pkg_b, + const ResourceTableTypeView& type_a, + const ResourceTableEntryView& entry_a, LoadedApk* apk_b, + const ResourceTablePackageView& pkg_b, const ResourceTableTypeView& type_b, - const ResourceEntry* entry_b) { + const ResourceTableEntryView& entry_b) { bool diff = false; - for (const std::unique_ptr<ResourceConfigValue>& config_value_a : entry_a->values) { - auto config_value_b = entry_b->FindValue(config_value_a->config); + for (const ResourceConfigValue* config_value_a : entry_a.values) { + auto config_value_b = entry_b.FindValue(config_value_a->config); if (!config_value_b) { std::stringstream str_stream; - str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << entry_a->name + str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << entry_a.name << " config=" << config_value_a->config; EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } else { - diff |= - EmitResourceConfigValueDiff(context, apk_a, pkg_a, type_a, entry_a, config_value_a.get(), - apk_b, pkg_b, type_b, entry_b, config_value_b); + diff |= EmitResourceConfigValueDiff(context, apk_a, pkg_a, type_a, entry_a, config_value_a, + apk_b, pkg_b, type_b, entry_b, config_value_b); } } // Check for any newly added config values. - for (const std::unique_ptr<ResourceConfigValue>& config_value_b : entry_b->values) { - auto config_value_a = entry_a->FindValue(config_value_b->config); + for (const ResourceConfigValue* config_value_b : entry_b.values) { + auto config_value_a = entry_a.FindValue(config_value_b->config); if (!config_value_a) { std::stringstream str_stream; - str_stream << "new config " << pkg_b.name << ":" << type_b.type << "/" << entry_b->name + str_stream << "new config " << pkg_b.name << ":" << type_b.type << "/" << entry_b.name << " config=" << config_value_b->config; EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; @@ -164,36 +164,35 @@ if (entry_b_iter == type_b.entries.end()) { // Type A contains a type that type B does not have. std::stringstream str_stream; - str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << (*entry_a_iter)->name; + str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << entry_a_iter->name; EmitDiffLine(apk_a->GetSource(), str_stream.str()); diff = true; } else if (entry_a_iter == type_a.entries.end()) { // Type B contains a type that type A does not have. std::stringstream str_stream; - str_stream << "new entry " << pkg_b.name << ":" << type_b.type << "/" - << (*entry_b_iter)->name; + str_stream << "new entry " << pkg_b.name << ":" << type_b.type << "/" << entry_b_iter->name; EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } else { const auto& entry_a = *entry_a_iter; const auto& entry_b = *entry_b_iter; - if (IsSymbolVisibilityDifferent(entry_a->visibility, entry_b->visibility)) { + if (IsSymbolVisibilityDifferent(entry_a.visibility, entry_b.visibility)) { std::stringstream str_stream; - str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a->name + str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a.name << " has different visibility ("; - if (entry_b->visibility.staged_api) { + if (entry_b.visibility.staged_api) { str_stream << "STAGED "; } - if (entry_b->visibility.level == Visibility::Level::kPublic) { + if (entry_b.visibility.level == Visibility::Level::kPublic) { str_stream << "PUBLIC"; } else { str_stream << "PRIVATE"; } str_stream << " vs "; - if (entry_a->visibility.staged_api) { + if (entry_a.visibility.staged_api) { str_stream << "STAGED "; } - if (entry_a->visibility.level == Visibility::Level::kPublic) { + if (entry_a.visibility.level == Visibility::Level::kPublic) { str_stream << "PUBLIC"; } else { str_stream << "PRIVATE"; @@ -201,19 +200,19 @@ str_stream << ")"; EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; - } else if (IsIdDiff(entry_a->visibility.level, entry_a->id, entry_b->visibility.level, - entry_b->id)) { + } else if (IsIdDiff(entry_a.visibility.level, entry_a.id, entry_b.visibility.level, + entry_b.id)) { std::stringstream str_stream; - str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a->name + str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a.name << " has different public ID ("; - if (entry_b->id) { - str_stream << "0x" << std::hex << entry_b->id.value(); + if (entry_b.id) { + str_stream << "0x" << std::hex << entry_b.id.value(); } else { str_stream << "none"; } str_stream << " vs "; - if (entry_a->id) { - str_stream << "0x " << std::hex << entry_a->id.value(); + if (entry_a.id) { + str_stream << "0x " << std::hex << entry_a.id.value(); } else { str_stream << "none"; }