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

Commit 80e7d124 authored by lijilou's avatar lijilou
Browse files

Notification: The updateLightsLocked method should be called by the NMS.mNotificationLock lock.

The crash log as below:
 java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.PHONE_STATE flg=0x1000010 (has extras) } in com.android.server.notification.NotificationAttentionHelper$3@b85964e
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1905)
at android.app.LoadedApk$ReceiverDispatcher$Args.$r8$lambda$mcNAAl1SQ4MyJPyDg8TJ2x2h0Rk(Unknown Source:0)
at android.app.LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at android.os.Handler.handleCallback(Handler.java:959)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loopOnce(Looper.java:249)
at android.os.Looper.loop(Looper.java:337)
at com.android.server.SystemServer.run(SystemServer.java:1065)
at com.android.server.SystemServer.main(SystemServer.java:724)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:913)
Caused by: java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 0
at jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
at java.util.Objects.checkIndex(Objects.java:359)
at java.util.ArrayList.get(ArrayList.java:434)
at com.android.server.notification.NotificationAttentionHelper.updateLightsLocked(NotificationAttentionHelper.java:899)
at com.android.server.notification.NotificationAttentionHelper$3.onReceive(NotificationAttentionHelper.java:1641)
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1892)
... 11 more

Test: OEM monkey test
Bug:372183860
Change-Id: Ic87ec55c0ab2f430055ffa6850963298d7b5493b
parent 56149b13
Loading
Loading
Loading
Loading
+35 −15
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ import com.android.server.lights.LogicalLight;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import com.android.internal.annotations.GuardedBy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -119,6 +120,8 @@ public final class NotificationAttentionHelper {
    );

    private final Context mContext;
    //This is NMS.mNotificationLock.
    private final Object mLock;
    private final PackageManager mPackageManager;
    private final TelephonyManager mTelephonyManager;
    private final UserManager mUm;
@@ -132,6 +135,7 @@ public final class NotificationAttentionHelper {

    private VibratorHelper mVibratorHelper;
    // The last key in this list owns the hardware.
    @GuardedBy("mLock")
    ArrayList<String> mLights = new ArrayList<>();
    private LogicalLight mNotificationLight;
    private LogicalLight mAttentionLight;
@@ -149,8 +153,10 @@ public final class NotificationAttentionHelper {
    private String mVibrateNotificationKey;
    private boolean mSystemReady;
    private boolean mInCallStateOffHook = false;
    @GuardedBy("mLock")
    private boolean mScreenOn = true;
    private boolean mUserPresent = false;
    @GuardedBy("mLock")
    private boolean mNotificationPulseEnabled;
    private final Uri mInCallNotificationUri;
    private final AudioAttributes mInCallNotificationAudioAttributes;
@@ -166,12 +172,13 @@ public final class NotificationAttentionHelper {
    private final PolitenessStrategy mStrategy;
    private int mCurrentWorkProfileId = UserHandle.USER_NULL;

    public NotificationAttentionHelper(Context context, LightsManager lightsManager,
    public NotificationAttentionHelper(Context context, Object lock, LightsManager lightsManager,
            AccessibilityManager accessibilityManager, PackageManager packageManager,
            UserManager userManager, NotificationUsageStats usageStats,
            NotificationManagerPrivate notificationManagerPrivate,
            ZenModeHelper zenModeHelper, SystemUiSystemPropertiesFlags.FlagResolver flagResolver) {
        mContext = context;
        mLock = lock;
        mPackageManager = packageManager;
        mTelephonyManager = context.getSystemService(TelephonyManager.class);
        mAccessibilityManager = accessibilityManager;
@@ -315,10 +322,12 @@ public final class NotificationAttentionHelper {
    private void loadUserSettings() {
        boolean pulseEnabled = Settings.System.getIntForUser(mContext.getContentResolver(),
                Settings.System.NOTIFICATION_LIGHT_PULSE, 0, UserHandle.USER_CURRENT) != 0;
        synchronized (mLock) {
            if (mNotificationPulseEnabled != pulseEnabled) {
                mNotificationPulseEnabled = pulseEnabled;
                updateLightsLocked();
            }
        }

        if (Flags.politeNotifications()) {
            try {
@@ -1063,7 +1072,8 @@ public final class NotificationAttentionHelper {
        }
    }

    public void dump(PrintWriter pw, String prefix, NotificationManagerService.DumpFilter filter) {
    public void dumpLocked(PrintWriter pw, String prefix,
            NotificationManagerService.DumpFilter filter) {
        pw.println("\n  Notification attention state:");
        pw.print(prefix);
        pw.println("  mSoundNotificationKey=" + mSoundNotificationKey);
@@ -1591,16 +1601,22 @@ public final class NotificationAttentionHelper {
            if (action.equals(Intent.ACTION_SCREEN_ON)) {
                // Keep track of screen on/off state, but do not turn off the notification light
                // until user passes through the lock screen or views the notification.
                synchronized (mLock) {
                    mScreenOn = true;
                    updateLightsLocked();
                }
            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                synchronized (mLock) {
                    mScreenOn = false;
                    mUserPresent = false;
                    updateLightsLocked();
                }
            } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
                mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK
                        .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
                synchronized (mLock) {
                    updateLightsLocked();
                }
            } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                mUserPresent = true;
                // turn off LED when user passes through lock screen
@@ -1662,11 +1678,13 @@ public final class NotificationAttentionHelper {
                        Settings.System.NOTIFICATION_LIGHT_PULSE, 0,
                        UserHandle.USER_CURRENT)
                        != 0;
                synchronized (mLock) {
                    if (mNotificationPulseEnabled != pulseEnabled) {
                        mNotificationPulseEnabled = pulseEnabled;
                        updateLightsLocked();
                    }
                }
            }
            if (Flags.politeNotifications()) {
                if (NOTIFICATION_COOLDOWN_ENABLED_URI.equals(uri)) {
                    mNotificationCooldownEnabled = Settings.System.getIntForUser(
@@ -1747,8 +1765,10 @@ public final class NotificationAttentionHelper {

    @VisibleForTesting
    void setScreenOn(boolean on) {
        synchronized (mLock) {
            mScreenOn = on;
        }
    }

    @VisibleForTesting
    void setUserPresent(boolean userPresent) {
+4 −4
Original line number Diff line number Diff line
@@ -2573,9 +2573,9 @@ public class NotificationManagerService extends SystemService {
        mToastRateLimiter = toastRateLimiter;
        mAttentionHelper = new NotificationAttentionHelper(getContext(), lightsManager,
                mAccessibilityManager, mPackageManagerClient, userManager, usageStats,
                mNotificationManagerPrivate, mZenModeHelper, flagResolver);
        mAttentionHelper = new NotificationAttentionHelper(getContext(), mNotificationLock,
                lightsManager, mAccessibilityManager, mPackageManagerClient, userManager,
                usageStats, mNotificationManagerPrivate, mZenModeHelper, flagResolver);
        // register for various Intents.
        // If this is called within a test, make sure to unregister the intent receivers by
@@ -6916,7 +6916,7 @@ public class NotificationManagerService extends SystemService {
                    pw.println("  mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate);
                    pw.println("  hideSilentStatusBar="
                            + mPreferencesHelper.shouldHideSilentStatusIcons());
                    mAttentionHelper.dump(pw, "    ", filter);
                    mAttentionHelper.dumpLocked(pw, "    ", filter);
                }
                pw.println("  mArchive=" + mArchive.toString());
                mArchive.dumpImpl(pw, filter);
+4 −3
Original line number Diff line number Diff line
@@ -243,9 +243,10 @@ public class NotificationAttentionHelperTest extends UiServiceTestCase {
    }

    private void initAttentionHelper(TestableFlagResolver flagResolver) {
        mAttentionHelper = new NotificationAttentionHelper(getContext(), mock(LightsManager.class),
                mAccessibilityManager, mPackageManager, mUserManager, mUsageStats,
                mService.mNotificationManagerPrivate, mock(ZenModeHelper.class), flagResolver);
        mAttentionHelper = new NotificationAttentionHelper(getContext(), new Object(),
                mock(LightsManager.class),mAccessibilityManager, mPackageManager,
                mUserManager, mUsageStats, mService.mNotificationManagerPrivate,
                mock(ZenModeHelper.class), flagResolver);
        mAttentionHelper.onSystemReady();
        mAttentionHelper.setVibratorHelper(spy(new VibratorHelper(getContext())));
        mAttentionHelper.setAudioManager(mAudioManager);