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

Commit abd2fc4b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Don't attach private Notification to A11yEvent when user locked" into rvc-dev

parents a40db193 0caa6008
Loading
Loading
Loading
Loading
+28 −7
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ import android.app.INotificationManager;
import android.app.ITransientNotification;
import android.app.ITransientNotificationCallback;
import android.app.IUriGrantsManager;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -478,6 +479,8 @@ public class NotificationManagerService extends SystemService {
    final ArrayMap<NotificationRecord, ArrayList<CancelNotificationRunnable>> mDelayedCancelations =
            new ArrayMap<>();

    private KeyguardManager mKeyguardManager;

    // The last key in this list owns the hardware.
    ArrayList<String> mLights = new ArrayList<>();

@@ -1724,6 +1727,11 @@ public class NotificationManagerService extends SystemService {
        mAudioManager = audioMananger;
    }

    @VisibleForTesting
    void setKeyguardManager(KeyguardManager keyguardManager) {
        mKeyguardManager = keyguardManager;
    }

    @VisibleForTesting
    ShortcutHelper getShortcutHelper() {
        return mShortcutHelper;
@@ -2322,6 +2330,7 @@ public class NotificationManagerService extends SystemService {
            mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
            mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
            mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
            mKeyguardManager = getContext().getSystemService(KeyguardManager.class);
            mZenModeHelper.onSystemReady();
            mRoleObserver = new RoleObserver(getContext().getSystemService(RoleManager.class),
                    mPackageManager, getContext().getMainExecutor());
@@ -6890,7 +6899,6 @@ public class NotificationManagerService extends SystemService {
        boolean beep = false;
        boolean blink = false;

        final Notification notification = record.getSbn().getNotification();
        final String key = record.getKey();

        // Should this notification make noise, vibe, or use the LED?
@@ -6912,7 +6920,7 @@ public class NotificationManagerService extends SystemService {
        if (!record.isUpdate
                && record.getImportance() > IMPORTANCE_MIN
                && !suppressedByDnd) {
            sendAccessibilityEvent(notification, record.getSbn().getPackageName());
            sendAccessibilityEvent(record);
            sentAccessibilityEvent = true;
        }

@@ -6934,7 +6942,7 @@ public class NotificationManagerService extends SystemService {
                boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
                if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
                    if (!sentAccessibilityEvent) {
                        sendAccessibilityEvent(notification, record.getSbn().getPackageName());
                        sendAccessibilityEvent(record);
                        sentAccessibilityEvent = true;
                    }
                    if (DBG) Slog.v(TAG, "Interrupting!");
@@ -7639,17 +7647,30 @@ public class NotificationManagerService extends SystemService {
        return (x < low) ? low : ((x > high) ? high : x);
    }

    void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
    void sendAccessibilityEvent(NotificationRecord record) {
        if (!mAccessibilityManager.isEnabled()) {
            return;
        }

        AccessibilityEvent event =
        final Notification notification = record.getNotification();
        final CharSequence packageName = record.getSbn().getPackageName();
        final AccessibilityEvent event =
            AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
        event.setPackageName(packageName);
        event.setClassName(Notification.class.getName());
        final int visibilityOverride = record.getPackageVisibilityOverride();
        final int notifVisibility = visibilityOverride == NotificationManager.VISIBILITY_NO_OVERRIDE
                ? notification.visibility : visibilityOverride;
        final int userId = record.getUser().getIdentifier();
        final boolean needPublic = userId >= 0 && mKeyguardManager.isDeviceLocked(userId);
        if (needPublic && notifVisibility != Notification.VISIBILITY_PUBLIC) {
            // Emit the public version if we're on the lockscreen and this notification isn't
            // publicly visible.
            event.setParcelableData(notification.publicVersion);
        } else {
            event.setParcelableData(notification);
        CharSequence tickerText = notification.tickerText;
        }
        final CharSequence tickerText = notification.tickerText;
        if (!TextUtils.isEmpty(tickerText)) {
            event.getText().add(tickerText);
        }
+94 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.Notification.Builder;
import android.app.NotificationChannel;
@@ -81,6 +82,7 @@ import com.android.server.lights.LogicalLight;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.Mockito;
@@ -100,6 +102,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
    NotificationUsageStats mUsageStats;
    @Mock
    IAccessibilityManager mAccessibilityService;
    @Mock
    KeyguardManager mKeyguardManager;
    NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
    private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
            1 << 30);
@@ -144,6 +148,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
        when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);

        long serviceReturnValue = IntPair.of(
                AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
@@ -165,6 +170,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
        mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
        mService.setUsageStats(mUsageStats);
        mService.setAccessibilityManager(accessibilityManager);
        mService.setKeyguardManager(mKeyguardManager);
        mService.mScreenOn = false;
        mService.mInCallStateOffHook = false;
        mService.mNotificationPulseEnabled = true;
@@ -475,6 +481,94 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
    }

    @Test
    public void testLockedPrivateA11yRedaction() throws Exception {
        NotificationRecord r = getBeepyNotification();
        r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
        r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
        when(accessibilityManager.isEnabled()).thenReturn(true);
        mService.setAccessibilityManager(accessibilityManager);

        mService.buzzBeepBlinkLocked(r);

        ArgumentCaptor<AccessibilityEvent> eventCaptor =
                ArgumentCaptor.forClass(AccessibilityEvent.class);

        verify(accessibilityManager, times(1))
                .sendAccessibilityEvent(eventCaptor.capture());

        AccessibilityEvent event = eventCaptor.getValue();
        assertEquals(r.getNotification().publicVersion, event.getParcelableData());
    }

    @Test
    public void testLockedOverridePrivateA11yRedaction() throws Exception {
        NotificationRecord r = getBeepyNotification();
        r.setPackageVisibilityOverride(Notification.VISIBILITY_PRIVATE);
        r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
        when(accessibilityManager.isEnabled()).thenReturn(true);
        mService.setAccessibilityManager(accessibilityManager);

        mService.buzzBeepBlinkLocked(r);

        ArgumentCaptor<AccessibilityEvent> eventCaptor =
                ArgumentCaptor.forClass(AccessibilityEvent.class);

        verify(accessibilityManager, times(1))
                .sendAccessibilityEvent(eventCaptor.capture());

        AccessibilityEvent event = eventCaptor.getValue();
        assertEquals(r.getNotification().publicVersion, event.getParcelableData());
    }

    @Test
    public void testLockedPublicA11yNoRedaction() throws Exception {
        NotificationRecord r = getBeepyNotification();
        r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
        r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
        when(accessibilityManager.isEnabled()).thenReturn(true);
        mService.setAccessibilityManager(accessibilityManager);

        mService.buzzBeepBlinkLocked(r);

        ArgumentCaptor<AccessibilityEvent> eventCaptor =
                ArgumentCaptor.forClass(AccessibilityEvent.class);

        verify(accessibilityManager, times(1))
                .sendAccessibilityEvent(eventCaptor.capture());

        AccessibilityEvent event = eventCaptor.getValue();
        assertEquals(r.getNotification(), event.getParcelableData());
    }

    @Test
    public void testUnlockedPrivateA11yNoRedaction() throws Exception {
        NotificationRecord r = getBeepyNotification();
        r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
        r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
        when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
        AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
        when(accessibilityManager.isEnabled()).thenReturn(true);
        mService.setAccessibilityManager(accessibilityManager);

        mService.buzzBeepBlinkLocked(r);

        ArgumentCaptor<AccessibilityEvent> eventCaptor =
                ArgumentCaptor.forClass(AccessibilityEvent.class);

        verify(accessibilityManager, times(1))
                .sendAccessibilityEvent(eventCaptor.capture());

        AccessibilityEvent event = eventCaptor.getValue();
        assertEquals(r.getNotification(), event.getParcelableData());
    }

    @Test
    public void testBeepInsistently() throws Exception {
        NotificationRecord r = getInsistentBeepyNotification();