• 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 #include "Debug.h"
18 #include "Diagnostics.h"
19 #include "Flags.h"
20 #include "io/ZipArchive.h"
21 #include "process/IResourceTableConsumer.h"
22 #include "proto/ProtoSerialize.h"
23 #include "util/Files.h"
24 #include "util/StringPiece.h"
25 
26 #include <vector>
27 
28 namespace aapt {
29 
30 //struct DumpOptions {
31 //
32 //};
33 
dumpCompiledFile(const pb::CompiledFile & pbFile,const void * data,size_t len,const Source & source,IAaptContext * context)34 void dumpCompiledFile(const pb::CompiledFile& pbFile, const void* data, size_t len,
35                       const Source& source, IAaptContext* context) {
36     std::unique_ptr<ResourceFile> file = deserializeCompiledFileFromPb(pbFile, source,
37                                                                        context->getDiagnostics());
38     if (!file) {
39         return;
40     }
41 
42     std::cout << "Resource: " << file->name << "\n"
43               << "Config:   " << file->config << "\n"
44               << "Source:   " << file->source << "\n";
45 }
46 
dumpCompiledTable(const pb::ResourceTable & pbTable,const Source & source,IAaptContext * context)47 void dumpCompiledTable(const pb::ResourceTable& pbTable, const Source& source,
48                        IAaptContext* context) {
49     std::unique_ptr<ResourceTable> table = deserializeTableFromPb(pbTable, source,
50                                                                   context->getDiagnostics());
51     if (!table) {
52         return;
53     }
54 
55     Debug::printTable(table.get());
56 }
57 
tryDumpFile(IAaptContext * context,const std::string & filePath)58 void tryDumpFile(IAaptContext* context, const std::string& filePath) {
59     std::string err;
60     std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::create(filePath, &err);
61     if (zip) {
62         io::IFile* file = zip->findFile("resources.arsc.flat");
63         if (file) {
64             std::unique_ptr<io::IData> data = file->openAsData();
65             if (!data) {
66                 context->getDiagnostics()->error(DiagMessage(filePath)
67                                                  << "failed to open resources.arsc.flat");
68                 return;
69             }
70 
71             pb::ResourceTable pbTable;
72             if (!pbTable.ParseFromArray(data->data(), data->size())) {
73                 context->getDiagnostics()->error(DiagMessage(filePath)
74                                                  << "invalid resources.arsc.flat");
75                 return;
76             }
77 
78             std::unique_ptr<ResourceTable> table = deserializeTableFromPb(
79                     pbTable, Source(filePath), context->getDiagnostics());
80             if (table) {
81                 DebugPrintTableOptions debugPrintTableOptions;
82                 debugPrintTableOptions.showSources = true;
83                 Debug::printTable(table.get(), debugPrintTableOptions);
84             }
85         }
86         return;
87     }
88 
89     Maybe<android::FileMap> file = file::mmapPath(filePath, &err);
90     if (!file) {
91         context->getDiagnostics()->error(DiagMessage(filePath) << err);
92         return;
93     }
94 
95     android::FileMap* fileMap = &file.value();
96 
97     // Try as a compiled table.
98     pb::ResourceTable pbTable;
99     if (pbTable.ParseFromArray(fileMap->getDataPtr(), fileMap->getDataLength())) {
100         dumpCompiledTable(pbTable, Source(filePath), context);
101         return;
102     }
103 
104     // Try as a compiled file.
105     CompiledFileInputStream input(fileMap->getDataPtr(), fileMap->getDataLength());
106     if (const pb::CompiledFile* pbFile = input.CompiledFile()) {
107        dumpCompiledFile(*pbFile, input.data(), input.size(), Source(filePath), context);
108        return;
109     }
110 }
111 
112 class DumpContext : public IAaptContext {
113 public:
getDiagnostics()114     IDiagnostics* getDiagnostics() override {
115         return &mDiagnostics;
116     }
117 
getNameMangler()118     NameMangler* getNameMangler() override {
119         abort();
120         return nullptr;
121     }
122 
getCompilationPackage()123     const std::u16string& getCompilationPackage() override {
124         static std::u16string empty;
125         return empty;
126     }
127 
getPackageId()128     uint8_t getPackageId() override {
129         return 0;
130     }
131 
getExternalSymbols()132     SymbolTable* getExternalSymbols() override {
133         abort();
134         return nullptr;
135     }
136 
verbose()137     bool verbose() override {
138         return mVerbose;
139     }
140 
setVerbose(bool val)141     void setVerbose(bool val) {
142         mVerbose = val;
143     }
144 
145 private:
146     StdErrDiagnostics mDiagnostics;
147     bool mVerbose = false;
148 };
149 
150 /**
151  * Entry point for dump command.
152  */
dump(const std::vector<StringPiece> & args)153 int dump(const std::vector<StringPiece>& args) {
154     bool verbose = false;
155     Flags flags = Flags()
156             .optionalSwitch("-v", "increase verbosity of output", &verbose);
157     if (!flags.parse("aapt2 dump", args, &std::cerr)) {
158         return 1;
159     }
160 
161     DumpContext context;
162     context.setVerbose(verbose);
163 
164     for (const std::string& arg : flags.getArgs()) {
165         tryDumpFile(&context, arg);
166     }
167     return 0;
168 }
169 
170 } // namespace aapt
171