Merge "Add captureLayers function to capture a layer and its children."
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index 239a2d5..c36ab08 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -62,6 +62,8 @@
             "         --help: shows this help\n"
             "         -l: only list services, do not dump them\n"
             "         -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\n"
+            "         --proto: filter services that support dumping data in proto format. Dumps"
+            "               will be in proto format.\n"
             "         --priority LEVEL: filter services based on specified priority\n"
             "               LEVEL must be one of CRITICAL | HIGH | NORMAL\n"
             "         --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
@@ -77,17 +79,17 @@
     return false;
 }
 
-static bool ConvertPriorityTypeToBitmask(String16& type, int& bitmask) {
-    if (type == PRIORITY_ARG_CRITICAL) {
-        bitmask = IServiceManager::DUMP_PRIORITY_CRITICAL;
+static bool ConvertPriorityTypeToBitmask(const String16& type, int& bitmask) {
+    if (type == PriorityDumper::PRIORITY_ARG_CRITICAL) {
+        bitmask = IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL;
         return true;
     }
-    if (type == PRIORITY_ARG_HIGH) {
-        bitmask = IServiceManager::DUMP_PRIORITY_HIGH;
+    if (type == PriorityDumper::PRIORITY_ARG_HIGH) {
+        bitmask = IServiceManager::DUMP_FLAG_PRIORITY_HIGH;
         return true;
     }
-    if (type == PRIORITY_ARG_NORMAL) {
-        bitmask = IServiceManager::DUMP_PRIORITY_NORMAL;
+    if (type == PriorityDumper::PRIORITY_ARG_NORMAL) {
+        bitmask = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL;
         return true;
     }
     return false;
@@ -98,11 +100,14 @@
     Vector<String16> args;
     String16 priorityType;
     Vector<String16> skippedServices;
+    Vector<String16> protoServices;
     bool showListOnly = false;
     bool skipServices = false;
+    bool filterByProto = false;
     int timeoutArg = 10;
-    int dumpPriority = IServiceManager::DUMP_PRIORITY_ALL;
+    int dumpPriorityFlags = IServiceManager::DUMP_FLAG_PRIORITY_ALL;
     static struct option longOptions[] = {{"priority", required_argument, 0, 0},
+                                          {"proto", no_argument, 0, 0},
                                           {"skip", no_argument, 0, 0},
                                           {"help", no_argument, 0, 0},
                                           {0, 0, 0, 0}};
@@ -124,12 +129,14 @@
         case 0:
             if (!strcmp(longOptions[optionIndex].name, "skip")) {
                 skipServices = true;
+            } else if (!strcmp(longOptions[optionIndex].name, "proto")) {
+                filterByProto = true;
             } else if (!strcmp(longOptions[optionIndex].name, "help")) {
                 usage();
                 return 0;
             } else if (!strcmp(longOptions[optionIndex].name, "priority")) {
                 priorityType = String16(String8(optarg));
-                if (!ConvertPriorityTypeToBitmask(priorityType, dumpPriority)) {
+                if (!ConvertPriorityTypeToBitmask(priorityType, dumpPriorityFlags)) {
                     fprintf(stderr, "\n");
                     usage();
                     return -1;
@@ -179,10 +186,19 @@
 
     if (services.empty() || showListOnly) {
         // gets all services
-        services = sm_->listServices(dumpPriority);
+        services = sm_->listServices(dumpPriorityFlags);
         services.sort(sort_func);
-        if (dumpPriority != IServiceManager::DUMP_PRIORITY_ALL) {
-            args.insertAt(String16(PRIORITY_ARG), 0);
+        if (filterByProto) {
+            protoServices = sm_->listServices(IServiceManager::DUMP_FLAG_PROTO);
+            protoServices.sort(sort_func);
+            Vector<String16> intersection;
+            std::set_intersection(services.begin(), services.end(), protoServices.begin(),
+                                  protoServices.end(), std::back_inserter(intersection));
+            services = std::move(intersection);
+            args.insertAt(String16(PriorityDumper::PROTO_ARG), 0);
+        }
+        if (dumpPriorityFlags != IServiceManager::DUMP_FLAG_PRIORITY_ALL) {
+            args.insertAt(String16(PriorityDumper::PRIORITY_ARG), 0);
             args.insertAt(priorityType, 1);
         } else {
             args.add(String16("-a"));
@@ -230,7 +246,7 @@
             if (N > 1) {
                 aout << "------------------------------------------------------------"
                         "-------------------" << endl;
-                if (dumpPriority == IServiceManager::DUMP_PRIORITY_ALL) {
+                if (dumpPriorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_ALL) {
                     aout << "DUMP OF SERVICE " << service_name << ":" << endl;
                 } else {
                     aout << "DUMP OF SERVICE " << priorityType << " " << service_name << ":" << endl;
diff --git a/cmds/dumpsys/tests/Android.bp b/cmds/dumpsys/tests/Android.bp
index 39fcb80..e182b9d 100644
--- a/cmds/dumpsys/tests/Android.bp
+++ b/cmds/dumpsys/tests/Android.bp
@@ -15,6 +15,7 @@
     static_libs: [
         "libdumpsys",
         "libgmock",
+        "libserviceutils",
     ],
 
     clang: true,
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index 9fe4572..18a4da9 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -22,6 +22,7 @@
 #include <gtest/gtest.h>
 
 #include <android-base/file.h>
+#include <serviceutils/PriorityDumper.h>
 #include <utils/String16.h>
 #include <utils/String8.h>
 #include <utils/Vector.h>
@@ -131,16 +132,16 @@
         for (auto& service : services) {
             services16.add(String16(service.c_str()));
         }
-        EXPECT_CALL(sm_, listServices(IServiceManager::DUMP_PRIORITY_ALL))
+        EXPECT_CALL(sm_, listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL))
             .WillRepeatedly(Return(services16));
     }
 
-    void ExpectListServicesWithPriority(std::vector<std::string> services, int dumpPriority) {
+    void ExpectListServicesWithPriority(std::vector<std::string> services, int dumpFlags) {
         Vector<String16> services16;
         for (auto& service : services) {
             services16.add(String16(service.c_str()));
         }
-        EXPECT_CALL(sm_, listServices(dumpPriority)).WillRepeatedly(Return(services16));
+        EXPECT_CALL(sm_, listServices(dumpFlags)).WillRepeatedly(Return(services16));
     }
 
     sp<BinderMock> ExpectCheckService(const char* name, bool running = true) {
@@ -210,6 +211,13 @@
         EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n" + dump));
     }
 
+    void AssertDumpedWithPriority(const std::string& service, const std::string& dump,
+                                  const char16_t* priorityType) {
+        std::string priority = String8(priorityType).c_str();
+        EXPECT_THAT(stdout_,
+                    HasSubstr("DUMP OF SERVICE " + priority + " " + service + ":\n" + dump));
+    }
+
     void AssertNotDumped(const std::string& dump) {
         EXPECT_THAT(stdout_, Not(HasSubstr(dump)));
     }
@@ -250,7 +258,7 @@
 
 // Tests 'dumpsys -l --priority HIGH'
 TEST_F(DumpsysTest, ListAllServicesWithPriority) {
-    ExpectListServicesWithPriority({"Locksmith", "Valet"}, IServiceManager::DUMP_PRIORITY_HIGH);
+    ExpectListServicesWithPriority({"Locksmith", "Valet"}, IServiceManager::DUMP_FLAG_PRIORITY_HIGH);
     ExpectCheckService("Locksmith");
     ExpectCheckService("Valet");
 
@@ -261,13 +269,26 @@
 
 // Tests 'dumpsys -l --priority HIGH' with and empty list
 TEST_F(DumpsysTest, ListEmptyServicesWithPriority) {
-    ExpectListServicesWithPriority({}, IServiceManager::DUMP_PRIORITY_HIGH);
+    ExpectListServicesWithPriority({}, IServiceManager::DUMP_FLAG_PRIORITY_HIGH);
 
     CallMain({"-l", "--priority", "HIGH"});
 
     AssertRunningServices({});
 }
 
+// Tests 'dumpsys -l --proto'
+TEST_F(DumpsysTest, ListAllServicesWithProto) {
+    ExpectListServicesWithPriority({"Locksmith", "Valet", "Car"},
+                                   IServiceManager::DUMP_FLAG_PRIORITY_ALL);
+    ExpectListServicesWithPriority({"Valet", "Car"}, IServiceManager::DUMP_FLAG_PROTO);
+    ExpectCheckService("Car");
+    ExpectCheckService("Valet");
+
+    CallMain({"-l", "--proto"});
+
+    AssertRunningServices({"Car", "Valet"});
+}
+
 // Tests 'dumpsys service_name' on a service is running
 TEST_F(DumpsysTest, DumpRunningService) {
     ExpectDump("Valet", "Here's your car");
@@ -336,7 +357,7 @@
 // Tests 'dumpsys --skip skipped3 skipped5 --priority CRITICAL', which should skip these services
 TEST_F(DumpsysTest, DumpWithSkipAndPriority) {
     ExpectListServicesWithPriority({"running1", "stopped2", "skipped3", "running4", "skipped5"},
-                                   IServiceManager::DUMP_PRIORITY_CRITICAL);
+                                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
     ExpectDump("running1", "dump1");
     ExpectCheckService("stopped2", false);
     ExpectDump("skipped3", "dump3");
@@ -346,8 +367,8 @@
     CallMain({"--priority", "CRITICAL", "--skip", "skipped3", "skipped5"});
 
     AssertRunningServices({"running1", "running4", "skipped3 (skipped)", "skipped5 (skipped)"});
-    AssertDumped("running1", "dump1");
-    AssertDumped("running4", "dump4");
+    AssertDumpedWithPriority("running1", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL);
+    AssertDumpedWithPriority("running4", "dump4", PriorityDumper::PRIORITY_ARG_CRITICAL);
     AssertStopped("stopped2");
     AssertNotDumped("dump3");
     AssertNotDumped("dump5");
@@ -356,41 +377,74 @@
 // Tests 'dumpsys --priority CRITICAL'
 TEST_F(DumpsysTest, DumpWithPriorityCritical) {
     ExpectListServicesWithPriority({"runningcritical1", "runningcritical2"},
-                                   IServiceManager::DUMP_PRIORITY_CRITICAL);
+                                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
     ExpectDump("runningcritical1", "dump1");
     ExpectDump("runningcritical2", "dump2");
 
     CallMain({"--priority", "CRITICAL"});
 
     AssertRunningServices({"runningcritical1", "runningcritical2"});
-    AssertDumped("runningcritical1", "dump1");
-    AssertDumped("runningcritical2", "dump2");
+    AssertDumpedWithPriority("runningcritical1", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL);
+    AssertDumpedWithPriority("runningcritical2", "dump2", PriorityDumper::PRIORITY_ARG_CRITICAL);
 }
 
 // Tests 'dumpsys --priority HIGH'
 TEST_F(DumpsysTest, DumpWithPriorityHigh) {
     ExpectListServicesWithPriority({"runninghigh1", "runninghigh2"},
-                                   IServiceManager::DUMP_PRIORITY_HIGH);
+                                   IServiceManager::DUMP_FLAG_PRIORITY_HIGH);
     ExpectDump("runninghigh1", "dump1");
     ExpectDump("runninghigh2", "dump2");
 
     CallMain({"--priority", "HIGH"});
 
     AssertRunningServices({"runninghigh1", "runninghigh2"});
-    AssertDumped("runninghigh1", "dump1");
-    AssertDumped("runninghigh2", "dump2");
+    AssertDumpedWithPriority("runninghigh1", "dump1", PriorityDumper::PRIORITY_ARG_HIGH);
+    AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH);
 }
 
 // Tests 'dumpsys --priority NORMAL'
 TEST_F(DumpsysTest, DumpWithPriorityNormal) {
     ExpectListServicesWithPriority({"runningnormal1", "runningnormal2"},
-                                   IServiceManager::DUMP_PRIORITY_NORMAL);
+                                   IServiceManager::DUMP_FLAG_PRIORITY_NORMAL);
     ExpectDump("runningnormal1", "dump1");
     ExpectDump("runningnormal2", "dump2");
 
     CallMain({"--priority", "NORMAL"});
 
     AssertRunningServices({"runningnormal1", "runningnormal2"});
-    AssertDumped("runningnormal1", "dump1");
-    AssertDumped("runningnormal2", "dump2");
+    AssertDumpedWithPriority("runningnormal1", "dump1", PriorityDumper::PRIORITY_ARG_NORMAL);
+    AssertDumpedWithPriority("runningnormal2", "dump2", PriorityDumper::PRIORITY_ARG_NORMAL);
+}
+
+// Tests 'dumpsys --proto'
+TEST_F(DumpsysTest, DumpWithProto) {
+    ExpectListServicesWithPriority({"run8", "run1", "run2", "run5"},
+                                   IServiceManager::DUMP_FLAG_PRIORITY_ALL);
+    ExpectListServicesWithPriority({"run3", "run2", "run4", "run8"},
+                                   IServiceManager::DUMP_FLAG_PROTO);
+    ExpectDump("run2", "dump1");
+    ExpectDump("run8", "dump2");
+
+    CallMain({"--proto"});
+
+    AssertRunningServices({"run2", "run8"});
+    AssertDumped("run2", "dump1");
+    AssertDumped("run8", "dump2");
+}
+
+// Tests 'dumpsys --priority HIGH --proto'
+TEST_F(DumpsysTest, DumpWithPriorityHighAndProto) {
+    ExpectListServicesWithPriority({"runninghigh1", "runninghigh2"},
+                                   IServiceManager::DUMP_FLAG_PRIORITY_HIGH);
+    ExpectListServicesWithPriority({"runninghigh1", "runninghigh2", "runninghigh3"},
+                                   IServiceManager::DUMP_FLAG_PROTO);
+
+    ExpectDump("runninghigh1", "dump1");
+    ExpectDump("runninghigh2", "dump2");
+
+    CallMain({"--priority", "HIGH", "--proto"});
+
+    AssertRunningServices({"runninghigh1", "runninghigh2"});
+    AssertDumpedWithPriority("runninghigh1", "dump1", PriorityDumper::PRIORITY_ARG_HIGH);
+    AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH);
 }
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 4bb8ebe..cbd67be 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1407,7 +1407,7 @@
         argv[i++] = downgrade_flag;
     }
     if (class_loader_context != nullptr) {
-        argv[i++] = class_loader_context;
+        argv[i++] = class_loader_context_arg.c_str();
     }
     argv[i] = NULL;
 
diff --git a/libs/binder/include/binder/BinderService.h b/libs/binder/include/binder/BinderService.h
index 4e69067..4ce82a1 100644
--- a/libs/binder/include/binder/BinderService.h
+++ b/libs/binder/include/binder/BinderService.h
@@ -35,15 +35,16 @@
 {
 public:
     static status_t publish(bool allowIsolated = false,
-                            int dumpPriority = IServiceManager::DUMP_PRIORITY_NORMAL) {
+                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) {
         sp<IServiceManager> sm(defaultServiceManager());
         return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
-                              dumpPriority);
+                              dumpFlags);
     }
 
-    static void publishAndJoinThreadPool(bool allowIsolated = false,
-                                         int dumpPriority = IServiceManager::DUMP_PRIORITY_NORMAL) {
-        publish(allowIsolated, dumpPriority);
+    static void publishAndJoinThreadPool(
+            bool allowIsolated = false,
+            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) {
+        publish(allowIsolated, dumpFlags);
         joinThreadPool();
     }
 
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 78b03bd..19e841a 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -34,11 +34,12 @@
     /*
      * Must match values in IServiceManager.java
      */
-    static const int DUMP_PRIORITY_CRITICAL = 1 << 0;
-    static const int DUMP_PRIORITY_HIGH = 1 << 1;
-    static const int DUMP_PRIORITY_NORMAL = 1 << 2;
-    static const int DUMP_PRIORITY_ALL =
-            DUMP_PRIORITY_CRITICAL | DUMP_PRIORITY_HIGH | DUMP_PRIORITY_NORMAL;
+    static const int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0;
+    static const int DUMP_FLAG_PRIORITY_HIGH = 1 << 1;
+    static const int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2;
+    static const int DUMP_FLAG_PRIORITY_ALL =
+            DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL;
+    static const int DUMP_FLAG_PROTO = 1 << 3;
 
     /**
      * Retrieve an existing service, blocking for a few seconds
@@ -56,12 +57,12 @@
      */
     virtual status_t addService(const String16& name, const sp<IBinder>& service,
                                 bool allowIsolated = false,
-                                int dumpsysPriority = DUMP_PRIORITY_NORMAL) = 0;
+                                int dumpsysFlags = DUMP_FLAG_PRIORITY_NORMAL) = 0;
 
     /**
      * Return list of all existing services.
      */
-    virtual Vector<String16> listServices(int dumpsysPriority = DUMP_PRIORITY_ALL) = 0;
+    virtual Vector<String16> listServices(int dumpsysFlags = DUMP_FLAG_PRIORITY_ALL) = 0;
 
     enum {
         GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fe9409b..875bef1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3483,12 +3483,18 @@
 
 // ---------------------------------------------------------------------------
 
-status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args) {
+status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args, bool asProto) {
     String8 result;
 
     IPCThreadState* ipc = IPCThreadState::self();
     const int pid = ipc->getCallingPid();
     const int uid = ipc->getCallingUid();
+
+    if (asProto) {
+        // Return early as SurfaceFlinger does not support dumping sections in proto format
+        return OK;
+    }
+
     if ((uid != AID_SHELL) &&
             !PermissionCache::checkPermission(sDump, pid, uid)) {
         result.appendFormat("Permission Denial: "
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 9975de9..25ccb89 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -604,11 +604,14 @@
      * Debugging & dumpsys
      */
 public:
-    status_t dumpCritical(int fd, const Vector<String16>& /*args*/) {
-        return doDump(fd, Vector<String16>());
+    status_t dumpCritical(int fd, const Vector<String16>& /*args*/, bool asProto) {
+        return doDump(fd, Vector<String16>(), asProto);
     }
 
-    status_t dumpAll(int fd, const Vector<String16>& args) { return doDump(fd, args); }
+    status_t dumpAll(int fd, const Vector<String16>& args, bool asProto) {
+        return doDump(fd, args, asProto);
+    }
+
 private:
     void listLayersLocked(const Vector<String16>& args, size_t& index, String8& result) const;
     void dumpStatsLocked(const Vector<String16>& args, size_t& index, String8& result) const;
@@ -634,7 +637,7 @@
     bool isLayerTripleBufferingDisabled() const {
         return this->mLayerTripleBufferingDisabled;
     }
-    status_t doDump(int fd, const Vector<String16>& args);
+    status_t doDump(int fd, const Vector<String16>& args, bool asProto);
 
 #ifdef USE_HWC2
     /* ------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 8c530e0..952023e 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -3009,13 +3009,18 @@
 
 // ---------------------------------------------------------------------------
 
-status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args)
-{
+status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args, bool asProto) {
     String8 result;
 
     IPCThreadState* ipc = IPCThreadState::self();
     const int pid = ipc->getCallingPid();
     const int uid = ipc->getCallingUid();
+
+    if (asProto) {
+        // Return early as SurfaceFlinger does not support dumping sections in proto format
+        return OK;
+    }
+
     if ((uid != AID_SHELL) &&
             !PermissionCache::checkPermission(sDump, pid, uid)) {
         result.appendFormat("Permission Denial: "
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index 6554167..e6f2ce7 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -14,10 +14,16 @@
  * limitations under the License.
  */
 
+#include <android-base/stringprintf.h>
 #include <layerproto/LayerProtoParser.h>
+#include <ui/DebugUtils.h>
+
+using android::base::StringAppendF;
+using android::base::StringPrintf;
 
 namespace android {
 namespace surfaceflinger {
+
 bool sortLayers(const LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs) {
     uint32_t ls = lhs->layerStack;
     uint32_t rs = rhs->layerStack;
@@ -219,5 +225,62 @@
     return result;
 }
 
+std::string LayerProtoParser::ActiveBuffer::to_string() const {
+    return StringPrintf("[%4ux%4u:%4u,%s]", width, height, stride,
+                        decodePixelFormat(format).c_str());
+}
+
+std::string LayerProtoParser::Transform::to_string() const {
+    return StringPrintf("[%.2f, %.2f][%.2f, %.2f]", static_cast<double>(dsdx),
+                        static_cast<double>(dtdx), static_cast<double>(dsdy),
+                        static_cast<double>(dtdy));
+}
+
+std::string LayerProtoParser::Rect::to_string() const {
+    return StringPrintf("[%3d, %3d, %3d, %3d]", left, top, right, bottom);
+}
+
+std::string LayerProtoParser::Region::to_string(const char* what) const {
+    std::string result =
+            StringPrintf("  Region %s (this=%lx count=%d)\n", what, static_cast<unsigned long>(id),
+                         static_cast<int>(rects.size()));
+
+    for (auto& rect : rects) {
+        StringAppendF(&result, "    %s\n", rect.to_string().c_str());
+    }
+
+    return result;
+}
+
+std::string LayerProtoParser::Layer::to_string() const {
+    std::string result;
+    StringAppendF(&result, "+ %s (%s)\n", type.c_str(), name.c_str());
+    result.append(transparentRegion.to_string("TransparentRegion").c_str());
+    result.append(visibleRegion.to_string("VisibleRegion").c_str());
+    result.append(damageRegion.to_string("SurfaceDamageRegion").c_str());
+
+    StringAppendF(&result, "      layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ", layerStack,
+                  z, static_cast<double>(position.x), static_cast<double>(position.y), size.x,
+                  size.y);
+
+    StringAppendF(&result, "crop=%s, finalCrop=%s, ", crop.to_string().c_str(),
+                  finalCrop.to_string().c_str());
+    StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
+    StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
+    StringAppendF(&result, "pixelformat=%s, ", pixelFormat.c_str());
+    StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
+                  static_cast<double>(color.r), static_cast<double>(color.g),
+                  static_cast<double>(color.b), static_cast<double>(color.a), flags);
+    StringAppendF(&result, "tr=%s", transform.to_string().c_str());
+    result.append("\n");
+    StringAppendF(&result, "      parent=%s\n", parent == nullptr ? "none" : parent->name.c_str());
+    StringAppendF(&result, "      zOrderRelativeOf=%s\n",
+                  zOrderRelativeOf == nullptr ? "none" : zOrderRelativeOf->name.c_str());
+    StringAppendF(&result, "      activeBuffer=%s,", activeBuffer.to_string().c_str());
+    StringAppendF(&result, " queued-frames=%d, mRefreshPending=%d", queuedFrames, refreshPending);
+
+    return result;
+}
+
 } // namespace surfaceflinger
 } // namespace android
diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
index 7b94cef..78c6cd1 100644
--- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
+++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
@@ -18,14 +18,9 @@
 
 #include <math/vec4.h>
 
-#include <android-base/stringprintf.h>
-#include <ui/DebugUtils.h>
 #include <unordered_map>
 #include <vector>
 
-using android::base::StringAppendF;
-using android::base::StringPrintf;
-
 namespace android {
 namespace surfaceflinger {
 
@@ -38,10 +33,7 @@
         uint32_t stride;
         int32_t format;
 
-        std::string to_string() const {
-            return StringPrintf("[%4ux%4u:%4u,%s]", width, height, stride,
-                                decodePixelFormat(format).c_str());
-        }
+        std::string to_string() const;
     };
 
     class Transform {
@@ -51,11 +43,7 @@
         float dsdy;
         float dtdy;
 
-        std::string to_string() const {
-            return StringPrintf("[%.2f, %.2f][%.2f, %.2f]", static_cast<double>(dsdx),
-                                static_cast<double>(dtdx), static_cast<double>(dsdy),
-                                static_cast<double>(dtdy));
-        }
+        std::string to_string() const;
     };
 
     class Rect {
@@ -65,9 +53,7 @@
         int32_t right;
         int32_t bottom;
 
-        std::string to_string() const {
-            return StringPrintf("[%3d, %3d, %3d, %3d]", left, top, right, bottom);
-        }
+        std::string to_string() const;
     };
 
     class Region {
@@ -75,17 +61,7 @@
         uint64_t id;
         std::vector<Rect> rects;
 
-        std::string to_string(const char* what) const {
-            std::string result =
-                    StringPrintf("  Region %s (this=%lx count=%d)\n", what,
-                                 static_cast<unsigned long>(id), static_cast<int>(rects.size()));
-
-            for (auto& rect : rects) {
-                StringAppendF(&result, "    %s\n", rect.to_string().c_str());
-            }
-
-            return result;
-        }
+        std::string to_string(const char* what) const;
     };
 
     class Layer {
@@ -120,37 +96,7 @@
         int32_t queuedFrames;
         bool refreshPending;
 
-        std::string to_string() const {
-            std::string result;
-            StringAppendF(&result, "+ %s (%s)\n", type.c_str(), name.c_str());
-            result.append(transparentRegion.to_string("TransparentRegion").c_str());
-            result.append(visibleRegion.to_string("VisibleRegion").c_str());
-            result.append(damageRegion.to_string("SurfaceDamageRegion").c_str());
-
-            StringAppendF(&result, "      layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ",
-                          layerStack, z, static_cast<double>(position.x),
-                          static_cast<double>(position.y), size.x, size.y);
-
-            StringAppendF(&result, "crop=%s, finalCrop=%s, ", crop.to_string().c_str(),
-                          finalCrop.to_string().c_str());
-            StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
-            StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
-            StringAppendF(&result, "pixelformat=%s, ", pixelFormat.c_str());
-            StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
-                          static_cast<double>(color.r), static_cast<double>(color.g),
-                          static_cast<double>(color.b), static_cast<double>(color.a), flags);
-            StringAppendF(&result, "tr=%s", transform.to_string().c_str());
-            result.append("\n");
-            StringAppendF(&result, "      parent=%s\n",
-                          parent == nullptr ? "none" : parent->name.c_str());
-            StringAppendF(&result, "      zOrderRelativeOf=%s\n",
-                          zOrderRelativeOf == nullptr ? "none" : zOrderRelativeOf->name.c_str());
-            StringAppendF(&result, "      activeBuffer=%s,", activeBuffer.to_string().c_str());
-            StringAppendF(&result, " queued-frames=%d, mRefreshPending=%d", queuedFrames,
-                          refreshPending);
-
-            return result;
-        }
+        std::string to_string() const;
     };
 
     static std::vector<const Layer*> generateLayerTree(const LayersProto& layersProto);
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index 6a24891..2a924ae 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -106,7 +106,7 @@
     // publish surface flinger
     sp<IServiceManager> sm(defaultServiceManager());
     sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
-                   IServiceManager::DUMP_PRIORITY_CRITICAL);
+                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
 
     // publish GpuService
     sp<GpuService> gpuservice = new GpuService();
diff --git a/services/utils/PriorityDumper.cpp b/services/utils/PriorityDumper.cpp
index 9851188..967dee5 100644
--- a/services/utils/PriorityDumper.cpp
+++ b/services/utils/PriorityDumper.cpp
@@ -18,41 +18,68 @@
 
 namespace android {
 
-static void getStrippedArgs(Vector<String16>& dest, const Vector<String16>& source,
-                            std::size_t numArgsToStrip) {
-    for (auto it = source.begin() + numArgsToStrip; it != source.end(); it++) {
-        dest.add(*it);
+const char16_t PriorityDumper::PROTO_ARG[] = u"--proto";
+const char16_t PriorityDumper::PRIORITY_ARG[] = u"--dump-priority";
+const char16_t PriorityDumper::PRIORITY_ARG_CRITICAL[] = u"CRITICAL";
+const char16_t PriorityDumper::PRIORITY_ARG_HIGH[] = u"HIGH";
+const char16_t PriorityDumper::PRIORITY_ARG_NORMAL[] = u"NORMAL";
+
+enum class PriorityType { INVALID, CRITICAL, HIGH, NORMAL };
+
+static PriorityType getPriorityType(const String16& arg) {
+    if (arg == PriorityDumper::PRIORITY_ARG_CRITICAL) {
+        return PriorityType::CRITICAL;
+    } else if (arg == PriorityDumper::PRIORITY_ARG_HIGH) {
+        return PriorityType::HIGH;
+    } else if (arg == PriorityDumper::PRIORITY_ARG_NORMAL) {
+        return PriorityType::NORMAL;
     }
+    return PriorityType::INVALID;
 }
 
-status_t PriorityDumper::dumpAll(int fd, const Vector<String16>& args) {
+status_t PriorityDumper::dumpAll(int fd, const Vector<String16>& args, bool asProto) {
     status_t status;
-    status = dumpCritical(fd, args);
+    status = dumpCritical(fd, args, asProto);
     if (status != OK) return status;
-    status = dumpHigh(fd, args);
+    status = dumpHigh(fd, args, asProto);
     if (status != OK) return status;
-    status = dumpNormal(fd, args);
+    status = dumpNormal(fd, args, asProto);
     if (status != OK) return status;
     return status;
 }
 
 status_t PriorityDumper::priorityDump(int fd, const Vector<String16>& args) {
     status_t status;
-    if (args.size() >= 2 && args[0] == PRIORITY_ARG) {
-        String16 priority = args[1];
-        Vector<String16> strippedArgs;
-        getStrippedArgs(strippedArgs, args, 2);
-        if (priority == PRIORITY_ARG_CRITICAL) {
-            status = dumpCritical(fd, strippedArgs);
-        } else if (priority == PRIORITY_ARG_HIGH) {
-            status = dumpHigh(fd, strippedArgs);
-        } else if (priority == PRIORITY_ARG_NORMAL) {
-            status = dumpNormal(fd, strippedArgs);
+    bool asProto = false;
+    PriorityType priority = PriorityType::INVALID;
+
+    Vector<String16> strippedArgs;
+    for (uint32_t argIndex = 0; argIndex < args.size(); argIndex++) {
+        if (args[argIndex] == PROTO_ARG) {
+            asProto = true;
+        } else if (args[argIndex] == PRIORITY_ARG) {
+            if (argIndex + 1 < args.size()) {
+                argIndex++;
+                priority = getPriorityType(args[argIndex]);
+            }
         } else {
-            status = dumpAll(fd, args);
+            strippedArgs.add(args[argIndex]);
         }
-    } else {
-        status = dumpAll(fd, args);
+    }
+
+    switch (priority) {
+        case PriorityType::CRITICAL:
+            status = dumpCritical(fd, strippedArgs, asProto);
+            break;
+        case PriorityType::HIGH:
+            status = dumpHigh(fd, strippedArgs, asProto);
+            break;
+        case PriorityType::NORMAL:
+            status = dumpNormal(fd, strippedArgs, asProto);
+            break;
+        default:
+            status = dumpAll(fd, strippedArgs, asProto);
+            break;
     }
     return status;
 }
diff --git a/services/utils/include/serviceutils/PriorityDumper.h b/services/utils/include/serviceutils/PriorityDumper.h
index 0319242..d01a102 100644
--- a/services/utils/include/serviceutils/PriorityDumper.h
+++ b/services/utils/include/serviceutils/PriorityDumper.h
@@ -23,34 +23,43 @@
 
 namespace android {
 
-constexpr const char16_t PRIORITY_ARG[] = u"--dump-priority";
-constexpr const char16_t PRIORITY_ARG_CRITICAL[] = u"CRITICAL";
-constexpr const char16_t PRIORITY_ARG_HIGH[] = u"HIGH";
-constexpr const char16_t PRIORITY_ARG_NORMAL[] = u"NORMAL";
-
-// Helper class to split dumps into various priority buckets.
+// Helper class to parse common arguments responsible for splitting dumps into
+// various priority buckets and changing the output format of the dump.
 class PriorityDumper {
 public:
-    // Parses the argument list checking if the first argument is --dump_priority and
-    // the second argument is the priority type (HIGH, CRITICAL or NORMAL). If the
-    // arguments are found, they are stripped and the appropriate PriorityDumper
-    // method is called.
-    // If --dump_priority argument is not passed, all supported sections are dumped.
+    static const char16_t PRIORITY_ARG[];
+    static const char16_t PRIORITY_ARG_CRITICAL[];
+    static const char16_t PRIORITY_ARG_HIGH[];
+    static const char16_t PRIORITY_ARG_NORMAL[];
+    static const char16_t PROTO_ARG[];
+
+    // Parses the argument list searching for --dump_priority with a priority type
+    // (HIGH, CRITICAL or NORMAL) and --proto. Matching arguments are stripped.
+    // If a valid priority type is found, the associated PriorityDumper
+    // method is called otherwise all supported sections are dumped.
+    // If --proto is found, the dumpAsProto flag is set to dump sections in proto
+    // format.
     status_t priorityDump(int fd, const Vector<String16>& args);
 
     // Dumps CRITICAL priority sections.
-    virtual status_t dumpCritical(int /*fd*/, const Vector<String16>& /*args*/) { return OK; }
+    virtual status_t dumpCritical(int /*fd*/, const Vector<String16>& /*args*/, bool /*asProto*/) {
+        return OK;
+    }
 
     // Dumps HIGH priority sections.
-    virtual status_t dumpHigh(int /*fd*/, const Vector<String16>& /*args*/) { return OK; }
+    virtual status_t dumpHigh(int /*fd*/, const Vector<String16>& /*args*/, bool /*asProto*/) {
+        return OK;
+    }
 
     // Dumps normal priority sections.
-    virtual status_t dumpNormal(int /*fd*/, const Vector<String16>& /*args*/) { return OK; }
+    virtual status_t dumpNormal(int /*fd*/, const Vector<String16>& /*args*/, bool /*asProto*/) {
+        return OK;
+    }
 
     // Dumps all sections.
     // This method is called when priorityDump is called without priority
     // arguments. By default, it calls all three dump methods.
-    virtual status_t dumpAll(int fd, const Vector<String16>& args);
+    virtual status_t dumpAll(int fd, const Vector<String16>& args, bool asProto);
     virtual ~PriorityDumper() = default;
 };
 
diff --git a/services/utils/tests/PriorityDumper_test.cpp b/services/utils/tests/PriorityDumper_test.cpp
index 79e7340..90cc6de 100644
--- a/services/utils/tests/PriorityDumper_test.cpp
+++ b/services/utils/tests/PriorityDumper_test.cpp
@@ -32,17 +32,17 @@
 
 class PriorityDumperMock : public PriorityDumper {
 public:
-    MOCK_METHOD2(dumpCritical, status_t(int, const Vector<String16>&));
-    MOCK_METHOD2(dumpHigh, status_t(int, const Vector<String16>&));
-    MOCK_METHOD2(dumpNormal, status_t(int, const Vector<String16>&));
-    MOCK_METHOD2(dumpAll, status_t(int, const Vector<String16>&));
+    MOCK_METHOD3(dumpCritical, status_t(int, const Vector<String16>&, bool));
+    MOCK_METHOD3(dumpHigh, status_t(int, const Vector<String16>&, bool));
+    MOCK_METHOD3(dumpNormal, status_t(int, const Vector<String16>&, bool));
+    MOCK_METHOD3(dumpAll, status_t(int, const Vector<String16>&, bool));
 };
 
 class DumpAllMock : public PriorityDumper {
 public:
-    MOCK_METHOD2(dumpCritical, status_t(int, const Vector<String16>&));
-    MOCK_METHOD2(dumpHigh, status_t(int, const Vector<String16>&));
-    MOCK_METHOD2(dumpNormal, status_t(int, const Vector<String16>&));
+    MOCK_METHOD3(dumpCritical, status_t(int, const Vector<String16>&, bool));
+    MOCK_METHOD3(dumpHigh, status_t(int, const Vector<String16>&, bool));
+    MOCK_METHOD3(dumpNormal, status_t(int, const Vector<String16>&, bool));
 };
 
 class PriorityDumperTest : public Test {
@@ -61,14 +61,14 @@
 
 TEST_F(PriorityDumperTest, noArgsPassed) {
     Vector<String16> args;
-    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args)));
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args), /*asProto=*/false));
     dumper_.priorityDump(fd, args);
 }
 
 TEST_F(PriorityDumperTest, noPriorityArgsPassed) {
     Vector<String16> args;
     addAll(args, {"bunch", "of", "args"});
-    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args)));
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args), /*asProto=*/false));
     dumper_.priorityDump(fd, args);
 }
 
@@ -76,7 +76,7 @@
     Vector<String16> args;
     addAll(args, {"--dump-priority", "CRITICAL"});
     Vector<String16> strippedArgs;
-    EXPECT_CALL(dumper_, dumpCritical(fd, ElementsAreArray(strippedArgs)));
+    EXPECT_CALL(dumper_, dumpCritical(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
     dumper_.priorityDump(fd, args);
 }
 
@@ -86,7 +86,17 @@
     Vector<String16> strippedArgs;
     addAll(strippedArgs, {"args", "left", "behind"});
 
-    EXPECT_CALL(dumper_, dumpCritical(fd, ElementsAreArray(strippedArgs)));
+    EXPECT_CALL(dumper_, dumpCritical(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
+    dumper_.priorityDump(fd, args);
+}
+
+TEST_F(PriorityDumperTest, dumpCriticalInMiddle) {
+    Vector<String16> args;
+    addAll(args, {"args", "left", "--dump-priority", "CRITICAL", "behind"});
+    Vector<String16> strippedArgs;
+    addAll(strippedArgs, {"args", "left", "behind"});
+
+    EXPECT_CALL(dumper_, dumpCritical(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
     dumper_.priorityDump(fd, args);
 }
 
@@ -96,7 +106,17 @@
     Vector<String16> strippedArgs;
     addAll(strippedArgs, {"args", "left", "behind"});
 
-    EXPECT_CALL(dumper_, dumpHigh(fd, ElementsAreArray(strippedArgs)));
+    EXPECT_CALL(dumper_, dumpHigh(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
+    dumper_.priorityDump(fd, args);
+}
+
+TEST_F(PriorityDumperTest, dumpHighInEnd) {
+    Vector<String16> args;
+    addAll(args, {"args", "left", "behind", "--dump-priority", "HIGH"});
+    Vector<String16> strippedArgs;
+    addAll(strippedArgs, {"args", "left", "behind"});
+
+    EXPECT_CALL(dumper_, dumpHigh(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
     dumper_.priorityDump(fd, args);
 }
 
@@ -106,7 +126,7 @@
     Vector<String16> strippedArgs;
     addAll(strippedArgs, {"args", "left", "behind"});
 
-    EXPECT_CALL(dumper_, dumpNormal(fd, ElementsAreArray(strippedArgs)));
+    EXPECT_CALL(dumper_, dumpNormal(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
     dumper_.priorityDump(fd, args);
 }
 
@@ -114,9 +134,9 @@
     Vector<String16> args;
     addAll(args, {"args", "left", "behind"});
 
-    EXPECT_CALL(dumpAlldumper_, dumpCritical(fd, ElementsAreArray(args)));
-    EXPECT_CALL(dumpAlldumper_, dumpHigh(fd, ElementsAreArray(args)));
-    EXPECT_CALL(dumpAlldumper_, dumpNormal(fd, ElementsAreArray(args)));
+    EXPECT_CALL(dumpAlldumper_, dumpCritical(fd, ElementsAreArray(args), /*asProto=*/false));
+    EXPECT_CALL(dumpAlldumper_, dumpHigh(fd, ElementsAreArray(args), /*asProto=*/false));
+    EXPECT_CALL(dumpAlldumper_, dumpNormal(fd, ElementsAreArray(args), /*asProto=*/false));
 
     dumpAlldumper_.priorityDump(fd, args);
 }
@@ -124,7 +144,8 @@
 TEST_F(PriorityDumperTest, priorityArgWithPriorityMissing) {
     Vector<String16> args;
     addAll(args, {"--dump-priority"});
-    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args)));
+    Vector<String16> strippedArgs;
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
 
     dumper_.priorityDump(fd, args);
 }
@@ -132,7 +153,67 @@
 TEST_F(PriorityDumperTest, priorityArgWithInvalidPriority) {
     Vector<String16> args;
     addAll(args, {"--dump-priority", "REALLY_HIGH"});
-    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args)));
+    Vector<String16> strippedArgs;
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/false));
+
+    dumper_.priorityDump(fd, args);
+}
+
+TEST_F(PriorityDumperTest, protoArg) {
+    Vector<String16> args;
+    addAll(args, {"--proto"});
+    Vector<String16> strippedArgs;
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
+
+    dumper_.priorityDump(fd, args);
+}
+
+TEST_F(PriorityDumperTest, protoArgWithPriorityArgs) {
+    Vector<String16> args;
+    addAll(args, {"--proto", "args", "--dump-priority", "NORMAL", "left", "behind"});
+    Vector<String16> strippedArgs;
+    addAll(strippedArgs, {"args", "left", "behind"});
+    EXPECT_CALL(dumper_, dumpNormal(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
+
+    dumper_.priorityDump(fd, args);
+}
+
+TEST_F(PriorityDumperTest, protoArgWithPriorityArgsInReverseOrder) {
+    Vector<String16> args;
+    addAll(args, {"--dump-priority", "NORMAL", "--proto", "args", "left", "behind"});
+    Vector<String16> strippedArgs;
+    addAll(strippedArgs, {"args", "left", "behind"});
+    EXPECT_CALL(dumper_, dumpNormal(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
+
+    dumper_.priorityDump(fd, args);
+}
+
+TEST_F(PriorityDumperTest, protoArgInMiddle) {
+    Vector<String16> args;
+    addAll(args, {"--unknown", "args", "--proto", "args", "left", "behind"});
+    Vector<String16> strippedArgs;
+    addAll(strippedArgs, {"--unknown", "args", "args", "left", "behind"});
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
+
+    dumper_.priorityDump(fd, args);
+}
+
+TEST_F(PriorityDumperTest, protoArgAtEnd) {
+    Vector<String16> args;
+    addAll(args, {"--unknown", "args", "args", "left", "behind", "--proto"});
+    Vector<String16> strippedArgs;
+    addAll(strippedArgs, {"--unknown", "args", "args", "left", "behind"});
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
+
+    dumper_.priorityDump(fd, args);
+}
+
+TEST_F(PriorityDumperTest, protoArgWithInvalidPriorityType) {
+    Vector<String16> args;
+    addAll(args, {"--dump-priority", "NOT_SO_HIGH", "--proto", "args", "left", "behind"});
+    Vector<String16> strippedArgs;
+    addAll(strippedArgs, {"args", "left", "behind"});
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(strippedArgs), /*asProto=*/true));
 
     dumper_.priorityDump(fd, args);
 }
\ No newline at end of file