AAPT2: Fix overlay support
Supports the <add-resource> tag and mimics old AAPT behavior of
not allowing new resources defined unless <add-resource> was used
or --auto-add-overlay was specified.
Change-Id: I9b461137357617ade37fd7045b418b8e6450b9c4
diff --git a/tools/aapt2/link/TableMerger.h b/tools/aapt2/link/TableMerger.h
index a2c9dbf..e1be5d5 100644
--- a/tools/aapt2/link/TableMerger.h
+++ b/tools/aapt2/link/TableMerger.h
@@ -17,21 +17,40 @@
#ifndef AAPT_TABLEMERGER_H
#define AAPT_TABLEMERGER_H
+#include "Resource.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
+#include "io/File.h"
+#include "process/IResourceTableConsumer.h"
#include "util/Util.h"
-#include "process/IResourceTableConsumer.h"
-
-#include <queue>
-#include <set>
+#include <functional>
+#include <map>
namespace aapt {
struct FileToMerge {
- ResourceTable* srcTable;
- std::u16string srcPath;
- std::u16string dstPath;
+ /**
+ * The compiled file from which to read the data.
+ */
+ io::IFile* file;
+
+ /**
+ * Where the original, uncompiled file came from.
+ */
+ Source originalSource;
+
+ /**
+ * The destination path within the APK/archive.
+ */
+ std::string dstPath;
+};
+
+struct TableMergerOptions {
+ /**
+ * If true, resources in overlays can be added without previously having existed.
+ */
+ bool autoAddOverlay = false;
};
/**
@@ -50,40 +69,74 @@
*/
class TableMerger {
public:
- TableMerger(IAaptContext* context, ResourceTable* outTable);
+ /**
+ * Note: The outTable ResourceTable must live longer than this TableMerger. References
+ * are made to this ResourceTable for efficiency reasons.
+ */
+ TableMerger(IAaptContext* context, ResourceTable* outTable, const TableMergerOptions& options);
- inline std::queue<FileToMerge>* getFileMergeQueue() {
- return &mFilesToMerge;
+ const std::map<ResourceKeyRef, FileToMerge>& getFilesToMerge() {
+ return mFilesToMerge;
}
- inline const std::set<std::u16string>& getMergedPackages() const {
+ const std::set<std::u16string>& getMergedPackages() const {
return mMergedPackages;
}
/**
* Merges resources from the same or empty package. This is for local sources.
*/
- bool merge(const Source& src, ResourceTable* table, bool overrideExisting);
+ bool merge(const Source& src, ResourceTable* table);
+
+ /**
+ * Merges resources from an overlay ResourceTable.
+ */
+ bool mergeOverlay(const Source& src, ResourceTable* table);
/**
* Merges resources from the given package, mangling the name. This is for static libraries.
+ * An io::IFileCollection is needed in order to find the referenced Files and process them.
*/
- bool mergeAndMangle(const Source& src, const StringPiece16& package, ResourceTable* table);
+ bool mergeAndMangle(const Source& src, const StringPiece16& package, ResourceTable* table,
+ io::IFileCollection* collection);
+
+ /**
+ * Merges a compiled file that belongs to this same or empty package. This is for local sources.
+ */
+ bool mergeFile(const ResourceFile& fileDesc, io::IFile* file);
+
+ /**
+ * Merges a compiled file from an overlay, overriding an existing definition.
+ */
+ bool mergeFileOverlay(const ResourceFile& fileDesc, io::IFile* file);
private:
+ using FileMergeCallback = std::function<bool(const ResourceNameRef&,
+ const ConfigDescription& config,
+ FileReference*,
+ FileReference*)>;
+
IAaptContext* mContext;
ResourceTable* mMasterTable;
+ TableMergerOptions mOptions;
ResourceTablePackage* mMasterPackage;
std::set<std::u16string> mMergedPackages;
- std::queue<FileToMerge> mFilesToMerge;
+ std::map<ResourceKeyRef, FileToMerge> mFilesToMerge;
+
+ bool mergeFileImpl(const ResourceFile& fileDesc, io::IFile* file, bool overlay);
+
+ bool mergeImpl(const Source& src, ResourceTable* srcTable,
+ bool overlay, bool allowNew);
bool doMerge(const Source& src, ResourceTable* srcTable, ResourceTablePackage* srcPackage,
- const bool manglePackage, const bool overrideExisting);
+ const bool manglePackage,
+ const bool overlay,
+ const bool allowNewResources,
+ FileMergeCallback callback);
- std::unique_ptr<Value> cloneAndMangle(ResourceTable* table, const std::u16string& package,
- Value* value);
- std::unique_ptr<Value> clone(Value* value);
+ std::unique_ptr<FileReference> cloneAndMangleFile(const std::u16string& package,
+ const FileReference& value);
};
} // namespace aapt