11ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/*
21ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
31ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
41ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
51ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * you may not use this file except in compliance with the License.
61ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * You may obtain a copy of the License at
71ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
81ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
91ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Unless required by applicable law or agreed to in writing, software
111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * See the License for the specific language governing permissions and
141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * limitations under the License.
151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */
161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#ifndef AAPT_TABLEMERGER_H
181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#define AAPT_TABLEMERGER_H
191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
20a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski#include "Resource.h"
211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "ResourceTable.h"
221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "ResourceValues.h"
236a008170cb18666e04c42856f992fc7a0afa1e1fAdam Lesinski#include "filter/ConfigFilter.h"
24a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski#include "io/File.h"
251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "process/IResourceTableConsumer.h"
26a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski#include "util/Util.h"
271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
28a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski#include <functional>
29a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski#include <map>
301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace aapt {
321ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
33a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinskistruct TableMergerOptions {
34a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    /**
35a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     * If true, resources in overlays can be added without previously having existed.
36a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     */
37a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    bool autoAddOverlay = false;
381ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
391ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
401ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/**
411ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * TableMerger takes resource tables and merges all packages within the tables that have the same
421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * package ID.
431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
441ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * If a package has a different name, all the entries in that table have their names mangled
451ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * to include the package name. This way there are no collisions. In order to do this correctly,
461ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * the TableMerger needs to also mangle any FileReference paths. Once these are mangled,
471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * the original source path of the file, along with the new destination path is recorded in the
481ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * queue returned from getFileMergeQueue().
491ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
501ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Once the merging is complete, a separate process can go collect the files from the various
511ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * source APKs and either copy or process their XML and put them in the correct location in
521ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * the final APK.
531ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */
541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass TableMerger {
551ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskipublic:
56a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    /**
57a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     * Note: The outTable ResourceTable must live longer than this TableMerger. References
58a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     * are made to this ResourceTable for efficiency reasons.
59a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     */
60a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    TableMerger(IAaptContext* context, ResourceTable* outTable, const TableMergerOptions& options);
611ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
62a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    const std::set<std::u16string>& getMergedPackages() const {
631ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        return mMergedPackages;
641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
6683f2255f69729e0e97539e96e5e6161843e85823Adam Lesinski    /**
6783f2255f69729e0e97539e96e5e6161843e85823Adam Lesinski     * Merges resources from the same or empty package. This is for local sources.
6864587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski     * An io::IFileCollection is optional and used to find the referenced Files and process them.
6983f2255f69729e0e97539e96e5e6161843e85823Adam Lesinski     */
7064587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    bool merge(const Source& src, ResourceTable* table,
7164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski               io::IFileCollection* collection = nullptr);
72a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
73a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    /**
74a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     * Merges resources from an overlay ResourceTable.
7564587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski     * An io::IFileCollection is optional and used to find the referenced Files and process them.
76a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     */
7764587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    bool mergeOverlay(const Source& src, ResourceTable* table,
7864587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski                      io::IFileCollection* collection = nullptr);
791ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
8083f2255f69729e0e97539e96e5e6161843e85823Adam Lesinski    /**
8183f2255f69729e0e97539e96e5e6161843e85823Adam Lesinski     * Merges resources from the given package, mangling the name. This is for static libraries.
82a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     * An io::IFileCollection is needed in order to find the referenced Files and process them.
83a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     */
84a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    bool mergeAndMangle(const Source& src, const StringPiece16& package, ResourceTable* table,
85a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski                        io::IFileCollection* collection);
86a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
87a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    /**
88a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     * Merges a compiled file that belongs to this same or empty package. This is for local sources.
89a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     */
90a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    bool mergeFile(const ResourceFile& fileDesc, io::IFile* file);
91a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
92a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    /**
93a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski     * Merges a compiled file from an overlay, overriding an existing definition.
9483f2255f69729e0e97539e96e5e6161843e85823Adam Lesinski     */
95a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    bool mergeFileOverlay(const ResourceFile& fileDesc, io::IFile* file);
9683f2255f69729e0e97539e96e5e6161843e85823Adam Lesinski
971ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiprivate:
98a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    using FileMergeCallback = std::function<bool(const ResourceNameRef&,
99a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski                                                 const ConfigDescription& config,
100355f285ffd000f6cfe76680eb22d010546d124bbAdam Lesinski                                                 FileReference*, FileReference*)>;
101a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
1021ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    IAaptContext* mContext;
1031ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    ResourceTable* mMasterTable;
104a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    TableMergerOptions mOptions;
1051ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    ResourceTablePackage* mMasterPackage;
1061ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1071ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    std::set<std::u16string> mMergedPackages;
108a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
109a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    bool mergeFileImpl(const ResourceFile& fileDesc, io::IFile* file, bool overlay);
110a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski
11164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    bool mergeImpl(const Source& src, ResourceTable* srcTable, io::IFileCollection* collection,
112a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski                   bool overlay, bool allowNew);
1131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    bool doMerge(const Source& src, ResourceTable* srcTable, ResourceTablePackage* srcPackage,
115a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski                 const bool manglePackage,
116a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski                 const bool overlay,
117a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski                 const bool allowNewResources,
118a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski                 FileMergeCallback callback);
1191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
120a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski    std::unique_ptr<FileReference> cloneAndMangleFile(const std::u16string& package,
121a6fe345be955368a13aea76aefb4db821aad11dfAdam Lesinski                                                      const FileReference& value);
1221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
1231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1241ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski} // namespace aapt
1251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1261ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#endif /* AAPT_TABLEMERGER_H */
127