blob: 3556cd882cf851210cb6eca22561021c041c32fa [file] [log] [blame]
Adam Lesinski59e04c62016-02-04 15:59:23 -08001/*
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"
Adam Lesinski64587af2016-02-18 18:33:06 -080020#include "io/ZipArchive.h"
Adam Lesinski59e04c62016-02-04 15:59:23 -080021#include "process/IResourceTableConsumer.h"
22#include "proto/ProtoSerialize.h"
Adam Lesinski5e8fa3a2016-06-27 16:21:42 -070023#include "unflatten/BinaryResourceParser.h"
Adam Lesinski59e04c62016-02-04 15:59:23 -080024#include "util/Files.h"
25#include "util/StringPiece.h"
26
27#include <vector>
28
29namespace aapt {
30
Adam Lesinskicacb28f2016-10-19 12:18:14 -070031// struct DumpOptions {
Adam Lesinski59e04c62016-02-04 15:59:23 -080032//
33//};
34
Adam Lesinskicacb28f2016-10-19 12:18:14 -070035void dumpCompiledFile(const pb::CompiledFile& pbFile, const void* data,
36 size_t len, const Source& source, IAaptContext* context) {
37 std::unique_ptr<ResourceFile> file =
38 deserializeCompiledFileFromPb(pbFile, source, context->getDiagnostics());
39 if (!file) {
40 context->getDiagnostics()->warn(DiagMessage()
41 << "failed to read compiled file");
42 return;
43 }
Adam Lesinski59e04c62016-02-04 15:59:23 -080044
Adam Lesinskicacb28f2016-10-19 12:18:14 -070045 std::cout << "Resource: " << file->name << "\n"
46 << "Config: " << file->config << "\n"
47 << "Source: " << file->source << "\n";
Adam Lesinski59e04c62016-02-04 15:59:23 -080048}
49
Adam Lesinski59e04c62016-02-04 15:59:23 -080050void tryDumpFile(IAaptContext* context, const std::string& filePath) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070051 std::unique_ptr<ResourceTable> table;
Adam Lesinski5e8fa3a2016-06-27 16:21:42 -070052
Adam Lesinskicacb28f2016-10-19 12:18:14 -070053 std::string err;
54 std::unique_ptr<io::ZipFileCollection> zip =
55 io::ZipFileCollection::create(filePath, &err);
56 if (zip) {
57 io::IFile* file = zip->findFile("resources.arsc.flat");
58 if (file) {
59 std::unique_ptr<io::IData> data = file->openAsData();
60 if (!data) {
61 context->getDiagnostics()->error(
62 DiagMessage(filePath) << "failed to open resources.arsc.flat");
63 return;
64 }
Adam Lesinski64587af2016-02-18 18:33:06 -080065
Adam Lesinskicacb28f2016-10-19 12:18:14 -070066 pb::ResourceTable pbTable;
67 if (!pbTable.ParseFromArray(data->data(), data->size())) {
68 context->getDiagnostics()->error(DiagMessage(filePath)
69 << "invalid resources.arsc.flat");
70 return;
71 }
Adam Lesinski64587af2016-02-18 18:33:06 -080072
Adam Lesinskicacb28f2016-10-19 12:18:14 -070073 table = deserializeTableFromPb(pbTable, Source(filePath),
74 context->getDiagnostics());
75 if (!table) {
76 return;
77 }
Adam Lesinski64587af2016-02-18 18:33:06 -080078 }
79
Adam Lesinski5e8fa3a2016-06-27 16:21:42 -070080 if (!table) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070081 file = zip->findFile("resources.arsc");
82 if (file) {
83 std::unique_ptr<io::IData> data = file->openAsData();
84 if (!data) {
85 context->getDiagnostics()->error(DiagMessage(filePath)
86 << "failed to open resources.arsc");
87 return;
Adam Lesinski5e8fa3a2016-06-27 16:21:42 -070088 }
89
Adam Lesinskicacb28f2016-10-19 12:18:14 -070090 table = util::make_unique<ResourceTable>();
91 BinaryResourceParser parser(context, table.get(), Source(filePath),
92 data->data(), data->size());
93 if (!parser.parse()) {
94 return;
Adam Lesinski5e8fa3a2016-06-27 16:21:42 -070095 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -070096 }
97 }
98 }
Adam Lesinski5e8fa3a2016-06-27 16:21:42 -070099
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700100 if (!table) {
101 Maybe<android::FileMap> file = file::mmapPath(filePath, &err);
102 if (!file) {
103 context->getDiagnostics()->error(DiagMessage(filePath) << err);
104 return;
Adam Lesinski59e04c62016-02-04 15:59:23 -0800105 }
106
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700107 android::FileMap* fileMap = &file.value();
108
109 // Try as a compiled table.
110 pb::ResourceTable pbTable;
111 if (pbTable.ParseFromArray(fileMap->getDataPtr(),
112 fileMap->getDataLength())) {
113 table = deserializeTableFromPb(pbTable, Source(filePath),
114 context->getDiagnostics());
Adam Lesinski59e04c62016-02-04 15:59:23 -0800115 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700116
117 if (!table) {
118 // Try as a compiled file.
119 CompiledFileInputStream input(fileMap->getDataPtr(),
120 fileMap->getDataLength());
121
122 uint32_t numFiles = 0;
123 if (!input.ReadLittleEndian32(&numFiles)) {
124 return;
125 }
126
127 for (uint32_t i = 0; i < numFiles; i++) {
128 pb::CompiledFile compiledFile;
129 if (!input.ReadCompiledFile(&compiledFile)) {
130 context->getDiagnostics()->warn(DiagMessage()
131 << "failed to read compiled file");
132 return;
133 }
134
135 uint64_t offset, len;
136 if (!input.ReadDataMetaData(&offset, &len)) {
137 context->getDiagnostics()->warn(DiagMessage()
138 << "failed to read meta data");
139 return;
140 }
141
142 const void* data =
143 static_cast<const uint8_t*>(fileMap->getDataPtr()) + offset;
144 dumpCompiledFile(compiledFile, data, len, Source(filePath), context);
145 }
146 }
147 }
148
149 if (table) {
150 DebugPrintTableOptions debugPrintTableOptions;
151 debugPrintTableOptions.showSources = true;
152 Debug::printTable(table.get(), debugPrintTableOptions);
153 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800154}
155
156class DumpContext : public IAaptContext {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700157 public:
158 IDiagnostics* getDiagnostics() override { return &mDiagnostics; }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800159
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700160 NameMangler* getNameMangler() override {
161 abort();
162 return nullptr;
163 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800164
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700165 const std::string& getCompilationPackage() override {
166 static std::string empty;
167 return empty;
168 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800169
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700170 uint8_t getPackageId() override { return 0; }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800171
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700172 SymbolTable* getExternalSymbols() override {
173 abort();
174 return nullptr;
175 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800176
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700177 bool verbose() override { return mVerbose; }
Adam Lesinski355f2852016-02-13 20:26:45 -0800178
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700179 void setVerbose(bool val) { mVerbose = val; }
Adam Lesinski355f2852016-02-13 20:26:45 -0800180
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700181 int getMinSdkVersion() override { return 0; }
Adam Lesinskifb6312f2016-06-28 14:40:32 -0700182
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700183 private:
184 StdErrDiagnostics mDiagnostics;
185 bool mVerbose = false;
Adam Lesinski59e04c62016-02-04 15:59:23 -0800186};
187
188/**
189 * Entry point for dump command.
190 */
191int dump(const std::vector<StringPiece>& args) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700192 bool verbose = false;
193 Flags flags =
194 Flags().optionalSwitch("-v", "increase verbosity of output", &verbose);
195 if (!flags.parse("aapt2 dump", args, &std::cerr)) {
196 return 1;
197 }
Adam Lesinski59e04c62016-02-04 15:59:23 -0800198
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700199 DumpContext context;
200 context.setVerbose(verbose);
Adam Lesinski59e04c62016-02-04 15:59:23 -0800201
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700202 for (const std::string& arg : flags.getArgs()) {
203 tryDumpFile(&context, arg);
204 }
205 return 0;
Adam Lesinski59e04c62016-02-04 15:59:23 -0800206}
207
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700208} // namespace aapt