blob: cd215b00db227fcf17e6b26856f78d70721b6c34 [file] [log] [blame]
Ryan Mitchell833a1a62018-07-10 13:51:36 -07001/*
2 * Copyright (C) 2018 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 AAPT2_DUMP_H
18#define AAPT2_DUMP_H
19
20#include "Command.h"
21#include "Debug.h"
Ryan Mitchell214846d2018-09-19 16:57:01 -070022#include "LoadedApk.h"
Ryan Mitchellfc225b22018-08-21 14:52:51 -070023#include "dump/DumpManifest.h"
Ryan Mitchell833a1a62018-07-10 13:51:36 -070024
25namespace aapt {
26
Ryan Mitchell214846d2018-09-19 16:57:01 -070027/**
28 * The base command for dumping information about apks. When the command is executed, the command
29 * performs the DumpApkCommand::Dump() operation on each apk provided as a file argument.
30 **/
31class DumpApkCommand : public Command {
32 public:
33 explicit DumpApkCommand(const std::string&& name, text::Printer* printer, IDiagnostics* diag)
34 : Command(name), printer_(printer), diag_(diag) {
35 }
36
37 text::Printer* GetPrinter() {
38 return printer_;
39 }
40
41 IDiagnostics* GetDiagnostics() {
42 return diag_;
43 }
44
45 /** Perform the dump operation on the apk. */
46 virtual int Dump(LoadedApk* apk) = 0;
47
48 int Action(const std::vector<std::string>& args) final {
49 if (args.size() < 1) {
50 diag_->Error(DiagMessage() << "No dump apk specified.");
51 return 1;
52 }
53
54 bool error = false;
55 for (auto apk : args) {
56 auto loaded_apk = LoadedApk::LoadApkFromPath(apk, diag_);
57 if (!loaded_apk) {
58 error = true;
59 continue;
60 }
61
62 error |= Dump(loaded_apk.get());
63 }
64
65 return error;
66 }
67
68 private:
69 text::Printer* printer_;
70 IDiagnostics* diag_;
71};
72
73/** Command that prints contents of files generated from the compilation stage. */
Ryan Mitchell5d275512018-07-19 14:29:00 -070074class DumpAPCCommand : public Command {
Ryan Mitchell833a1a62018-07-10 13:51:36 -070075 public:
Ryan Mitchell214846d2018-09-19 16:57:01 -070076 explicit DumpAPCCommand(text::Printer* printer, IDiagnostics* diag)
77 : Command("apc"), printer_(printer), diag_(diag) {
Ryan Mitchell5d275512018-07-19 14:29:00 -070078 SetDescription("Print the contents of the AAPT2 Container (APC) generated fom compilation.");
Ryan Mitchell833a1a62018-07-10 13:51:36 -070079 AddOptionalSwitch("--no-values", "Suppresses output of values when displaying resource tables.",
Ryan Mitchell5d275512018-07-19 14:29:00 -070080 &no_values_);
81 AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
Ryan Mitchell833a1a62018-07-10 13:51:36 -070082 }
83
84 int Action(const std::vector<std::string>& args) override;
85
86 private:
Ryan Mitchell214846d2018-09-19 16:57:01 -070087 text::Printer* printer_;
Ryan Mitchell5d275512018-07-19 14:29:00 -070088 IDiagnostics* diag_;
Ryan Mitchell833a1a62018-07-10 13:51:36 -070089 bool no_values_ = false;
Ryan Mitchell214846d2018-09-19 16:57:01 -070090 bool verbose_ = false;
Ryan Mitchell833a1a62018-07-10 13:51:36 -070091};
92
Ryan Mitchell214846d2018-09-19 16:57:01 -070093/** Easter egg command shown when users enter "badger" instead of "badging". */
94class DumpBadgerCommand : public Command {
Ryan Mitchell5d275512018-07-19 14:29:00 -070095 public:
Ryan Mitchell214846d2018-09-19 16:57:01 -070096 explicit DumpBadgerCommand(text::Printer* printer) : Command("badger"), printer_(printer) {
Ryan Mitchell5d275512018-07-19 14:29:00 -070097 }
98
99 int Action(const std::vector<std::string>& args) override;
100
101 private:
Ryan Mitchell214846d2018-09-19 16:57:01 -0700102 text::Printer* printer_;
103 const static char kBadgerData[2925];
Ryan Mitchell5d275512018-07-19 14:29:00 -0700104};
105
Ryan Mitchell214846d2018-09-19 16:57:01 -0700106class DumpBadgingCommand : public DumpApkCommand {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700107 public:
Ryan Mitchell214846d2018-09-19 16:57:01 -0700108 explicit DumpBadgingCommand(text::Printer* printer, IDiagnostics* diag)
109 : DumpApkCommand("badging", printer, diag) {
110 SetDescription("Print information extracted from the manifest of the APK.");
111 AddOptionalSwitch("--include-meta-data", "Include meta-data information.",
112 &options_.include_meta_data);
113 }
114
115 int Dump(LoadedApk* apk) override {
116 return DumpManifest(apk, options_, GetPrinter(), GetDiagnostics());
117 }
118
119 private:
120 DumpManifestOptions options_;
121};
122
123class DumpConfigsCommand : public DumpApkCommand {
124 public:
125 explicit DumpConfigsCommand(text::Printer* printer, IDiagnostics* diag)
126 : DumpApkCommand("configurations", printer, diag) {
127 SetDescription("Print every configuration used by a resource in the APK.");
128 }
129
130 int Dump(LoadedApk* apk) override;
131};
132
133class DumpPackageNameCommand : public DumpApkCommand {
134 public:
135 explicit DumpPackageNameCommand(text::Printer* printer, IDiagnostics* diag)
136 : DumpApkCommand("packagename", printer, diag) {
137 SetDescription("Print the package name of the APK.");
138 }
139
140 int Dump(LoadedApk* apk) override;
141};
142
143class DumpPermissionsCommand : public DumpApkCommand {
144 public:
145 explicit DumpPermissionsCommand(text::Printer* printer, IDiagnostics* diag)
146 : DumpApkCommand("permissions", printer, diag) {
147 SetDescription("Print the permissions extracted from the manifest of the APK.");
148 }
149
150 int Dump(LoadedApk* apk) override {
151 DumpManifestOptions options;
152 options.only_permissions = true;
153 return DumpManifest(apk, options, GetPrinter(), GetDiagnostics());
154 }
155};
156
157class DumpStringsCommand : public DumpApkCommand {
158 public:
159 explicit DumpStringsCommand(text::Printer* printer, IDiagnostics* diag)
160 : DumpApkCommand("strings", printer, diag) {
161 SetDescription("Print the contents of the resource table string pool in the APK.");
162 }
163
164 int Dump(LoadedApk* apk) override;
165};
166
167class DumpTableCommand : public DumpApkCommand {
168 public:
169 explicit DumpTableCommand(text::Printer* printer, IDiagnostics* diag)
170 : DumpApkCommand("resources", printer, diag) {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700171 SetDescription("Print the contents of the resource table from the APK.");
172 AddOptionalSwitch("--no-values", "Suppresses output of values when displaying resource tables.",
173 &no_values_);
174 AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
175 }
176
Ryan Mitchell214846d2018-09-19 16:57:01 -0700177 int Dump(LoadedApk* apk) override;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700178
179 private:
Ryan Mitchell5d275512018-07-19 14:29:00 -0700180 bool no_values_ = false;
Ryan Mitchell214846d2018-09-19 16:57:01 -0700181 bool verbose_ = false;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700182};
183
Ryan Mitchell214846d2018-09-19 16:57:01 -0700184class DumpXmlStringsCommand : public DumpApkCommand {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700185 public:
Ryan Mitchell214846d2018-09-19 16:57:01 -0700186 explicit DumpXmlStringsCommand(text::Printer* printer, IDiagnostics* diag)
187 : DumpApkCommand("xmlstrings", printer, diag) {
188 SetDescription("Print the string pool of a compiled xml in an APK.");
189 AddRequiredFlagList("--file", "A compiled xml file to print", &files_);
190 }
191
192 int Dump(LoadedApk* apk) override;
193
194 private:
195 std::vector<std::string> files_;
196};
197
198class DumpXmlTreeCommand : public DumpApkCommand {
199 public:
200 explicit DumpXmlTreeCommand(text::Printer* printer, IDiagnostics* diag)
201 : DumpApkCommand("xmltree", printer, diag) {
Ryan Mitchell5d275512018-07-19 14:29:00 -0700202 SetDescription("Print the tree of a compiled xml in an APK.");
203 AddRequiredFlagList("--file", "A compiled xml file to print", &files_);
204 }
205
Ryan Mitchell214846d2018-09-19 16:57:01 -0700206 int Dump(LoadedApk* apk) override;
Ryan Mitchell5d275512018-07-19 14:29:00 -0700207
208 private:
Ryan Mitchell5d275512018-07-19 14:29:00 -0700209 std::vector<std::string> files_;
210};
211
Todd Kennedy908b7fc2018-08-24 10:11:21 -0700212/** The default dump command. Performs no action because a subcommand is required. */
Ryan Mitchell5d275512018-07-19 14:29:00 -0700213class DumpCommand : public Command {
214 public:
Ryan Mitchell214846d2018-09-19 16:57:01 -0700215 explicit DumpCommand(text::Printer* printer, IDiagnostics* diag)
216 : Command("dump", "d"), diag_(diag) {
217 AddOptionalSubcommand(util::make_unique<DumpAPCCommand>(printer, diag_));
218 AddOptionalSubcommand(util::make_unique<DumpBadgingCommand>(printer, diag_));
219 AddOptionalSubcommand(util::make_unique<DumpConfigsCommand>(printer, diag_));
220 AddOptionalSubcommand(util::make_unique<DumpPackageNameCommand>(printer, diag_));
221 AddOptionalSubcommand(util::make_unique<DumpPermissionsCommand>(printer, diag_));
222 AddOptionalSubcommand(util::make_unique<DumpStringsCommand>(printer, diag_));
223 AddOptionalSubcommand(util::make_unique<DumpTableCommand>(printer, diag_));
224 AddOptionalSubcommand(util::make_unique<DumpXmlStringsCommand>(printer, diag_));
225 AddOptionalSubcommand(util::make_unique<DumpXmlTreeCommand>(printer, diag_));
226 AddOptionalSubcommand(util::make_unique<DumpBadgerCommand>(printer), /* hidden */ true);
Ryan Mitchell5d275512018-07-19 14:29:00 -0700227 }
228
Ryan Mitchell214846d2018-09-19 16:57:01 -0700229 int Action(const std::vector<std::string>& args) override {
230 if (args.size() == 0) {
231 diag_->Error(DiagMessage() << "no subcommand specified");
232 } else {
233 diag_->Error(DiagMessage() << "unknown subcommand '" << args[0] << "'");
234 }
235 Usage(&std::cerr);
236 return 1;
237 }
Ryan Mitchell5d275512018-07-19 14:29:00 -0700238
239 private:
240 IDiagnostics* diag_;
241};
242
Ryan Mitchell214846d2018-09-19 16:57:01 -0700243} // namespace aapt
Ryan Mitchell833a1a62018-07-10 13:51:36 -0700244
Ryan Mitchell214846d2018-09-19 16:57:01 -0700245#endif // AAPT2_DUMP_H