Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2726f482 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "AAPT2: Improve diff command"

parents 46822051 5e8fa3a2
Loading
Loading
Loading
Loading
+68 −9
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@
#include "io/File.h"
#include "io/File.h"
#include "util/Util.h"
#include "util/Util.h"


#include <algorithm>
#include <androidfw/ResourceTypes.h>
#include <androidfw/ResourceTypes.h>
#include <limits>
#include <limits>


@@ -302,18 +303,42 @@ Attribute::Attribute(bool w, uint32_t t) :
    mWeak = w;
    mWeak = w;
}
}


template <typename T>
T* addPointer(T& val) {
    return &val;
}

bool Attribute::equals(const Value* value) const {
bool Attribute::equals(const Value* value) const {
    const Attribute* other = valueCast<Attribute>(value);
    const Attribute* other = valueCast<Attribute>(value);
    if (!other) {
    if (!other) {
        return false;
        return false;
    }
    }


    return this->typeMask == other->typeMask && this->minInt == other->minInt &&
    if (symbols.size() != other->symbols.size()) {
            this->maxInt == other->maxInt &&
        return false;
            std::equal(this->symbols.begin(), this->symbols.end(),
    }
                       other->symbols.begin(),

                       [](const Symbol& a, const Symbol& b) -> bool {
    if (typeMask != other->typeMask || minInt != other->minInt || maxInt != other->maxInt) {
        return a.symbol.equals(&b.symbol) && a.value == b.value;
        return false;
    }

    std::vector<const Symbol*> sortedA;
    std::transform(symbols.begin(), symbols.end(),
                   std::back_inserter(sortedA), addPointer<const Symbol>);
    std::sort(sortedA.begin(), sortedA.end(), [](const Symbol* a, const Symbol* b) -> bool {
        return a->symbol.name < b->symbol.name;
    });

    std::vector<const Symbol*> sortedB;
    std::transform(other->symbols.begin(), other->symbols.end(),
                   std::back_inserter(sortedB), addPointer<const Symbol>);
    std::sort(sortedB.begin(), sortedB.end(), [](const Symbol* a, const Symbol* b) -> bool {
        return a->symbol.name < b->symbol.name;
    });

    return std::equal(sortedA.begin(), sortedA.end(), sortedB.begin(),
                      [](const Symbol* a, const Symbol* b) -> bool {
        return a->symbol.equals(&b->symbol) && a->value == b->value;
    });
    });
}
}


@@ -526,9 +551,28 @@ bool Style::equals(const Value* value) const {
            (parent && other->parent && !parent.value().equals(&other->parent.value()))) {
            (parent && other->parent && !parent.value().equals(&other->parent.value()))) {
        return false;
        return false;
    }
    }
    return std::equal(entries.begin(), entries.end(), other->entries.begin(),

                      [](const Entry& a, const Entry& b) -> bool {
    if (entries.size() != other->entries.size()) {
        return a.key.equals(&b.key) && a.value->equals(b.value.get());
        return false;
    }

    std::vector<const Entry*> sortedA;
    std::transform(entries.begin(), entries.end(),
                   std::back_inserter(sortedA), addPointer<const Entry>);
    std::sort(sortedA.begin(), sortedA.end(), [](const Entry* a, const Entry* b) -> bool {
        return a->key.name < b->key.name;
    });

    std::vector<const Entry*> sortedB;
    std::transform(other->entries.begin(), other->entries.end(),
                   std::back_inserter(sortedB), addPointer<const Entry>);
    std::sort(sortedB.begin(), sortedB.end(), [](const Entry* a, const Entry* b) -> bool {
        return a->key.name < b->key.name;
    });

    return std::equal(sortedA.begin(), sortedA.end(), sortedB.begin(),
                      [](const Entry* a, const Entry* b) -> bool {
        return a->key.equals(&b->key) && a->value->equals(b->value.get());
    });
    });
}
}


@@ -563,6 +607,8 @@ void Style::print(std::ostream* out) const {
static ::std::ostream& operator<<(::std::ostream& out, const Style::Entry& value) {
static ::std::ostream& operator<<(::std::ostream& out, const Style::Entry& value) {
    if (value.key.name) {
    if (value.key.name) {
        out << value.key.name.value();
        out << value.key.name.value();
    } else if (value.key.id) {
        out << value.key.id.value();
    } else {
    } else {
        out << "???";
        out << "???";
    }
    }
@@ -577,6 +623,10 @@ bool Array::equals(const Value* value) const {
        return false;
        return false;
    }
    }


    if (items.size() != other->items.size()) {
        return false;
    }

    return std::equal(items.begin(), items.end(), other->items.begin(),
    return std::equal(items.begin(), items.end(), other->items.begin(),
                      [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool {
                      [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool {
        return a->equals(b.get());
        return a->equals(b.get());
@@ -605,6 +655,10 @@ bool Plural::equals(const Value* value) const {
        return false;
        return false;
    }
    }


    if (values.size() != other->values.size()) {
        return false;
    }

    return std::equal(values.begin(), values.end(), other->values.begin(),
    return std::equal(values.begin(), values.end(), other->values.begin(),
                      [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool {
                      [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool {
        if (bool(a) != bool(b)) {
        if (bool(a) != bool(b)) {
@@ -659,6 +713,11 @@ bool Styleable::equals(const Value* value) const {
    if (!other) {
    if (!other) {
        return false;
        return false;
    }
    }

    if (entries.size() != other->entries.size()) {
        return false;
    }

    return std::equal(entries.begin(), entries.end(), other->entries.begin(),
    return std::equal(entries.begin(), entries.end(), other->entries.begin(),
                      [](const Reference& a, const Reference& b) -> bool {
                      [](const Reference& a, const Reference& b) -> bool {
        return a.equals(&b);
        return a.equals(&b);
+23 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


#include "Flags.h"
#include "Flags.h"
#include "ResourceTable.h"
#include "ResourceTable.h"
#include "ValueVisitor.h"
#include "io/ZipArchive.h"
#include "io/ZipArchive.h"
#include "process/IResourceTableConsumer.h"
#include "process/IResourceTableConsumer.h"
#include "process/SymbolTable.h"
#include "process/SymbolTable.h"
@@ -385,6 +386,24 @@ static bool emitResourceTableDiff(IAaptContext* context, LoadedApk* apkA, Loaded
    return diff;
    return diff;
}
}


class ZeroingReferenceVisitor : public ValueVisitor {
public:
    using ValueVisitor::visit;

    void visit(Reference* ref) override {
        if (ref->name && ref->id) {
            if (ref->id.value().packageId() == 0x7f) {
                ref->id = {};
            }
        }
    }
};

static void zeroOutAppReferences(ResourceTable* table) {
    ZeroingReferenceVisitor visitor;
    visitAllValuesInTable(table, &visitor);
}

int diff(const std::vector<StringPiece>& args) {
int diff(const std::vector<StringPiece>& args) {
    DiffContext context;
    DiffContext context;


@@ -405,6 +424,10 @@ int diff(const std::vector<StringPiece>& args) {
        return 1;
        return 1;
    }
    }


    // Zero out Application IDs in references.
    zeroOutAppReferences(apkA->getResourceTable());
    zeroOutAppReferences(apkB->getResourceTable());

    if (emitResourceTableDiff(&context, apkA.get(), apkB.get())) {
    if (emitResourceTableDiff(&context, apkA.get(), apkB.get())) {
        // We emitted a diff, so return 1 (failure).
        // We emitted a diff, so return 1 (failure).
        return 1;
        return 1;
+50 −33
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include "io/ZipArchive.h"
#include "io/ZipArchive.h"
#include "process/IResourceTableConsumer.h"
#include "process/IResourceTableConsumer.h"
#include "proto/ProtoSerialize.h"
#include "proto/ProtoSerialize.h"
#include "unflatten/BinaryResourceParser.h"
#include "util/Files.h"
#include "util/Files.h"
#include "util/StringPiece.h"
#include "util/StringPiece.h"


@@ -44,18 +45,9 @@ void dumpCompiledFile(const pb::CompiledFile& pbFile, const void* data, size_t l
              << "Source:   " << file->source << "\n";
              << "Source:   " << file->source << "\n";
}
}


void dumpCompiledTable(const pb::ResourceTable& pbTable, const Source& source,
                       IAaptContext* context) {
    std::unique_ptr<ResourceTable> table = deserializeTableFromPb(pbTable, source,
                                                                  context->getDiagnostics());
    if (!table) {
        return;
    }

    Debug::printTable(table.get());
}

void tryDumpFile(IAaptContext* context, const std::string& filePath) {
void tryDumpFile(IAaptContext* context, const std::string& filePath) {
    std::unique_ptr<ResourceTable> table;

    std::string err;
    std::string err;
    std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::create(filePath, &err);
    std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::create(filePath, &err);
    if (zip) {
    if (zip) {
@@ -75,17 +67,34 @@ void tryDumpFile(IAaptContext* context, const std::string& filePath) {
                return;
                return;
            }
            }


            std::unique_ptr<ResourceTable> table = deserializeTableFromPb(
            table = deserializeTableFromPb(
                    pbTable, Source(filePath), context->getDiagnostics());
                    pbTable, Source(filePath), context->getDiagnostics());
            if (table) {
            if (!table) {
                DebugPrintTableOptions debugPrintTableOptions;
                return;
                debugPrintTableOptions.showSources = true;
                Debug::printTable(table.get(), debugPrintTableOptions);
            }
            }
        }
        }

        if (!table) {
            file = zip->findFile("resources.arsc");
            if (file) {
                std::unique_ptr<io::IData> data = file->openAsData();
                if (!data) {
                    context->getDiagnostics()->error(DiagMessage(filePath)
                                                     << "failed to open resources.arsc");
                    return;
                    return;
                }
                }


                table = util::make_unique<ResourceTable>();
                BinaryResourceParser parser(context, table.get(), Source(filePath),
                                            data->data(), data->size());
                if (!parser.parse()) {
                    return;
                }
            }
        }
    }

    if (!table) {
        Maybe<android::FileMap> file = file::mmapPath(filePath, &err);
        Maybe<android::FileMap> file = file::mmapPath(filePath, &err);
        if (!file) {
        if (!file) {
            context->getDiagnostics()->error(DiagMessage(filePath) << err);
            context->getDiagnostics()->error(DiagMessage(filePath) << err);
@@ -97,10 +106,10 @@ void tryDumpFile(IAaptContext* context, const std::string& filePath) {
        // Try as a compiled table.
        // Try as a compiled table.
        pb::ResourceTable pbTable;
        pb::ResourceTable pbTable;
        if (pbTable.ParseFromArray(fileMap->getDataPtr(), fileMap->getDataLength())) {
        if (pbTable.ParseFromArray(fileMap->getDataPtr(), fileMap->getDataLength())) {
        dumpCompiledTable(pbTable, Source(filePath), context);
            table = deserializeTableFromPb(pbTable, Source(filePath), context->getDiagnostics());
        return;
        }
        }


        if (!table) {
            // Try as a compiled file.
            // Try as a compiled file.
            CompiledFileInputStream input(fileMap->getDataPtr(), fileMap->getDataLength());
            CompiledFileInputStream input(fileMap->getDataPtr(), fileMap->getDataLength());
            if (const pb::CompiledFile* pbFile = input.CompiledFile()) {
            if (const pb::CompiledFile* pbFile = input.CompiledFile()) {
@@ -108,6 +117,14 @@ void tryDumpFile(IAaptContext* context, const std::string& filePath) {
               return;
               return;
            }
            }
        }
        }
    }

    if (table) {
        DebugPrintTableOptions debugPrintTableOptions;
        debugPrintTableOptions.showSources = true;
        Debug::printTable(table.get(), debugPrintTableOptions);
    }
}


class DumpContext : public IAaptContext {
class DumpContext : public IAaptContext {
public:
public:
+0 −1
Original line number Original line Diff line number Diff line
@@ -61,7 +61,6 @@ public:
        auto cacheIter = mMapping->find(id);
        auto cacheIter = mMapping->find(id);
        if (cacheIter != mMapping->end()) {
        if (cacheIter != mMapping->end()) {
            reference->name = cacheIter->second;
            reference->name = cacheIter->second;
            reference->id = {};
        }
        }
    }
    }
};
};
+23 −0
Original line number Original line Diff line number Diff line
@@ -88,6 +88,8 @@ public:
     */
     */
    const T& value() const;
    const T& value() const;


    T valueOrDefault(const T& def) const;

private:
private:
    template <typename U>
    template <typename U>
    friend class Maybe;
    friend class Maybe;
@@ -262,6 +264,14 @@ const T& Maybe<T>::value() const {
    return reinterpret_cast<const T&>(mStorage);
    return reinterpret_cast<const T&>(mStorage);
}
}


template <typename T>
T Maybe<T>::valueOrDefault(const T& def) const {
    if (mNothing) {
        return def;
    }
    return reinterpret_cast<const T&>(mStorage);
}

template <typename T>
template <typename T>
void Maybe<T>::destroy() {
void Maybe<T>::destroy() {
    reinterpret_cast<T&>(mStorage).~T();
    reinterpret_cast<T&>(mStorage).~T();
@@ -306,6 +316,19 @@ typename std::enable_if<
    return !(a == b);
    return !(a == b);
}
}


template <typename T, typename U>
typename std::enable_if<
        has_lt_op<T, U>::value,
        bool
>::type operator<(const Maybe<T>& a, const Maybe<U>& b) {
    if (a && b) {
        return a.value() < b.value();
    } else if (!a && !b) {
        return false;
    }
    return !a;
}

} // namespace aapt
} // namespace aapt


#endif // AAPT_MAYBE_H
#endif // AAPT_MAYBE_H