Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3e4d251 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

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
parent f3537c20
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -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 @@ public abstract class SystemService {

    /**
     * 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 @@ public abstract class SystemService {

    /**
     * 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);
    }

    /**
+3 −0
Original line number Diff line number Diff line
@@ -703,6 +703,8 @@ public class ActivityManagerService extends IActivityManager.Stub
    // 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 @@ public class ActivityManagerService extends IActivityManager.Stub
                boolean asProto) {
            if (asProto) return;
            doDump(fd, pw, new String[]{"activities"}, asProto);
            doDump(fd, pw, new String[]{"service", SYSUI_COMPONENT_NAME}, asProto);
        }
        @Override
+47 −11
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import static android.app.NotificationManager.IMPORTANCE_NONE;
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.service.notification.NotificationListenerService.TRIM_LIGH
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 @@ public class NotificationManagerService extends SystemService {
        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 @@ public class NotificationManagerService extends SystemService {
                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 @@ public class NotificationManagerService extends SystemService {
        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 @@ public class NotificationManagerService extends SystemService {

        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 class NotificationManagerService extends SystemService {
        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 @@ public class NotificationManagerService extends SystemService {
                    } 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;
+11 −10
Original line number Diff line number Diff line
@@ -94,11 +94,7 @@ public class SpringfieldNuclearPowerPlant extends Binder {
 * <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 final class PriorityDump {

    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,18 +190,20 @@ public final class PriorityDump {
     */
    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;
            }
        }
    }

    /**
     * Helper for {@link android.os.Binder#dump(java.io.FileDescriptor, String[])} that supports the
@@ -238,7 +239,7 @@ public final class PriorityDump {
         * 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.
         */