1fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski/*
2fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * Copyright (C) 2014 The Android Open Source Project
3fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski *
4fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * you may not use this file except in compliance with the License.
6fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * You may obtain a copy of the License at
7fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski *
8fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski *
10fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * See the License for the specific language governing permissions and
14fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski * limitations under the License.
15fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski */
16fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
17fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#ifndef __APK_BUILDER_H
18fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#define __APK_BUILDER_H
19fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
20fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include <set>
21fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include <utils/Errors.h>
22fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include <utils/String8.h>
23fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include <utils/StrongPointer.h>
24fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include <utils/Vector.h>
25fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
26fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "ConfigDescription.h"
27fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "OutputSet.h"
28fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#include "ResourceFilter.h"
29fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
30fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiclass ApkSplit;
31fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiclass AaptFile;
32fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
33fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiclass ApkBuilder : public android::RefBase {
34fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskipublic:
35fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    ApkBuilder(const sp<WeakResourceFilter>& configFilter);
36fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
37fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    /**
38fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     * Tells the builder to generate a separate APK for resources that
39fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     * match the configurations specified. Split APKs can not have
40fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     * overlapping resources.
41fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     *
42fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     * NOTE: All splits should be set up before any files are added.
43fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     */
44fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    android::status_t createSplitForConfigs(const std::set<ConfigDescription>& configs);
45fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
46fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    /**
47fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     * Adds a file to be written to the final APK. It's name must not collide
48fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     * with that of any files previously added. When a Split APK is being
49fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     * generated, duplicates can exist as long as they are in different splits
50fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     * (resources.arsc, AndroidManifest.xml).
51fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski     */
52fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    android::status_t addEntry(const String8& path, const android::sp<AaptFile>& file);
53fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
54fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    android::Vector<sp<ApkSplit> >& getSplits() {
55fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return mSplits;
56fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
57fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
583921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski    android::sp<ApkSplit> getBaseSplit() {
593921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski        return mSplits[0];
603921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski    }
613921e87e6e67a063caa1987937d7944b24aef489Adam Lesinski
62fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    void print() const;
63fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
64fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiprivate:
65fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    android::sp<ResourceFilter> mConfigFilter;
66fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    android::sp<AndResourceFilter> mDefaultFilter;
67fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    android::Vector<sp<ApkSplit> > mSplits;
68fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski};
69fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
70fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiclass ApkSplit : public OutputSet {
71fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskipublic:
72fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    android::status_t addEntry(const String8& path, const android::sp<AaptFile>& file);
73fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
74fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const std::set<OutputEntry>& getEntries() const {
75fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return mFiles;
76fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
77fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
78fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const std::set<ConfigDescription>& getConfigs() const {
79fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return mConfigs;
80fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
81fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
82fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    bool matches(const sp<AaptFile>& file) const {
83fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return mFilter->match(file->getGroupEntry().toParams());
84fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
85fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
86fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    sp<ResourceFilter> getResourceFilter() const {
87fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return mFilter;
88fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
89fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
90fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const android::String8& getPrintableName() const {
91fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return mName;
92fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
93fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
94fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const android::String8& getDirectorySafeName() const {
95fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return mDirName;
96fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
97fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
986240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski    const android::String8& getPackageSafeName() const {
996240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski        return mPackageSafeName;
1006240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski    }
1016240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski
102fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    bool isBase() const {
103fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return mIsBase;
104fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
105fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
106fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    void print() const;
107fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
108fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiprivate:
109fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    friend class ApkBuilder;
110fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
111fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    ApkSplit(const std::set<ConfigDescription>& configs, const android::sp<ResourceFilter>& filter, bool isBase=false);
112fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
113fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    std::set<ConfigDescription> mConfigs;
114fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const sp<ResourceFilter> mFilter;
115fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const bool mIsBase;
116fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 mName;
117fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 mDirName;
1186240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski    String8 mPackageSafeName;
119fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    std::set<OutputEntry> mFiles;
120fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski};
121fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
122fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski#endif // __APK_BUILDER_H
123