Skip to content

Commit 5f2616c

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 40574b32076bc1de5ef1a29daf693c3673e96ba1)
1 parent d5b1cf4 commit 5f2616c

2 files changed

Lines changed: 121 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
@@ -123,6 +123,7 @@
123123
import android.app.ITransientNotification;
124124
import android.app.ITransientNotificationCallback;
125125
import android.app.IUriGrantsManager;
126+
import android.app.KeyguardManager;
126127
import android.app.Notification;
127128
import android.app.NotificationChannel;
128129
import android.app.NotificationChannelGroup;
@@ -479,6 +480,8 @@ public class NotificationManagerService extends SystemService {
479480
final ArrayMap<NotificationRecord, ArrayList<CancelNotificationRunnable>> mDelayedCancelations =
480481
new ArrayMap<>();
481482

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

@@ -1725,6 +1728,11 @@ void setAudioManager(AudioManager audioMananger) {
17251728
mAudioManager = audioMananger;
17261729
}
17271730

1731+
@VisibleForTesting
1732+
void setKeyguardManager(KeyguardManager keyguardManager) {
1733+
mKeyguardManager = keyguardManager;
1734+
}
1735+
17281736
@VisibleForTesting
17291737
ShortcutHelper getShortcutHelper() {
17301738
return mShortcutHelper;
@@ -2330,6 +2338,7 @@ public void onBootPhase(int phase) {
23302338
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
23312339
mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
23322340
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
2341+
mKeyguardManager = getContext().getSystemService(KeyguardManager.class);
23332342
mZenModeHelper.onSystemReady();
23342343
mRoleObserver = new RoleObserver(getContext().getSystemService(RoleManager.class),
23352344
mPackageManager, getContext().getMainExecutor());
@@ -6902,7 +6911,6 @@ int buzzBeepBlinkLocked(NotificationRecord record) {
69026911
boolean beep = false;
69036912
boolean blink = false;
69046913

6905-
final Notification notification = record.getSbn().getNotification();
69066914
final String key = record.getKey();
69076915

69086916
// Should this notification make noise, vibe, or use the LED?
@@ -6924,7 +6932,7 @@ int buzzBeepBlinkLocked(NotificationRecord record) {
69246932
if (!record.isUpdate
69256933
&& record.getImportance() > IMPORTANCE_MIN
69266934
&& !suppressedByDnd) {
6927-
sendAccessibilityEvent(notification, record.getSbn().getPackageName());
6935+
sendAccessibilityEvent(record);
69286936
sentAccessibilityEvent = true;
69296937
}
69306938

@@ -6946,7 +6954,7 @@ int buzzBeepBlinkLocked(NotificationRecord record) {
69466954
boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
69476955
if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
69486956
if (!sentAccessibilityEvent) {
6949-
sendAccessibilityEvent(notification, record.getSbn().getPackageName());
6957+
sendAccessibilityEvent(record);
69506958
sentAccessibilityEvent = true;
69516959
}
69526960
if (DBG) Slog.v(TAG, "Interrupting!");
@@ -7659,17 +7667,30 @@ static int clamp(int x, int low, int high) {
76597667
return (x < low) ? low : ((x > high) ? high : x);
76607668
}
76617669

7662-
void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
7670+
void sendAccessibilityEvent(NotificationRecord record) {
76637671
if (!mAccessibilityManager.isEnabled()) {
76647672
return;
76657673
}
76667674

7667-
AccessibilityEvent event =
7675+
final Notification notification = record.getNotification();
7676+
final CharSequence packageName = record.getSbn().getPackageName();
7677+
final AccessibilityEvent event =
76687678
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
76697679
event.setPackageName(packageName);
76707680
event.setClassName(Notification.class.getName());
7671-
event.setParcelableData(notification);
7672-
CharSequence tickerText = notification.tickerText;
7681+
final int visibilityOverride = record.getPackageVisibilityOverride();
7682+
final int notifVisibility = visibilityOverride == NotificationManager.VISIBILITY_NO_OVERRIDE
7683+
? notification.visibility : visibilityOverride;
7684+
final int userId = record.getUser().getIdentifier();
7685+
final boolean needPublic = userId >= 0 && mKeyguardManager.isDeviceLocked(userId);
7686+
if (needPublic && notifVisibility != Notification.VISIBILITY_PUBLIC) {
7687+
// Emit the public version if we're on the lockscreen and this notification isn't
7688+
// publicly visible.
7689+
event.setParcelableData(notification.publicVersion);
7690+
} else {
7691+
event.setParcelableData(notification);
7692+
}
7693+
final CharSequence tickerText = notification.tickerText;
76737694
if (!TextUtils.isEmpty(tickerText)) {
76747695
event.getText().add(tickerText);
76757696
}

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

Lines changed: 93 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;
@@ -103,6 +104,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
103104
NotificationUsageStats mUsageStats;
104105
@Mock
105106
IAccessibilityManager mAccessibilityService;
107+
@Mock
108+
KeyguardManager mKeyguardManager;
106109
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
107110
private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
108111
1 << 30);
@@ -147,6 +150,7 @@ public void setUp() throws Exception {
147150
when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
148151
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
149152
when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
153+
when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
150154

151155
long serviceReturnValue = IntPair.of(
152156
AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
@@ -168,6 +172,7 @@ public void setUp() throws Exception {
168172
mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
169173
mService.setUsageStats(mUsageStats);
170174
mService.setAccessibilityManager(accessibilityManager);
175+
mService.setKeyguardManager(mKeyguardManager);
171176
mService.mScreenOn = false;
172177
mService.mInCallStateOffHook = false;
173178
mService.mNotificationPulseEnabled = true;
@@ -483,6 +488,94 @@ public void testBeep() throws Exception {
483488
assertNotEquals(-1, r.getLastAudiblyAlertedMs());
484489
}
485490

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

0 commit comments

Comments
 (0)