dump package name

Test: aapt2 dump packagename foo.apk
Bug: 113105112
Change-Id: Ibea429adc3a2a890be10548824583addc59ad42d
diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp
index b4311c5..29e471e 100644
--- a/tools/aapt2/cmd/Dump.cpp
+++ b/tools/aapt2/cmd/Dump.cpp
@@ -398,6 +398,36 @@
   return 0;
 }
 
+int DumpPackageNameCommand::Action(const std::vector<std::string>& args) {
+  if (args.size() < 1) {
+    diag_->Error(DiagMessage() << "No dump apk specified.");
+    return 1;
+  }
+
+  auto loaded_apk = LoadedApk::LoadApkFromPath(args[0], diag_);
+  if (!loaded_apk) {
+    return 1;
+  }
+
+  io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
+  Printer printer(&fout);
+
+  xml::Element* manifest_el = loaded_apk->GetManifest()->root.get();
+  if (!manifest_el) {
+    diag_->Error(DiagMessage() << "No AndroidManifest.");
+    return 1;
+  }
+
+  xml::Attribute* attr = manifest_el->FindAttribute({}, "package");
+  if (!attr) {
+    diag_->Error(DiagMessage() << "No package name.");
+    return 1;
+  }
+  printer.Println(StringPrintf("%s", attr->value.c_str()));
+
+  return 0;
+}
+
 /** Preform no action because a subcommand is required. */
 int DumpCommand::Action(const std::vector<std::string>& args) {
   if (args.size() == 0) {
diff --git a/tools/aapt2/cmd/Dump.h b/tools/aapt2/cmd/Dump.h
index 03a4fba..0724d62 100644
--- a/tools/aapt2/cmd/Dump.h
+++ b/tools/aapt2/cmd/Dump.h
@@ -115,12 +115,26 @@
   std::vector<std::string> files_;
 };
 
-/** The default dump command. Preforms no action because a subcommand is required. */
+/** Prints the contents of the resource table from the APK. */
+class DumpPackageNameCommand : public Command {
+ public:
+  explicit DumpPackageNameCommand(IDiagnostics* diag) : Command("packagename"), diag_(diag) {
+    SetDescription("Print the package name of the APK.");
+  }
+
+  int Action(const std::vector<std::string>& args) override;
+
+ private:
+  IDiagnostics* diag_;
+};
+
+/** The default dump command. Performs no action because a subcommand is required. */
 class DumpCommand : public Command {
  public:
   explicit DumpCommand(IDiagnostics* diag) : Command("dump", "d"), diag_(diag) {
     AddOptionalSubcommand(util::make_unique<DumpAPCCommand>(diag_));
     AddOptionalSubcommand(util::make_unique<DumpConfigsCommand>(diag_));
+    AddOptionalSubcommand(util::make_unique<DumpPackageNameCommand>(diag_));
     AddOptionalSubcommand(util::make_unique<DumpStringsCommand>(diag_));
     AddOptionalSubcommand(util::make_unique<DumpTableCommand>(diag_));
     AddOptionalSubcommand(util::make_unique<DumpXmlStringsCommand>(diag_));