Dump systemUI and notification service in bugreport critical section
- modified publishBinderService to accept dump prioirty arguments
- registed NotificationManagerService with critical and normal dump support and
split dump into critical and normal sections
- ActivityManagerService critical section duration (manual runs): 0.024s, 0.050s, 0.038s
- NotificationManagerService critical section duration (manual runs): 0.007s,0.017s
Bug: 73958222
Test: Take bug report and verify contents
Test: mmm -j56 frameworks/native/cmds/dumpstate && \
adb sync data && adb shell /data/nativetest64/dumpstate_smoke_test/dumpstate_smoke_test && \
atest FrameworksServicesTests:PriorityDumpTest && \
printf "\n\n#### ALL TESTS PASSED ####\n"
Change-Id: I23cc9c056a550505393222f521cba5841782132e
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index 58731d2..8e9e74e 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -16,6 +16,8 @@
package com.android.server;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT;
+
import android.app.ActivityThread;
import android.content.Context;
import android.os.IBinder;
@@ -199,6 +201,9 @@
/**
* Publish the service so it is accessible to other services and apps.
+ *
+ * @param name the name of the new service
+ * @param service the service object
*/
protected final void publishBinderService(String name, IBinder service) {
publishBinderService(name, service, false);
@@ -206,10 +211,29 @@
/**
* Publish the service so it is accessible to other services and apps.
+ *
+ * @param name the name of the new service
+ * @param service the service object
+ * @param allowIsolated set to true to allow isolated sandboxed processes
+ * to access this service
*/
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated) {
- ServiceManager.addService(name, service, allowIsolated);
+ publishBinderService(name, service, allowIsolated, DUMP_FLAG_PRIORITY_DEFAULT);
+ }
+
+ /**
+ * Publish the service so it is accessible to other services and apps.
+ *
+ * @param name the name of the new service
+ * @param service the service object
+ * @param allowIsolated set to true to allow isolated sandboxed processes
+ * to access this service
+ * @param dumpPriority supported dump priority levels as a bitmask
+ */
+ protected final void publishBinderService(String name, IBinder service,
+ boolean allowIsolated, int dumpPriority) {
+ ServiceManager.addService(name, service, allowIsolated, dumpPriority);
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index da88667..dc1b3bf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -703,6 +703,8 @@
// Whether we should use SCHED_FIFO for UI and RenderThreads.
private boolean mUseFifoUiScheduling = false;
+ private static final String SYSUI_COMPONENT_NAME = "com.android.systemui/.SystemUIService";
+
BroadcastQueue mFgBroadcastQueue;
BroadcastQueue mBgBroadcastQueue;
// Convenient for easy iteration over the queues. Foreground is first
@@ -802,6 +804,7 @@
boolean asProto) {
if (asProto) return;
doDump(fd, pw, new String[]{"activities"}, asProto);
+ doDump(fd, pw, new String[]{"service", SYSUI_COMPONENT_NAME}, asProto);
}
@Override
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ef354cd..b1bc462 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -25,6 +25,8 @@
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_NULL;
import static android.os.UserHandle.USER_SYSTEM;
@@ -65,6 +67,10 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static com.android.server.utils.PriorityDump.PRIORITY_ARG;
+import static com.android.server.utils.PriorityDump.PRIORITY_ARG_CRITICAL;
+import static com.android.server.utils.PriorityDump.PRIORITY_ARG_NORMAL;
+
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -1476,7 +1482,8 @@
IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
getContext().registerReceiver(mLocaleChangeReceiver, localeChangedFilter);
- publishBinderService(Context.NOTIFICATION_SERVICE, mService);
+ publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
+ DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL);
publishLocalService(NotificationManagerInternal.class, mInternalService);
}
@@ -2896,6 +2903,8 @@
dumpJson(pw, filter);
} else if (filter.proto) {
dumpProto(fd, filter);
+ } else if (filter.criticalPriority) {
+ dumpNotificationRecords(pw, filter);
} else {
dumpImpl(pw, filter);
}
@@ -3521,6 +3530,22 @@
proto.flush();
}
+ private void dumpNotificationRecords(PrintWriter pw, @NonNull DumpFilter filter) {
+ synchronized (mNotificationLock) {
+ int N;
+ N = mNotificationList.size();
+ if (N > 0) {
+ pw.println(" Notification List:");
+ for (int i = 0; i < N; i++) {
+ final NotificationRecord nr = mNotificationList.get(i);
+ if (filter.filtered && !filter.matches(nr.sbn)) continue;
+ nr.dump(pw, " ", getContext(), filter.redact);
+ }
+ pw.println(" ");
+ }
+ }
+ }
+
void dumpImpl(PrintWriter pw, @NonNull DumpFilter filter) {
pw.print("Current Notification Manager state");
if (filter.filtered) {
@@ -3545,17 +3570,11 @@
synchronized (mNotificationLock) {
if (!zenOnly) {
- N = mNotificationList.size();
- if (N > 0) {
- pw.println(" Notification List:");
- for (int i=0; i<N; i++) {
- final NotificationRecord nr = mNotificationList.get(i);
- if (filter.filtered && !filter.matches(nr.sbn)) continue;
- nr.dump(pw, " ", getContext(), filter.redact);
- }
- pw.println(" ");
+ // Priority filters are only set when called via bugreport. If set
+ // skip sections that are part of the critical section.
+ if (!filter.normalPriority) {
+ dumpNotificationRecords(pw, filter);
}
-
if (!filter.filtered) {
N = mLights.size();
if (N > 0) {
@@ -6202,6 +6221,8 @@
public boolean stats;
public boolean redact = true;
public boolean proto = false;
+ public boolean criticalPriority = false;
+ public boolean normalPriority = false;
@NonNull
public static DumpFilter parseFromArguments(String[] args) {
@@ -6233,6 +6254,21 @@
} else {
filter.since = 0;
}
+ } else if (PRIORITY_ARG.equals(a)) {
+ // Bugreport will call the service twice with priority arguments, first to dump
+ // critical sections and then non critical ones. Set approriate filters
+ // to generate the desired data.
+ if (ai < args.length - 1) {
+ ai++;
+ switch (args[ai]) {
+ case PRIORITY_ARG_CRITICAL:
+ filter.criticalPriority = true;
+ break;
+ case PRIORITY_ARG_NORMAL:
+ filter.normalPriority = true;
+ break;
+ }
+ }
}
}
return filter;
diff --git a/services/core/java/com/android/server/utils/PriorityDump.java b/services/core/java/com/android/server/utils/PriorityDump.java
index fb92c2b..d9fb9c0 100644
--- a/services/core/java/com/android/server/utils/PriorityDump.java
+++ b/services/core/java/com/android/server/utils/PriorityDump.java
@@ -94,11 +94,7 @@
* <p>To run the unit tests:
* <pre><code>
*
- mmm -j32 frameworks/base/services/tests/servicestests/ && \
- adb install -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && \
- adb shell am instrument -e class "com.android.server.utils.PriorityDumpTest" \
- -w "com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner"
-
+ atest FrameworksServicesTests:PriorityDumpTest
* </code></pre>
*
*
@@ -108,6 +104,9 @@
public static final String PRIORITY_ARG = "--dump-priority";
public static final String PROTO_ARG = "--proto";
+ public static final String PRIORITY_ARG_CRITICAL = "CRITICAL";
+ public static final String PRIORITY_ARG_HIGH = "HIGH";
+ public static final String PRIORITY_ARG_NORMAL = "NORMAL";
private PriorityDump() {
throw new UnsupportedOperationException();
@@ -191,17 +190,19 @@
*/
private static @PriorityType int getPriorityType(String arg) {
switch (arg) {
- case "CRITICAL": {
+ case PRIORITY_ARG_CRITICAL: {
return PRIORITY_TYPE_CRITICAL;
}
- case "HIGH": {
+ case PRIORITY_ARG_HIGH: {
return PRIORITY_TYPE_HIGH;
}
- case "NORMAL": {
+ case PRIORITY_ARG_NORMAL: {
return PRIORITY_TYPE_NORMAL;
}
+ default: {
+ return PRIORITY_TYPE_INVALID;
+ }
}
- return PRIORITY_TYPE_INVALID;
}
/**
@@ -238,7 +239,7 @@
* Dumps all sections.
* <p>
* This method is called when
- * {@link PriorityDump#dump(PriorityDumper, FileDescriptor, PrintWriter, String[], boolean)}
+ * {@link PriorityDump#dump(PriorityDumper, FileDescriptor, PrintWriter, String[])}
* is called without priority arguments. By default, it calls the 3 {@code dumpTYPE}
* methods, so sub-classes just need to implement the priority types they support.
*/