Merge changes I6da18cdb,I9de6ba64,I1af88c6d,I154783ff into sc-dev

* changes:
  idmap2: fix cpplint warnings
  OMS: include idmap data in dump
  idmap2: create in-memory FRRO before creating file
  OMS: update shell command --help
diff --git a/cmds/idmap2/CPPLINT.cfg b/cmds/idmap2/CPPLINT.cfg
index 20ed43c..eada694 100644
--- a/cmds/idmap2/CPPLINT.cfg
+++ b/cmds/idmap2/CPPLINT.cfg
@@ -15,4 +15,4 @@
 set noparent
 linelength=100
 root=..
-filter=+build/include_alpha,-runtime/references,-build/c++
+filter=+build/include_alpha,-runtime/references,-build/c++,-build/include_alpha
diff --git a/cmds/idmap2/idmap2/CommandUtils.cpp b/cmds/idmap2/idmap2/CommandUtils.cpp
index bf30a76..63235ff 100644
--- a/cmds/idmap2/idmap2/CommandUtils.cpp
+++ b/cmds/idmap2/idmap2/CommandUtils.cpp
@@ -19,6 +19,7 @@
 #include <string>
 #include <vector>
 
+#include "idmap2/CommandUtils.h"
 #include "idmap2/Idmap.h"
 #include "idmap2/Result.h"
 #include "idmap2/SysTrace.h"
diff --git a/cmds/idmap2/idmap2/CommandUtils.h b/cmds/idmap2/idmap2/CommandUtils.h
index e068967..341fec8 100644
--- a/cmds/idmap2/idmap2/CommandUtils.h
+++ b/cmds/idmap2/idmap2/CommandUtils.h
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef IDMAP2_IDMAP2_COMMAND_UTILS_H_
-#define IDMAP2_IDMAP2_COMMAND_UTILS_H_
+#ifndef IDMAP2_IDMAP2_COMMANDUTILS_H_
+#define IDMAP2_IDMAP2_COMMANDUTILS_H_
+
+#include <string>
 
 #include "idmap2/PolicyUtils.h"
 #include "idmap2/Result.h"
@@ -24,4 +26,4 @@
     const std::string& idmap_path, const std::string& target_path, const std::string& overlay_path,
     const std::string& overlay_name, PolicyBitmask fulfilled_policies, bool enforce_overlayable);
 
-#endif  // IDMAP2_IDMAP2_COMMAND_UTILS_H_
+#endif  // IDMAP2_IDMAP2_COMMANDUTILS_H_
diff --git a/cmds/idmap2/idmap2/Create.cpp b/cmds/idmap2/idmap2/Create.cpp
index 977a0bb..d5f1b89 100644
--- a/cmds/idmap2/idmap2/Create.cpp
+++ b/cmds/idmap2/idmap2/Create.cpp
@@ -20,6 +20,7 @@
 #include <fstream>
 #include <memory>
 #include <ostream>
+#include <string>
 #include <vector>
 
 #include "androidfw/ResourceTypes.h"
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp
index 05336ba..2cfbac3 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.cpp
+++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp
@@ -26,6 +26,8 @@
 #include <memory>
 #include <ostream>
 #include <string>
+#include <utility>
+#include <vector>
 
 #include "android-base/macros.h"
 #include "android-base/stringprintf.h"
@@ -33,6 +35,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 +48,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;
@@ -262,17 +266,17 @@
                                     path.c_str(), uid));
   }
 
+  const auto frro = builder.Build();
+  if (!frro) {
+    return error(StringPrintf("failed to serialize '%s:%s': %s", overlay.packageName.c_str(),
+                              overlay.overlayName.c_str(), frro.GetErrorMessage().c_str()));
+  }
   // Persist the fabricated overlay.
   umask(kIdmapFilePermissionMask);
   std::ofstream fout(path);
   if (fout.fail()) {
     return error("failed to open frro path " + path);
   }
-  const auto frro = builder.Build();
-  if (!frro) {
-    return error(StringPrintf("failed to serialize '%s:%s': %s", overlay.packageName.c_str(),
-                              overlay.overlayName.c_str(), frro.GetErrorMessage().c_str()));
-  }
   auto result = frro->ToBinaryStream(fout);
   if (!result) {
     unlink(path.c_str());
@@ -352,4 +356,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..c16c3c5 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.h
+++ b/cmds/idmap2/idmap2d/Idmap2Service.h
@@ -24,7 +24,9 @@
 #include <idmap2/ResourceContainer.h>
 #include <idmap2/Result.h>
 
+#include <memory>
 #include <string>
+#include <vector>
 
 namespace android::os {
 
@@ -60,6 +62,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);
 }
diff --git a/cmds/idmap2/include/idmap2/FabricatedOverlay.h b/cmds/idmap2/include/idmap2/FabricatedOverlay.h
index be687d9..3756718 100644
--- a/cmds/idmap2/include/idmap2/FabricatedOverlay.h
+++ b/cmds/idmap2/include/idmap2/FabricatedOverlay.h
@@ -14,15 +14,17 @@
  * limitations under the License.
  */
 
-#ifndef IDMAP2_INCLUDE_IDMAP2_FABRICATEDOVERLAY_H
-#define IDMAP2_INCLUDE_IDMAP2_FABRICATEDOVERLAY_H
+#ifndef IDMAP2_INCLUDE_IDMAP2_FABRICATEDOVERLAY_H_
+#define IDMAP2_INCLUDE_IDMAP2_FABRICATEDOVERLAY_H_
 
 #include <libidmap2/proto/fabricated_v1.pb.h>
 
 #include <iostream>
 #include <map>
 #include <memory>
+#include <string>
 #include <unordered_map>
+#include <vector>
 
 #include "idmap2/ResourceContainer.h"
 #include "idmap2/Result.h"
@@ -68,7 +70,8 @@
   Result<SerializedData*> InitializeData() const;
   Result<uint32_t> GetCrc() const;
 
-  FabricatedOverlay(pb::FabricatedOverlay&& overlay, std::optional<uint32_t> crc_from_disk = {});
+  explicit FabricatedOverlay(pb::FabricatedOverlay&& overlay,
+                             std::optional<uint32_t> crc_from_disk = {});
 
   pb::FabricatedOverlay overlay_pb_;
   std::optional<uint32_t> crc_from_disk_;
@@ -102,4 +105,4 @@
 
 }  // namespace android::idmap2
 
-#endif  // IDMAP2_INCLUDE_IDMAP2_FABRICATEDOVERLAY_H
+#endif  // IDMAP2_INCLUDE_IDMAP2_FABRICATEDOVERLAY_H_
diff --git a/cmds/idmap2/include/idmap2/ResourceContainer.h b/cmds/idmap2/include/idmap2/ResourceContainer.h
index 74a6f56..c3ba464 100644
--- a/cmds/idmap2/include/idmap2/ResourceContainer.h
+++ b/cmds/idmap2/include/idmap2/ResourceContainer.h
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef IDMAP2_INCLUDE_IDMAP2_RESOURCECONTAINER_H
-#define IDMAP2_INCLUDE_IDMAP2_RESOURCECONTAINER_H
+#ifndef IDMAP2_INCLUDE_IDMAP2_RESOURCECONTAINER_H_
+#define IDMAP2_INCLUDE_IDMAP2_RESOURCECONTAINER_H_
 
+#include <memory>
 #include <string>
 #include <variant>
 #include <vector>
@@ -103,4 +104,4 @@
 
 }  // namespace android::idmap2
 
-#endif  // IDMAP2_INCLUDE_IDMAP2_RESOURCECONTAINER_H
+#endif  // IDMAP2_INCLUDE_IDMAP2_RESOURCECONTAINER_H_
diff --git a/cmds/idmap2/libidmap2/FabricatedOverlay.cpp b/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
index 4f61801..8352dbb 100644
--- a/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
+++ b/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
@@ -23,6 +23,10 @@
 #include <zlib.h>
 
 #include <fstream>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
 
 namespace android::idmap2 {
 
@@ -89,7 +93,7 @@
     auto package = entries.find(package_name);
     if (package == entries.end()) {
       package = entries
-                    .insert(std::make_pair<>(
+                    .insert(std::make_pair(
                         package_name, std::map<std::string, std::map<std::string, TargetValue>>()))
                     .first;
     }
@@ -98,13 +102,13 @@
     if (type == package->second.end()) {
       type =
           package->second
-              .insert(std::make_pair<>(type_name.to_string(), std::map<std::string, TargetValue>()))
+              .insert(std::make_pair(type_name.to_string(), std::map<std::string, TargetValue>()))
               .first;
     }
 
     auto entry = type->second.find(entry_name.to_string());
     if (entry == type->second.end()) {
-      entry = type->second.insert(std::make_pair<>(entry_name.to_string(), TargetValue())).first;
+      entry = type->second.insert(std::make_pair(entry_name.to_string(), TargetValue())).first;
     }
 
     entry->second = TargetValue{res_entry.data_type, res_entry.data_value};
@@ -299,4 +303,4 @@
   return Error("Fabricated overlay does not contain resources.");
 }
 
-}  // namespace android::idmap2
\ No newline at end of file
+}  // namespace android::idmap2
diff --git a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
index 721612c..d10a278 100644
--- a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
+++ b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
@@ -18,6 +18,7 @@
 
 #include <istream>
 #include <string>
+#include <utility>
 
 #include "android-base/macros.h"
 #include "android-base/stringprintf.h"
diff --git a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
index a016a36..779538c 100644
--- a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
+++ b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
@@ -18,6 +18,8 @@
 
 #include <algorithm>
 #include <cstdarg>
+#include <string>
+#include <utility>
 
 #include "android-base/macros.h"
 #include "android-base/stringprintf.h"
diff --git a/cmds/idmap2/libidmap2/ResourceContainer.cpp b/cmds/idmap2/libidmap2/ResourceContainer.cpp
index c147f6a..a62472c 100644
--- a/cmds/idmap2/libidmap2/ResourceContainer.cpp
+++ b/cmds/idmap2/libidmap2/ResourceContainer.cpp
@@ -16,6 +16,11 @@
 
 #include "idmap2/ResourceContainer.h"
 
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
 #include "androidfw/ApkAssets.h"
 #include "androidfw/AssetManager.h"
 #include "androidfw/Util.h"
@@ -445,4 +450,4 @@
   return std::unique_ptr<OverlayResourceContainer>(result->release());
 }
 
-}  // namespace android::idmap2
\ No newline at end of file
+}  // namespace android::idmap2
diff --git a/cmds/idmap2/libidmap2/ResourceUtils.cpp b/cmds/idmap2/libidmap2/ResourceUtils.cpp
index e809bf1..32c04d2 100644
--- a/cmds/idmap2/libidmap2/ResourceUtils.cpp
+++ b/cmds/idmap2/libidmap2/ResourceUtils.cpp
@@ -17,6 +17,7 @@
 #include "idmap2/ResourceUtils.h"
 
 #include <memory>
+#include <string>
 
 #include "androidfw/StringPiece.h"
 #include "androidfw/Util.h"
diff --git a/cmds/idmap2/tests/FabricatedOverlayTests.cpp b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
index 79ab243..468ea0c 100644
--- a/cmds/idmap2/tests/FabricatedOverlayTests.cpp
+++ b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
@@ -19,6 +19,7 @@
 #include <idmap2/FabricatedOverlay.h>
 
 #include <fstream>
+#include <utility>
 
 namespace android::idmap2 {
 
@@ -135,4 +136,4 @@
   EXPECT_EQ(Res_value::TYPE_INT_DEC, entry->data_type);
 }
 
-}  // namespace android::idmap2
\ No newline at end of file
+}  // namespace android::idmap2
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 9516ff8..9c6402a 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -83,7 +83,7 @@
   std::stringstream stream;
   stream << android::kIdmapMagic;
   stream << 0xffffffffU;
-  stream << std::string(kJunkSize, (char)0xffU);
+  stream << std::string(kJunkSize, static_cast<char>(0xffU));
   ASSERT_FALSE(Idmap::FromBinaryStream(stream));
 }
 
@@ -92,7 +92,7 @@
   std::stringstream stream;
   stream << 0xffffffffU;
   stream << android::kIdmapCurrentVersion;
-  stream << std::string(kJunkSize, (char)0xffU);
+  stream << std::string(kJunkSize, static_cast<char>(0xffU));
   ASSERT_FALSE(Idmap::FromBinaryStream(stream));
 }
 
diff --git a/cmds/idmap2/tests/R.h b/cmds/idmap2/tests/R.h
index ac9b058..89219c9 100644
--- a/cmds/idmap2/tests/R.h
+++ b/cmds/idmap2/tests/R.h
@@ -66,8 +66,8 @@
     constexpr ResourceId str1 = 0x7f02000b;
     constexpr ResourceId str3 = 0x7f02000c;
     constexpr ResourceId str4 = 0x7f02000d;
-  }
-}
+  }  // namespace string
+}  // namespace R::overlay
 // clang-format on
 
 }  // namespace android::idmap2
diff --git a/services/core/java/com/android/server/om/IdmapDaemon.java b/services/core/java/com/android/server/om/IdmapDaemon.java
index b07a1f7..555081a 100644
--- a/services/core/java/com/android/server/om/IdmapDaemon.java
+++ b/services/core/java/com/android/server/om/IdmapDaemon.java
@@ -170,6 +170,16 @@
         }
     }
 
+    String dumpIdmap(@NonNull String overlayPath) {
+        try (Connection c = connect()) {
+            String dump = mService.dumpIdmap(overlayPath);
+            return TextUtils.nullIfEmpty(dump);
+        } catch (Exception e) {
+            Slog.wtf(TAG, "failed to dump idmap", e);
+            return null;
+        }
+    }
+
     private IBinder getIdmapService() throws TimeoutException, RemoteException {
         SystemService.start(IDMAP_DAEMON);
 
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index 64362c9..157a1fc 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -22,7 +22,6 @@
 import android.annotation.NonNull;
 import android.content.om.OverlayInfo;
 import android.content.om.OverlayableInfo;
-import android.content.pm.PackageParser;
 import android.os.Build.VERSION_CODES;
 import android.os.FabricatedOverlayInfo;
 import android.os.FabricatedOverlayInternal;
@@ -142,6 +141,14 @@
     }
 
     /**
+     * Gets the idmap data associated with an overlay, in dump format.
+     * Only indented for debugging.
+     */
+    String dumpIdmap(@NonNull String overlayPath) {
+        return mIdmapDaemon.dumpIdmap(overlayPath);
+    }
+
+    /**
      * Checks if overlayable and policies should be enforced on the specified overlay for backwards
      * compatibility with pre-Q overlays.
      */
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 799ab46..e4ca5b6 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -22,6 +22,7 @@
 import static android.content.om.OverlayInfo.STATE_NO_IDMAP;
 import static android.content.om.OverlayInfo.STATE_OVERLAY_IS_BEING_REPLACED;
 import static android.content.om.OverlayInfo.STATE_TARGET_IS_BEING_REPLACED;
+import static android.os.UserHandle.USER_SYSTEM;
 
 import static com.android.server.om.OverlayManagerService.DEBUG;
 import static com.android.server.om.OverlayManagerService.TAG;
@@ -38,6 +39,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Pair;
 import android.util.Slog;
 
 import com.android.internal.content.om.OverlayConfig;
@@ -682,8 +684,38 @@
     }
 
     void dump(@NonNull final PrintWriter pw, @NonNull DumpState dumpState) {
+        Pair<OverlayIdentifier, String> overlayIdmap = null;
+        if (dumpState.getPackageName() != null) {
+            OverlayIdentifier id = new OverlayIdentifier(dumpState.getPackageName(),
+                    dumpState.getOverlayName());
+            OverlayInfo oi = mSettings.getNullableOverlayInfo(id, USER_SYSTEM);
+            if (oi != null) {
+                overlayIdmap = new Pair<>(id, oi.baseCodePath);
+            }
+        }
+
+        // settings
         mSettings.dump(pw, dumpState);
-        if (dumpState.getPackageName() == null) {
+
+        // idmap data
+        if (dumpState.getField() == null) {
+            Set<Pair<OverlayIdentifier, String>> allIdmaps = (overlayIdmap != null)
+                    ? Set.of(overlayIdmap) : mSettings.getAllIdentifiersAndBaseCodePaths();
+            for (Pair<OverlayIdentifier, String> pair : allIdmaps) {
+                pw.println("IDMAP OF " + pair.first);
+                String dump = mIdmapManager.dumpIdmap(pair.second);
+                if (dump != null) {
+                    pw.println(dump);
+                } else {
+                    OverlayInfo oi = mSettings.getNullableOverlayInfo(pair.first, USER_SYSTEM);
+                    pw.println((oi != null && !mIdmapManager.idmapExists(oi))
+                            ? "<missing idmap>" : "<internal error>");
+                }
+            }
+        }
+
+        // default overlays
+        if (overlayIdmap == null) {
             pw.println("Default overlays: " + TextUtils.join(";", mDefaultOverlays));
         }
     }
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index e3e0906..55bca17 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -26,6 +26,7 @@
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.TypedXmlPullParser;
 import android.util.TypedXmlSerializer;
@@ -205,6 +206,12 @@
         return paths;
     }
 
+    Set<Pair<OverlayIdentifier, String>> getAllIdentifiersAndBaseCodePaths() {
+        final Set<Pair<OverlayIdentifier, String>> set = new ArraySet<>();
+        mItems.forEach(item -> set.add(new Pair(item.mOverlay, item.mBaseCodePath)));
+        return set;
+    }
+
     @NonNull
     List<OverlayInfo> removeIf(@NonNull final Predicate<OverlayInfo> predicate, final int userId) {
         return removeIf(info -> (predicate.test(info) && info.userId == userId));
diff --git a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
index ba1bf93..89939a3 100644
--- a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
+++ b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
@@ -35,12 +35,9 @@
 import android.os.UserHandle;
 import android.util.TypedValue;
 
-import com.android.internal.util.ArrayUtils;
-
 import java.io.PrintWriter;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -103,9 +100,8 @@
         out.println("    Print debugging information about the overlay manager.");
         out.println("    With optional parameters PACKAGE and NAME, limit output to the specified");
         out.println("    overlay or target. With optional parameter FIELD, limit output to");
-        out.println("    the value of that SettingsItem field. Field names are");
-        out.println("    case insensitive and out.println the m prefix can be omitted,");
-        out.println("    so the following are equivalent: mState, mstate, State, state.");
+        out.println("    the corresponding SettingsItem field. Field names are all lower case");
+        out.println("    and omit the m prefix, i.e. 'userid' for SettingsItem.mUserId.");
         out.println("  list [--user USER_ID] [PACKAGE[:NAME]]");
         out.println("    Print information about target and overlay packages.");
         out.println("    Overlay packages are printed in priority order. With optional");
@@ -129,6 +125,11 @@
         out.println("    Load a package and print the value of a given resource");
         out.println("    applying the current configuration and enabled overlays.");
         out.println("    For a more fine-grained alternative, use 'idmap2 lookup'.");
+        out.println("  fabricate [--user USER_ID] [--target-name OVERLAYABLE] --target PACKAGE");
+        out.println("            --name NAME PACKAGE:TYPE/NAME ENCODED-TYPE-ID ENCODED-VALUE");
+        out.println("    Create an overlay from a single resource. Caller must be root. Example:");
+        out.println("      fabricate --target android --name LighterGray \\");
+        out.println("                android:color/lighter_gray 0x1c 0xffeeeeee");
     }
 
     private int runList() throws RemoteException {