OMS: include idmap data in dump

Teach the overlay manager to ask the idmap service to pretty print the
contents of each idmap file as part of OMS dump. This creates a single
entry point for dumping both OMS and idmap data, and circumvents the
problem of accessing the idmap service if it has been killed due to
inactivity.

Example idmap section:

---- 8< ----
IDMAP OF com.android.theme.color.sand
Paths:
    target path  : /system/framework/framework-res.apk
    overlay path : /product/overlay/AccentColorSand/AccentColorSandOverlay.apk
Debug info:
    W failed to find resource 'string/accent_color_overlay'
Mapping:
    0x0106006e -> 0x7f010000 (color/accent_device_default_dark -> color/accent_device_default_dark)
    0x01060070 -> 0x7f010001 (color/accent_device_default_light -> color/accent_device_default_light)
---- >8 ----

Bug: 189963636
Test: adb exec-out dumpsys
Test: adb exec-out cmd overlay dump
Test: adb exec-out cmd overlay dump <overlay-identifier>
Change-Id: I9de6ba646ad4714c9d0f0d8081fbf632577107e7
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp
index 4f775aa..73a7240 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.cpp
+++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp
@@ -33,6 +33,7 @@
 #include "idmap2/BinaryStreamVisitor.h"
 #include "idmap2/FileUtils.h"
 #include "idmap2/Idmap.h"
+#include "idmap2/PrettyPrintVisitor.h"
 #include "idmap2/Result.h"
 #include "idmap2/SysTrace.h"
 
@@ -45,6 +46,7 @@
 using android::idmap2::Idmap;
 using android::idmap2::IdmapHeader;
 using android::idmap2::OverlayResourceContainer;
+using android::idmap2::PrettyPrintVisitor;
 using android::idmap2::TargetResourceContainer;
 using android::idmap2::utils::kIdmapCacheDir;
 using android::idmap2::utils::kIdmapFilePermissionMask;
@@ -352,4 +354,24 @@
   return ok();
 }
 
+binder::Status Idmap2Service::dumpIdmap(const std::string& overlay_path,
+                                        std::string* _aidl_return) {
+  assert(_aidl_return);
+
+  const auto idmap_path = Idmap::CanonicalIdmapPathFor(kIdmapCacheDir, overlay_path);
+  std::ifstream fin(idmap_path);
+  const auto idmap = Idmap::FromBinaryStream(fin);
+  fin.close();
+  if (!idmap) {
+    return error(idmap.GetErrorMessage());
+  }
+
+  std::stringstream stream;
+  PrettyPrintVisitor visitor(stream);
+  (*idmap)->accept(&visitor);
+  *_aidl_return = stream.str();
+
+  return ok();
+}
+
 }  // namespace android::os
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.h b/cmds/idmap2/idmap2d/Idmap2Service.h
index 4d16ff3..40843f7 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.h
+++ b/cmds/idmap2/idmap2d/Idmap2Service.h
@@ -60,6 +60,8 @@
   binder::Status getFabricatedOverlayInfos(
       std::vector<os::FabricatedOverlayInfo>* _aidl_return) override;
 
+  binder::Status dumpIdmap(const std::string& overlay_path, std::string* _aidl_return) override;
+
  private:
   // idmap2d is killed after a period of inactivity, so any information stored on this class should
   // be able to be recalculated if idmap2 dies and restarts.
diff --git a/cmds/idmap2/idmap2d/aidl/services/android/os/IIdmap2.aidl b/cmds/idmap2/idmap2d/aidl/services/android/os/IIdmap2.aidl
index 35bca98..48cee69 100644
--- a/cmds/idmap2/idmap2d/aidl/services/android/os/IIdmap2.aidl
+++ b/cmds/idmap2/idmap2d/aidl/services/android/os/IIdmap2.aidl
@@ -16,8 +16,8 @@
 
 package android.os;
 
-import android.os.FabricatedOverlayInternal;
 import android.os.FabricatedOverlayInfo;
+import android.os.FabricatedOverlayInternal;
 
 /**
  * @hide
@@ -40,4 +40,5 @@
   @nullable FabricatedOverlayInfo createFabricatedOverlay(in FabricatedOverlayInternal overlay);
   List<FabricatedOverlayInfo> getFabricatedOverlayInfos();
   boolean deleteFabricatedOverlay(@utf8InCpp String path);
+  @utf8InCpp String dumpIdmap(@utf8InCpp String overlayApkPath);
 }