• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef AAPT_LOADEDAPK_H
18 #define AAPT_LOADEDAPK_H
19 
20 #include "androidfw/StringPiece.h"
21 
22 #include "ResourceTable.h"
23 #include "filter/Filter.h"
24 #include "format/Archive.h"
25 #include "format/binary/BinaryResourceParser.h"
26 #include "format/binary/TableFlattener.h"
27 #include "io/ZipArchive.h"
28 #include "xml/XmlDom.h"
29 
30 namespace aapt {
31 
32 constexpr static const char kApkResourceTablePath[] = "resources.arsc";
33 constexpr static const char kProtoResourceTablePath[] = "resources.pb";
34 constexpr static const char kAndroidManifestPath[] = "AndroidManifest.xml";
35 
36 enum ApkFormat {
37   kUnknown,
38   kBinary,
39   kProto,
40 };
41 
42 // Info about an APK loaded in memory.
43 class LoadedApk final {
44  public:
45   // Loads both binary and proto APKs from disk.
46   static std::unique_ptr<LoadedApk> LoadApkFromPath(android::StringPiece path,
47                                                     android::IDiagnostics* diag);
48 
49   // Loads a proto APK from the given file collection.
50   static std::unique_ptr<LoadedApk> LoadProtoApkFromFileCollection(
51       const android::Source& source, std::unique_ptr<io::IFileCollection> collection,
52       android::IDiagnostics* diag);
53 
54   // Loads a binary APK from the given file collection.
55   static std::unique_ptr<LoadedApk> LoadBinaryApkFromFileCollection(
56       const android::Source& source, std::unique_ptr<io::IFileCollection> collection,
57       android::IDiagnostics* diag);
58 
LoadedApk(const android::Source & source,std::unique_ptr<io::IFileCollection> apk,std::unique_ptr<ResourceTable> table,std::unique_ptr<xml::XmlResource> manifest,const ApkFormat & format)59   LoadedApk(const android::Source& source, std::unique_ptr<io::IFileCollection> apk,
60             std::unique_ptr<ResourceTable> table, std::unique_ptr<xml::XmlResource> manifest,
61             const ApkFormat& format)
62       : source_(source),
63         apk_(std::move(apk)),
64         table_(std::move(table)),
65         manifest_(std::move(manifest)),
66         format_(format) {
67   }
68 
GetFileCollection()69   io::IFileCollection* GetFileCollection() {
70     return apk_.get();
71   }
72 
GetApkFormat()73   ApkFormat GetApkFormat() {
74     return format_;
75   }
76 
GetResourceTable()77   const ResourceTable* GetResourceTable() const {
78     return table_.get();
79   }
80 
GetResourceTable()81   ResourceTable* GetResourceTable() {
82     return table_.get();
83   }
84 
GetSource()85   const android::Source& GetSource() {
86     return source_;
87   }
88 
GetManifest()89   const xml::XmlResource* GetManifest() const {
90     return manifest_.get();
91   }
92 
93   /**
94    * Writes the APK on disk at the given path, while also removing the resource
95    * files that are not referenced in the resource table.
96    */
97   bool WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options,
98                       IArchiveWriter* writer);
99 
100   /**
101    * Writes the APK on disk at the given path, while also removing the resource files that are not
102    * referenced in the resource table. The provided filter chain is applied to each entry in the APK
103    * file.
104    *
105    * If the manifest is also provided, it will be written to the new APK file, otherwise the
106    * original manifest will be written. The manifest is only required if the contents of the new APK
107    * have been modified in a way that require the AndroidManifest.xml to also be modified.
108    */
109   bool WriteToArchive(IAaptContext* context, ResourceTable* split_table,
110                       const TableFlattenerOptions& options, FilterChain* filters,
111                       IArchiveWriter* writer, xml::XmlResource* manifest = nullptr);
112 
113   /** Loads the file as an xml document. */
114   std::unique_ptr<xml::XmlResource> LoadXml(const std::string& file_path,
115                                             android::IDiagnostics* diag) const;
116 
117  private:
118   DISALLOW_COPY_AND_ASSIGN(LoadedApk);
119 
120   android::Source source_;
121   std::unique_ptr<io::IFileCollection> apk_;
122   std::unique_ptr<ResourceTable> table_;
123   std::unique_ptr<xml::XmlResource> manifest_;
124   ApkFormat format_;
125 };
126 
127 }  // namespace aapt
128 
129 #endif /* AAPT_LOADEDAPK_H */
130