Support priority based dumpsys in surface flinger

Call dump with no args when called with CRITICAL priority. Register
service with support for critical priority dumps.

BUG: 31774394

Test: lunch mini_emulator_x86-userdebug && make -j56
Test: adb bugreport ~/tmp.zip
Test: adb shell dumpsys --priority CRITICAL
Test: mmm -j32 frameworks/native/services/utils && \
      adb sync data && adb shell /data/nativetest/prioritydumper_test/prioritydumper_test && \
      adb shell /data/nativetest64/prioritydumper_test/prioritydumper_test && \
      printf "\n\n#### ALL TESTS PASSED ####\n"

Change-Id: Iec35ef8026d4d9346c83bab203bed8524c28bf89
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 4775e4e..64a2a50 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -1,6 +1,8 @@
 cc_library_static {
     name: "libsurfaceflingerincludes",
     export_include_dirs: ["."],
+    static_libs = ["libserviceutils"],
+    export_static_lib_headers = ["libserviceutils"],
 }
 
 subdirs = ["tests/fakehwc"]
\ No newline at end of file
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 1f4427a..390263f 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -67,7 +67,10 @@
     libtrace_proto \
     libvkjson \
     libvr_manager \
-    libvrflinger
+    libvrflinger \
+    libserviceutils
+
+LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := libserviceutils
 
 LOCAL_SHARED_LIBRARIES := \
     android.frameworks.vr.composer@1.0 \
@@ -145,7 +148,8 @@
     libdl
 
 LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
-LOCAL_STATIC_LIBRARIES := libtrace_proto
+LOCAL_STATIC_LIBRARIES := libtrace_proto \
+    libserviceutils
 
 LOCAL_MODULE := surfaceflinger
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f04cb88..5982422 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3459,8 +3459,7 @@
 
 // ---------------------------------------------------------------------------
 
-status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
-{
+status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args) {
     String8 result;
 
     IPCThreadState* ipc = IPCThreadState::self();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e87d35f..47ad7b9 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -47,6 +47,8 @@
 
 #include <hardware/hwcomposer_defs.h>
 
+#include <serviceutils/PriorityDumper.h>
+
 #include <system/graphics.h>
 
 #include <private/gui/LayerState.h>
@@ -105,6 +107,7 @@
 };
 
 class SurfaceFlinger : public BnSurfaceComposer,
+                       public PriorityDumper,
                        private IBinder::DeathRecipient,
 #ifdef USE_HWC2
                        private HWC2::ComposerCallback
@@ -272,7 +275,7 @@
      */
     virtual status_t onTransact(uint32_t code, const Parcel& data,
         Parcel* reply, uint32_t flags);
-    virtual status_t dump(int fd, const Vector<String16>& args);
+    virtual status_t dump(int fd, const Vector<String16>& args) { return priorityDump(fd, args); }
 
     /* ------------------------------------------------------------------------
      * ISurfaceComposer interface
@@ -592,6 +595,13 @@
     /* ------------------------------------------------------------------------
      * Debugging & dumpsys
      */
+public:
+    status_t dumpCritical(int fd, const Vector<String16>& /*args*/) {
+        return doDump(fd, Vector<String16>());
+    }
+
+    status_t dumpAll(int fd, const Vector<String16>& args) { return doDump(fd, args); }
+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;
     void clearStatsLocked(const Vector<String16>& args, size_t& index, String8& result);
@@ -616,6 +626,7 @@
     bool isLayerTripleBufferingDisabled() const {
         return this->mLayerTripleBufferingDisabled;
     }
+    status_t doDump(int fd, const Vector<String16>& args);
 
 #ifdef USE_HWC2
     /* ------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index b002138..b718ec8 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -3005,7 +3005,7 @@
 
 // ---------------------------------------------------------------------------
 
-status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
+status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args)
 {
     String8 result;
 
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index e50f3ce..6a24891 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -105,7 +105,8 @@
 
     // publish surface flinger
     sp<IServiceManager> sm(defaultServiceManager());
-    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
+    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
+                   IServiceManager::DUMP_PRIORITY_CRITICAL);
 
     // publish GpuService
     sp<GpuService> gpuservice = new GpuService();
diff --git a/services/utils/Android.bp b/services/utils/Android.bp
index 4673491..6132956 100644
--- a/services/utils/Android.bp
+++ b/services/utils/Android.bp
@@ -20,7 +20,6 @@
 
     cflags: [
         "-Wall",
-        "-Wno-unused-parameter",
         "-Werror",
     ],
 
diff --git a/services/utils/PriorityDumper.cpp b/services/utils/PriorityDumper.cpp
index 555cf03..9851188 100644
--- a/services/utils/PriorityDumper.cpp
+++ b/services/utils/PriorityDumper.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "include/PriorityDumper.h"
+#include "include/serviceutils/PriorityDumper.h"
 
 namespace android {
 
@@ -25,22 +25,35 @@
     }
 }
 
-void priorityDump(PriorityDumper& dumper, int fd, const Vector<String16>& args) {
+status_t PriorityDumper::dumpAll(int fd, const Vector<String16>& args) {
+    status_t status;
+    status = dumpCritical(fd, args);
+    if (status != OK) return status;
+    status = dumpHigh(fd, args);
+    if (status != OK) return status;
+    status = dumpNormal(fd, args);
+    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) {
-            dumper.dumpCritical(fd, strippedArgs);
+            status = dumpCritical(fd, strippedArgs);
         } else if (priority == PRIORITY_ARG_HIGH) {
-            dumper.dumpHigh(fd, strippedArgs);
+            status = dumpHigh(fd, strippedArgs);
         } else if (priority == PRIORITY_ARG_NORMAL) {
-            dumper.dumpNormal(fd, strippedArgs);
+            status = dumpNormal(fd, strippedArgs);
         } else {
-            dumper.dump(fd, args);
+            status = dumpAll(fd, args);
         }
     } else {
-        dumper.dump(fd, args);
+        status = dumpAll(fd, args);
     }
+    return status;
 }
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/utils/include/PriorityDumper.h b/services/utils/include/PriorityDumper.h
deleted file mode 100644
index 23e900d..0000000
--- a/services/utils/include/PriorityDumper.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_UTILS_PRIORITYDUMP_H
-#define ANDROID_UTILS_PRIORITYDUMP_H
-
-#include <utils/String16.h>
-#include <utils/Vector.h>
-
-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.
-class PriorityDumper {
-public:
-    // Dumps CRITICAL priority sections.
-    virtual void dumpCritical(int fd, const Vector<String16>& args) {}
-
-    // Dumps HIGH priority sections.
-    virtual void dumpHigh(int fd, const Vector<String16>& args) {}
-
-    // Dumps normal priority sections.
-    virtual void dumpNormal(int fd, const Vector<String16>& args) {}
-
-    // Dumps all sections.
-    // This method is called when priorityDump is called without priority
-    // arguments. By default, it calls all three dump methods.
-    virtual void dump(int fd, const Vector<String16>& args) {
-        dumpCritical(fd, args);
-        dumpHigh(fd, args);
-        dumpNormal(fd, args);
-    }
-    virtual ~PriorityDumper() = default;
-};
-
-// 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.
-void priorityDump(PriorityDumper& dumper, int fd, const Vector<String16>& args);
-
-}; // namespace android
-
-#endif // ANDROID_UTILS_PRIORITYDUMP_H
diff --git a/services/utils/include/serviceutils/PriorityDumper.h b/services/utils/include/serviceutils/PriorityDumper.h
new file mode 100644
index 0000000..0319242
--- /dev/null
+++ b/services/utils/include/serviceutils/PriorityDumper.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UTILS_PRIORITYDUMPER_H
+#define ANDROID_UTILS_PRIORITYDUMPER_H
+
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+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.
+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.
+    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; }
+
+    // Dumps HIGH priority sections.
+    virtual status_t dumpHigh(int /*fd*/, const Vector<String16>& /*args*/) { return OK; }
+
+    // Dumps normal priority sections.
+    virtual status_t dumpNormal(int /*fd*/, const Vector<String16>& /*args*/) { 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 ~PriorityDumper() = default;
+};
+
+} // namespace android
+
+#endif // ANDROID_UTILS_PRIORITYDUMPER_H
diff --git a/services/utils/tests/Android.bp b/services/utils/tests/Android.bp
index 5a9dc0a..15829fa 100644
--- a/services/utils/tests/Android.bp
+++ b/services/utils/tests/Android.bp
@@ -21,9 +21,6 @@
     shared_libs: [
         "libutils",
     ],
-    cflags: [
-        "-Wno-unused-parameter",
-    ],
     static_libs = [
         "libgmock",
         "libserviceutils"
diff --git a/services/utils/tests/PriorityDumper_test.cpp b/services/utils/tests/PriorityDumper_test.cpp
index c5a121e..79e7340 100644
--- a/services/utils/tests/PriorityDumper_test.cpp
+++ b/services/utils/tests/PriorityDumper_test.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "PriorityDumper.h"
+#include "serviceutils/PriorityDumper.h"
 
 #include <vector>
 
@@ -32,17 +32,17 @@
 
 class PriorityDumperMock : public PriorityDumper {
 public:
-    MOCK_METHOD2(dumpCritical, void(int, const Vector<String16>&));
-    MOCK_METHOD2(dumpHigh, void(int, const Vector<String16>&));
-    MOCK_METHOD2(dumpNormal, void(int, const Vector<String16>&));
-    MOCK_METHOD2(dump, void(int, const Vector<String16>&));
+    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>&));
 };
 
 class DumpAllMock : public PriorityDumper {
 public:
-    MOCK_METHOD2(dumpCritical, void(int, const Vector<String16>&));
-    MOCK_METHOD2(dumpHigh, void(int, const Vector<String16>&));
-    MOCK_METHOD2(dumpNormal, void(int, const Vector<String16>&));
+    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>&));
 };
 
 class PriorityDumperTest : public Test {
@@ -61,15 +61,15 @@
 
 TEST_F(PriorityDumperTest, noArgsPassed) {
     Vector<String16> args;
-    EXPECT_CALL(dumper_, dump(fd, ElementsAreArray(args)));
-    priorityDump(dumper_, fd, args);
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args)));
+    dumper_.priorityDump(fd, args);
 }
 
 TEST_F(PriorityDumperTest, noPriorityArgsPassed) {
     Vector<String16> args;
     addAll(args, {"bunch", "of", "args"});
-    EXPECT_CALL(dumper_, dump(fd, ElementsAreArray(args)));
-    priorityDump(dumper_, fd, args);
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args)));
+    dumper_.priorityDump(fd, args);
 }
 
 TEST_F(PriorityDumperTest, priorityArgsOnly) {
@@ -77,8 +77,7 @@
     addAll(args, {"--dump-priority", "CRITICAL"});
     Vector<String16> strippedArgs;
     EXPECT_CALL(dumper_, dumpCritical(fd, ElementsAreArray(strippedArgs)));
-
-    priorityDump(dumper_, fd, args);
+    dumper_.priorityDump(fd, args);
 }
 
 TEST_F(PriorityDumperTest, dumpCritical) {
@@ -88,7 +87,7 @@
     addAll(strippedArgs, {"args", "left", "behind"});
 
     EXPECT_CALL(dumper_, dumpCritical(fd, ElementsAreArray(strippedArgs)));
-    priorityDump(dumper_, fd, args);
+    dumper_.priorityDump(fd, args);
 }
 
 TEST_F(PriorityDumperTest, dumpHigh) {
@@ -98,7 +97,7 @@
     addAll(strippedArgs, {"args", "left", "behind"});
 
     EXPECT_CALL(dumper_, dumpHigh(fd, ElementsAreArray(strippedArgs)));
-    priorityDump(dumper_, fd, args);
+    dumper_.priorityDump(fd, args);
 }
 
 TEST_F(PriorityDumperTest, dumpNormal) {
@@ -108,7 +107,7 @@
     addAll(strippedArgs, {"args", "left", "behind"});
 
     EXPECT_CALL(dumper_, dumpNormal(fd, ElementsAreArray(strippedArgs)));
-    priorityDump(dumper_, fd, args);
+    dumper_.priorityDump(fd, args);
 }
 
 TEST_F(PriorityDumperTest, dumpAll) {
@@ -119,21 +118,21 @@
     EXPECT_CALL(dumpAlldumper_, dumpHigh(fd, ElementsAreArray(args)));
     EXPECT_CALL(dumpAlldumper_, dumpNormal(fd, ElementsAreArray(args)));
 
-    priorityDump(dumpAlldumper_, fd, args);
+    dumpAlldumper_.priorityDump(fd, args);
 }
 
 TEST_F(PriorityDumperTest, priorityArgWithPriorityMissing) {
     Vector<String16> args;
     addAll(args, {"--dump-priority"});
-    EXPECT_CALL(dumper_, dump(fd, ElementsAreArray(args)));
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args)));
 
-    priorityDump(dumper_, fd, args);
+    dumper_.priorityDump(fd, args);
 }
 
 TEST_F(PriorityDumperTest, priorityArgWithInvalidPriority) {
     Vector<String16> args;
     addAll(args, {"--dump-priority", "REALLY_HIGH"});
-    EXPECT_CALL(dumper_, dump(fd, ElementsAreArray(args)));
+    EXPECT_CALL(dumper_, dumpAll(fd, ElementsAreArray(args)));
 
-    priorityDump(dumper_, fd, args);
+    dumper_.priorityDump(fd, args);
 }
\ No newline at end of file