Skip to content

Commit 47fcdec

Browse files
Steve ElliottAndroid Build Coastguard Worker
authored andcommitted
Don't attach private Notification to A11yEvent when user locked
Fixes: 159624555 Test: manual, atest Change-Id: Ib44f1d3695d2b31bee4f8ccae3f948c83f3b40b6 Merged-In: Ib44f1d3695d2b31bee4f8ccae3f948c83f3b40b6 (cherry picked from commit 54fbccc2934eae844550d851480d5448c2542f1d) (cherry picked from commit 0caa60087fe6859ae0b2d96c59cc6643c06c17fc)
1 parent 30f20d5 commit 47fcdec

2 files changed

Lines changed: 122 additions & 7 deletions

File tree

services/core/java/com/android/server/notification/NotificationManagerService.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
import android.app.ITransientNotification;
123123
import android.app.ITransientNotificationCallback;
124124
import android.app.IUriGrantsManager;
125+
import android.app.KeyguardManager;
125126
import android.app.Notification;
126127
import android.app.NotificationChannel;
127128
import android.app.NotificationChannelGroup;
@@ -478,6 +479,8 @@ public class NotificationManagerService extends SystemService {
478479
final ArrayMap<NotificationRecord, ArrayList<CancelNotificationRunnable>> mDelayedCancelations =
479480
new ArrayMap<>();
480481

482+
private KeyguardManager mKeyguardManager;
483+
481484
// The last key in this list owns the hardware.
482485
ArrayList<String> mLights = new ArrayList<>();
483486

@@ -1724,6 +1727,11 @@ void setAudioManager(AudioManager audioMananger) {
17241727
mAudioManager = audioMananger;
17251728
}
17261729

1730+
@VisibleForTesting
1731+
void setKeyguardManager(KeyguardManager keyguardManager) {
1732+
mKeyguardManager = keyguardManager;
1733+
}
1734+
17271735
@VisibleForTesting
17281736
ShortcutHelper getShortcutHelper() {
17291737
return mShortcutHelper;
@@ -2322,6 +2330,7 @@ public void onBootPhase(int phase) {
23222330
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
23232331
mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
23242332
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
2333+
mKeyguardManager = getContext().getSystemService(KeyguardManager.class);
23252334
mZenModeHelper.onSystemReady();
23262335
mRoleObserver = new RoleObserver(getContext().getSystemService(RoleManager.class),
23272336
mPackageManager, getContext().getMainExecutor());
@@ -6890,7 +6899,6 @@ int buzzBeepBlinkLocked(NotificationRecord record) {
68906899
boolean beep = false;
68916900
boolean blink = false;
68926901

6893-
final Notification notification = record.getSbn().getNotification();
68946902
final String key = record.getKey();
68956903

68966904
// Should this notification make noise, vibe, or use the LED?
@@ -6912,7 +6920,7 @@ int buzzBeepBlinkLocked(NotificationRecord record) {
69126920
if (!record.isUpdate
69136921
&& record.getImportance() > IMPORTANCE_MIN
69146922
&& !suppressedByDnd) {
6915-
sendAccessibilityEvent(notification, record.getSbn().getPackageName());
6923+
sendAccessibilityEvent(record);
69166924
sentAccessibilityEvent = true;
69176925
}
69186926

@@ -6934,7 +6942,7 @@ int buzzBeepBlinkLocked(NotificationRecord record) {
69346942
boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
69356943
if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
69366944
if (!sentAccessibilityEvent) {
6937-
sendAccessibilityEvent(notification, record.getSbn().getPackageName());
6945+
sendAccessibilityEvent(record);
69386946
sentAccessibilityEvent = true;
69396947
}
69406948
if (DBG) Slog.v(TAG, "Interrupting!");
@@ -7639,17 +7647,30 @@ static int clamp(int x, int low, int high) {
76397647
return (x < low) ? low : ((x > high) ? high : x);
76407648
}
76417649

7642-
void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
7650+
void sendAccessibilityEvent(NotificationRecord record) {
76437651
if (!mAccessibilityManager.isEnabled()) {
76447652
return;
76457653
}
76467654

7647-
AccessibilityEvent event =
7655+
final Notification notification = record.getNotification();
7656+
final CharSequence packageName = record.getSbn().getPackageName();
7657+
final AccessibilityEvent event =
76487658
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
76497659
event.setPackageName(packageName);
76507660
event.setClassName(Notification.class.getName());
7651-
event.setParcelableData(notification);
7652-
CharSequence tickerText = notification.tickerText;
7661+
final int visibilityOverride = record.getPackageVisibilityOverride();
7662+
final int notifVisibility = visibilityOverride == NotificationManager.VISIBILITY_NO_OVERRIDE
7663+
? notification.visibility : visibilityOverride;
7664+
final int userId = record.getUser().getIdentifier();
7665+
final boolean needPublic = userId >= 0 && mKeyguardManager.isDeviceLocked(userId);
7666+
if (needPublic && notifVisibility != Notification.VISIBILITY_PUBLIC) {
7667+
// Emit the public version if we're on the lockscreen and this notification isn't
7668+
// publicly visible.
7669+
event.setParcelableData(notification.publicVersion);
7670+
} else {
7671+
event.setParcelableData(notification);
7672+
}
7673+
final CharSequence tickerText = notification.tickerText;
76537674
if (!TextUtils.isEmpty(tickerText)) {
76547675
event.getText().add(tickerText);
76557676
}

services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import static org.mockito.Mockito.when;
4747

4848
import android.app.ActivityManager;
49+
import android.app.KeyguardManager;
4950
import android.app.Notification;
5051
import android.app.Notification.Builder;
5152
import android.app.NotificationChannel;
@@ -81,6 +82,7 @@
8182
import org.junit.Before;
8283
import org.junit.Test;
8384
import org.junit.runner.RunWith;
85+
import org.mockito.ArgumentCaptor;
8486
import org.mockito.ArgumentMatcher;
8587
import org.mockito.Mock;
8688
import org.mockito.Mockito;
@@ -100,6 +102,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
100102
NotificationUsageStats mUsageStats;
101103
@Mock
102104
IAccessibilityManager mAccessibilityService;
105+
@Mock
106+
KeyguardManager mKeyguardManager;
103107
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
104108
private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
105109
1 << 30);
@@ -144,6 +148,7 @@ public void setUp() throws Exception {
144148
when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
145149
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
146150
when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
151+
when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
147152

148153
long serviceReturnValue = IntPair.of(
149154
AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
@@ -165,6 +170,7 @@ public void setUp() throws Exception {
165170
mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
166171
mService.setUsageStats(mUsageStats);
167172
mService.setAccessibilityManager(accessibilityManager);
173+
mService.setKeyguardManager(mKeyguardManager);
168174
mService.mScreenOn = false;
169175
mService.mInCallStateOffHook = false;
170176
mService.mNotificationPulseEnabled = true;
@@ -475,6 +481,94 @@ public void testBeep() throws Exception {
475481
assertNotEquals(-1, r.getLastAudiblyAlertedMs());
476482
}
477483

484+
@Test
485+
public void testLockedPrivateA11yRedaction() throws Exception {
486+
NotificationRecord r = getBeepyNotification();
487+
r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
488+
r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
489+
when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
490+
AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
491+
when(accessibilityManager.isEnabled()).thenReturn(true);
492+
mService.setAccessibilityManager(accessibilityManager);
493+
494+
mService.buzzBeepBlinkLocked(r);
495+
496+
ArgumentCaptor<AccessibilityEvent> eventCaptor =
497+
ArgumentCaptor.forClass(AccessibilityEvent.class);
498+
499+
verify(accessibilityManager, times(1))
500+
.sendAccessibilityEvent(eventCaptor.capture());
501+
502+
AccessibilityEvent event = eventCaptor.getValue();
503+
assertEquals(r.getNotification().publicVersion, event.getParcelableData());
504+
}
505+
506+
@Test
507+
public void testLockedOverridePrivateA11yRedaction() throws Exception {
508+
NotificationRecord r = getBeepyNotification();
509+
r.setPackageVisibilityOverride(Notification.VISIBILITY_PRIVATE);
510+
r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
511+
when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
512+
AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
513+
when(accessibilityManager.isEnabled()).thenReturn(true);
514+
mService.setAccessibilityManager(accessibilityManager);
515+
516+
mService.buzzBeepBlinkLocked(r);
517+
518+
ArgumentCaptor<AccessibilityEvent> eventCaptor =
519+
ArgumentCaptor.forClass(AccessibilityEvent.class);
520+
521+
verify(accessibilityManager, times(1))
522+
.sendAccessibilityEvent(eventCaptor.capture());
523+
524+
AccessibilityEvent event = eventCaptor.getValue();
525+
assertEquals(r.getNotification().publicVersion, event.getParcelableData());
526+
}
527+
528+
@Test
529+
public void testLockedPublicA11yNoRedaction() throws Exception {
530+
NotificationRecord r = getBeepyNotification();
531+
r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
532+
r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
533+
when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
534+
AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
535+
when(accessibilityManager.isEnabled()).thenReturn(true);
536+
mService.setAccessibilityManager(accessibilityManager);
537+
538+
mService.buzzBeepBlinkLocked(r);
539+
540+
ArgumentCaptor<AccessibilityEvent> eventCaptor =
541+
ArgumentCaptor.forClass(AccessibilityEvent.class);
542+
543+
verify(accessibilityManager, times(1))
544+
.sendAccessibilityEvent(eventCaptor.capture());
545+
546+
AccessibilityEvent event = eventCaptor.getValue();
547+
assertEquals(r.getNotification(), event.getParcelableData());
548+
}
549+
550+
@Test
551+
public void testUnlockedPrivateA11yNoRedaction() throws Exception {
552+
NotificationRecord r = getBeepyNotification();
553+
r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
554+
r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
555+
when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
556+
AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
557+
when(accessibilityManager.isEnabled()).thenReturn(true);
558+
mService.setAccessibilityManager(accessibilityManager);
559+
560+
mService.buzzBeepBlinkLocked(r);
561+
562+
ArgumentCaptor<AccessibilityEvent> eventCaptor =
563+
ArgumentCaptor.forClass(AccessibilityEvent.class);
564+
565+
verify(accessibilityManager, times(1))
566+
.sendAccessibilityEvent(eventCaptor.capture());
567+
568+
AccessibilityEvent event = eventCaptor.getValue();
569+
assertEquals(r.getNotification(), event.getParcelableData());
570+
}
571+
478572
@Test
479573
public void testBeepInsistently() throws Exception {
480574
NotificationRecord r = getInsistentBeepyNotification();

0 commit comments

Comments
 (0)