diff options
author | Adam Lesinski <adamlesinski@google.com> | 2017-04-03 18:12:45 -0700 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2017-04-10 11:59:18 -0700 |
commit | d0f492db038c6210c1138865d816bfb134376538 (patch) | |
tree | 1d4ed362037758111a28ecb453d527403d5d6815 /tools/aapt2/diff/Diff.cpp | |
parent | 0015a153536c51cdd66dce5e9f08d19eb517fab8 (diff) |
AAPT2: Share split functionality between link and optimize
Generating splits should be possible to do from the optimize command.
This means that a lot of infrastructure around split APKs can be
shared by both the optimize and link phase.
Bug: 35925830
Change-Id: Ia88b9e4bff300a56353b2f7a4a2547c8eb43a299
Test: manual
Diffstat (limited to 'tools/aapt2/diff/Diff.cpp')
-rw-r--r-- | tools/aapt2/diff/Diff.cpp | 379 |
1 files changed, 0 insertions, 379 deletions
diff --git a/tools/aapt2/diff/Diff.cpp b/tools/aapt2/diff/Diff.cpp deleted file mode 100644 index dacf8d9f1e96..000000000000 --- a/tools/aapt2/diff/Diff.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "android-base/macros.h" - -#include "Flags.h" -#include "LoadedApk.h" -#include "ValueVisitor.h" -#include "process/IResourceTableConsumer.h" -#include "process/SymbolTable.h" - -using android::StringPiece; - -namespace aapt { - -class DiffContext : public IAaptContext { - public: - DiffContext() : name_mangler_({}), symbol_table_(&name_mangler_) {} - - const std::string& GetCompilationPackage() override { return empty_; } - - uint8_t GetPackageId() override { return 0x0; } - - IDiagnostics* GetDiagnostics() override { return &diagnostics_; } - - NameMangler* GetNameMangler() override { return &name_mangler_; } - - SymbolTable* GetExternalSymbols() override { return &symbol_table_; } - - bool IsVerbose() override { return false; } - - int GetMinSdkVersion() override { return 0; } - - private: - std::string empty_; - StdErrDiagnostics diagnostics_; - NameMangler name_mangler_; - SymbolTable symbol_table_; -}; - -static void EmitDiffLine(const Source& source, const StringPiece& message) { - std::cerr << source << ": " << message << "\n"; -} - -static bool IsSymbolVisibilityDifferent(const Symbol& symbol_a, - const Symbol& symbol_b) { - return symbol_a.state != symbol_b.state; -} - -template <typename Id> -static bool IsIdDiff(const Symbol& symbol_a, const Maybe<Id>& id_a, - const Symbol& symbol_b, const Maybe<Id>& id_b) { - if (symbol_a.state == SymbolState::kPublic || - symbol_b.state == SymbolState::kPublic) { - return id_a != id_b; - } - return false; -} - -static bool EmitResourceConfigValueDiff( - IAaptContext* context, LoadedApk* apk_a, ResourceTablePackage* pkg_a, - ResourceTableType* type_a, ResourceEntry* entry_a, - ResourceConfigValue* config_value_a, LoadedApk* apk_b, - ResourceTablePackage* pkg_b, ResourceTableType* type_b, - ResourceEntry* entry_b, 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 << " config=" << config_value_a->config - << " does not match:\n"; - value_a->Print(&str_stream); - str_stream << "\n vs \n"; - value_b->Print(&str_stream); - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - return true; - } - return false; -} - -static bool EmitResourceEntryDiff(IAaptContext* context, LoadedApk* apk_a, - ResourceTablePackage* pkg_a, - ResourceTableType* type_a, - ResourceEntry* entry_a, LoadedApk* apk_b, - ResourceTablePackage* pkg_b, - ResourceTableType* type_b, - ResourceEntry* entry_b) { - bool diff = false; - for (std::unique_ptr<ResourceConfigValue>& config_value_a : entry_a->values) { - ResourceConfigValue* 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 << " 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); - } - } - - // Check for any newly added config values. - for (std::unique_ptr<ResourceConfigValue>& config_value_b : entry_b->values) { - ResourceConfigValue* 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 << " config=" << config_value_b->config; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } - } - return false; -} - -static bool EmitResourceTypeDiff(IAaptContext* context, LoadedApk* apk_a, - ResourceTablePackage* pkg_a, - ResourceTableType* type_a, LoadedApk* apk_b, - ResourceTablePackage* pkg_b, - ResourceTableType* type_b) { - bool diff = false; - for (std::unique_ptr<ResourceEntry>& entry_a : type_a->entries) { - ResourceEntry* entry_b = type_b->FindEntry(entry_a->name); - if (!entry_b) { - std::stringstream str_stream; - str_stream << "missing " << pkg_a->name << ":" << type_a->type << "/" - << entry_a->name; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } else { - if (IsSymbolVisibilityDifferent(entry_a->symbol_status, - entry_b->symbol_status)) { - std::stringstream str_stream; - str_stream << pkg_a->name << ":" << type_a->type << "/" << entry_a->name - << " has different visibility ("; - if (entry_b->symbol_status.state == SymbolState::kPublic) { - str_stream << "PUBLIC"; - } else { - str_stream << "PRIVATE"; - } - str_stream << " vs "; - if (entry_a->symbol_status.state == SymbolState::kPublic) { - str_stream << "PUBLIC"; - } else { - str_stream << "PRIVATE"; - } - str_stream << ")"; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } else if (IsIdDiff(entry_a->symbol_status, entry_a->id, - entry_b->symbol_status, entry_b->id)) { - std::stringstream str_stream; - 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(); - } else { - str_stream << "none"; - } - str_stream << " vs "; - if (entry_a->id) { - str_stream << "0x " << std::hex << entry_a->id.value(); - } else { - str_stream << "none"; - } - str_stream << ")"; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } - diff |= - EmitResourceEntryDiff(context, apk_a, pkg_a, type_a, entry_a.get(), - apk_b, pkg_b, type_b, entry_b); - } - } - - // Check for any newly added entries. - for (std::unique_ptr<ResourceEntry>& entry_b : type_b->entries) { - ResourceEntry* entry_a = type_a->FindEntry(entry_b->name); - if (!entry_a) { - std::stringstream str_stream; - str_stream << "new entry " << pkg_b->name << ":" << type_b->type << "/" - << entry_b->name; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } - } - return diff; -} - -static bool EmitResourcePackageDiff(IAaptContext* context, LoadedApk* apk_a, - ResourceTablePackage* pkg_a, - LoadedApk* apk_b, - ResourceTablePackage* pkg_b) { - bool diff = false; - for (std::unique_ptr<ResourceTableType>& type_a : pkg_a->types) { - ResourceTableType* type_b = pkg_b->FindType(type_a->type); - if (!type_b) { - std::stringstream str_stream; - str_stream << "missing " << pkg_a->name << ":" << type_a->type; - EmitDiffLine(apk_a->GetSource(), str_stream.str()); - diff = true; - } else { - if (IsSymbolVisibilityDifferent(type_a->symbol_status, - type_b->symbol_status)) { - std::stringstream str_stream; - str_stream << pkg_a->name << ":" << type_a->type - << " has different visibility ("; - if (type_b->symbol_status.state == SymbolState::kPublic) { - str_stream << "PUBLIC"; - } else { - str_stream << "PRIVATE"; - } - str_stream << " vs "; - if (type_a->symbol_status.state == SymbolState::kPublic) { - str_stream << "PUBLIC"; - } else { - str_stream << "PRIVATE"; - } - str_stream << ")"; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } else if (IsIdDiff(type_a->symbol_status, type_a->id, - type_b->symbol_status, type_b->id)) { - std::stringstream str_stream; - str_stream << pkg_a->name << ":" << type_a->type - << " has different public ID ("; - if (type_b->id) { - str_stream << "0x" << std::hex << type_b->id.value(); - } else { - str_stream << "none"; - } - str_stream << " vs "; - if (type_a->id) { - str_stream << "0x " << std::hex << type_a->id.value(); - } else { - str_stream << "none"; - } - str_stream << ")"; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } - diff |= EmitResourceTypeDiff(context, apk_a, pkg_a, type_a.get(), apk_b, - pkg_b, type_b); - } - } - - // Check for any newly added types. - for (std::unique_ptr<ResourceTableType>& type_b : pkg_b->types) { - ResourceTableType* type_a = pkg_a->FindType(type_b->type); - if (!type_a) { - std::stringstream str_stream; - str_stream << "new type " << pkg_b->name << ":" << type_b->type; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } - } - return diff; -} - -static bool EmitResourceTableDiff(IAaptContext* context, LoadedApk* apk_a, - LoadedApk* apk_b) { - ResourceTable* table_a = apk_a->GetResourceTable(); - ResourceTable* table_b = apk_b->GetResourceTable(); - - bool diff = false; - for (std::unique_ptr<ResourceTablePackage>& pkg_a : table_a->packages) { - ResourceTablePackage* pkg_b = table_b->FindPackage(pkg_a->name); - if (!pkg_b) { - std::stringstream str_stream; - str_stream << "missing package " << pkg_a->name; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } else { - if (pkg_a->id != pkg_b->id) { - std::stringstream str_stream; - str_stream << "package '" << pkg_a->name << "' has different id ("; - if (pkg_b->id) { - str_stream << "0x" << std::hex << pkg_b->id.value(); - } else { - str_stream << "none"; - } - str_stream << " vs "; - if (pkg_a->id) { - str_stream << "0x" << std::hex << pkg_a->id.value(); - } else { - str_stream << "none"; - } - str_stream << ")"; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } - diff |= - EmitResourcePackageDiff(context, apk_a, pkg_a.get(), apk_b, pkg_b); - } - } - - // Check for any newly added packages. - for (std::unique_ptr<ResourceTablePackage>& pkg_b : table_b->packages) { - ResourceTablePackage* pkg_a = table_a->FindPackage(pkg_b->name); - if (!pkg_a) { - std::stringstream str_stream; - str_stream << "new package " << pkg_b->name; - EmitDiffLine(apk_b->GetSource(), str_stream.str()); - diff = true; - } - } - return diff; -} - -class ZeroingReferenceVisitor : public ValueVisitor { - public: - using ValueVisitor::Visit; - - void Visit(Reference* ref) override { - if (ref->name && ref->id) { - if (ref->id.value().package_id() == kAppPackageId) { - ref->id = {}; - } - } - } -}; - -static void ZeroOutAppReferences(ResourceTable* table) { - ZeroingReferenceVisitor visitor; - VisitAllValuesInTable(table, &visitor); -} - -int Diff(const std::vector<StringPiece>& args) { - DiffContext context; - - Flags flags; - if (!flags.Parse("aapt2 diff", args, &std::cerr)) { - return 1; - } - - if (flags.GetArgs().size() != 2u) { - std::cerr << "must have two apks as arguments.\n\n"; - flags.Usage("aapt2 diff", &std::cerr); - return 1; - } - - std::unique_ptr<LoadedApk> apk_a = - LoadedApk::LoadApkFromPath(&context, flags.GetArgs()[0]); - std::unique_ptr<LoadedApk> apk_b = - LoadedApk::LoadApkFromPath(&context, flags.GetArgs()[1]); - if (!apk_a || !apk_b) { - return 1; - } - - // Zero out Application IDs in references. - ZeroOutAppReferences(apk_a->GetResourceTable()); - ZeroOutAppReferences(apk_b->GetResourceTable()); - - if (EmitResourceTableDiff(&context, apk_a.get(), apk_b.get())) { - // We emitted a diff, so return 1 (failure). - return 1; - } - return 0; -} - -} // namespace aapt |