Home | History | Annotate | Download | only in aapt2
      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 {
     44  public:
     45   virtual ~LoadedApk() = default;
     46 
     47   // Loads both binary and proto APKs from disk.
     48   static std::unique_ptr<LoadedApk> LoadApkFromPath(const ::android::StringPiece& path,
     49                                                     IDiagnostics* diag);
     50 
     51   // Loads a proto APK from the given file collection.
     52   static std::unique_ptr<LoadedApk> LoadProtoApkFromFileCollection(
     53       const Source& source, std::unique_ptr<io::IFileCollection> collection, IDiagnostics* diag);
     54 
     55   // Loads a binary APK from the given file collection.
     56   static std::unique_ptr<LoadedApk> LoadBinaryApkFromFileCollection(
     57       const Source& source, std::unique_ptr<io::IFileCollection> collection, IDiagnostics* diag);
     58 
     59   LoadedApk(const 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 
     69   io::IFileCollection* GetFileCollection() {
     70     return apk_.get();
     71   }
     72 
     73   const ResourceTable* GetResourceTable() const {
     74     return table_.get();
     75   }
     76 
     77   ResourceTable* GetResourceTable() {
     78     return table_.get();
     79   }
     80 
     81   const Source& GetSource() {
     82     return source_;
     83   }
     84 
     85   const xml::XmlResource* GetManifest() const {
     86     return manifest_.get();
     87   }
     88 
     89   /**
     90    * Writes the APK on disk at the given path, while also removing the resource
     91    * files that are not referenced in the resource table.
     92    */
     93   virtual bool WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options,
     94                               IArchiveWriter* writer);
     95 
     96   /**
     97    * Writes the APK on disk at the given path, while also removing the resource files that are not
     98    * referenced in the resource table. The provided filter chain is applied to each entry in the APK
     99    * file.
    100    *
    101    * If the manifest is also provided, it will be written to the new APK file, otherwise the
    102    * original manifest will be written. The manifest is only required if the contents of the new APK
    103    * have been modified in a way that require the AndroidManifest.xml to also be modified.
    104    */
    105   virtual bool WriteToArchive(IAaptContext* context, ResourceTable* split_table,
    106                               const TableFlattenerOptions& options, FilterChain* filters,
    107                               IArchiveWriter* writer, xml::XmlResource* manifest = nullptr);
    108 
    109 
    110  private:
    111   DISALLOW_COPY_AND_ASSIGN(LoadedApk);
    112 
    113   Source source_;
    114   std::unique_ptr<io::IFileCollection> apk_;
    115   std::unique_ptr<ResourceTable> table_;
    116   std::unique_ptr<xml::XmlResource> manifest_;
    117   ApkFormat format_;
    118 
    119   static ApkFormat DetermineApkFormat(io::IFileCollection* apk);
    120 };
    121 
    122 }  // namespace aapt
    123 
    124 #endif /* AAPT_LOADEDAPK_H */
    125