Don't attach private Notification to A11yEvent when user locked
Fixes: 159624555 Test: manual, atest Change-Id: Ib44f1d3695d2b31bee4f8ccae3f948c83f3b40b6
This commit is contained in:
@@ -140,6 +140,7 @@ import android.app.INotificationManager;
|
|||||||
import android.app.ITransientNotification;
|
import android.app.ITransientNotification;
|
||||||
import android.app.ITransientNotificationCallback;
|
import android.app.ITransientNotificationCallback;
|
||||||
import android.app.IUriGrantsManager;
|
import android.app.IUriGrantsManager;
|
||||||
|
import android.app.KeyguardManager;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationChannelGroup;
|
import android.app.NotificationChannelGroup;
|
||||||
@@ -549,6 +550,8 @@ public class NotificationManagerService extends SystemService {
|
|||||||
// Used for rate limiting toasts by package.
|
// Used for rate limiting toasts by package.
|
||||||
private MultiRateLimiter mToastRateLimiter;
|
private MultiRateLimiter mToastRateLimiter;
|
||||||
|
|
||||||
|
private KeyguardManager mKeyguardManager;
|
||||||
|
|
||||||
// The last key in this list owns the hardware.
|
// The last key in this list owns the hardware.
|
||||||
ArrayList<String> mLights = new ArrayList<>();
|
ArrayList<String> mLights = new ArrayList<>();
|
||||||
|
|
||||||
@@ -2007,6 +2010,11 @@ public class NotificationManagerService extends SystemService {
|
|||||||
mAudioManager = audioMananger;
|
mAudioManager = audioMananger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void setKeyguardManager(KeyguardManager keyguardManager) {
|
||||||
|
mKeyguardManager = keyguardManager;
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
ShortcutHelper getShortcutHelper() {
|
ShortcutHelper getShortcutHelper() {
|
||||||
return mShortcutHelper;
|
return mShortcutHelper;
|
||||||
@@ -2653,6 +2661,7 @@ public class NotificationManagerService extends SystemService {
|
|||||||
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
|
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
|
||||||
mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
|
mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
|
||||||
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
|
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
|
||||||
|
mKeyguardManager = getContext().getSystemService(KeyguardManager.class);
|
||||||
mZenModeHelper.onSystemReady();
|
mZenModeHelper.onSystemReady();
|
||||||
RoleObserver roleObserver = new RoleObserver(getContext(),
|
RoleObserver roleObserver = new RoleObserver(getContext(),
|
||||||
getContext().getSystemService(RoleManager.class),
|
getContext().getSystemService(RoleManager.class),
|
||||||
@@ -7388,7 +7397,6 @@ public class NotificationManagerService extends SystemService {
|
|||||||
boolean beep = false;
|
boolean beep = false;
|
||||||
boolean blink = false;
|
boolean blink = false;
|
||||||
|
|
||||||
final Notification notification = record.getSbn().getNotification();
|
|
||||||
final String key = record.getKey();
|
final String key = record.getKey();
|
||||||
|
|
||||||
// Should this notification make noise, vibe, or use the LED?
|
// Should this notification make noise, vibe, or use the LED?
|
||||||
@@ -7410,7 +7418,7 @@ public class NotificationManagerService extends SystemService {
|
|||||||
if (!record.isUpdate
|
if (!record.isUpdate
|
||||||
&& record.getImportance() > IMPORTANCE_MIN
|
&& record.getImportance() > IMPORTANCE_MIN
|
||||||
&& !suppressedByDnd) {
|
&& !suppressedByDnd) {
|
||||||
sendAccessibilityEvent(notification, record.getSbn().getPackageName());
|
sendAccessibilityEvent(record);
|
||||||
sentAccessibilityEvent = true;
|
sentAccessibilityEvent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7433,7 +7441,7 @@ public class NotificationManagerService extends SystemService {
|
|||||||
boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
|
boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
|
||||||
if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
|
if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
|
||||||
if (!sentAccessibilityEvent) {
|
if (!sentAccessibilityEvent) {
|
||||||
sendAccessibilityEvent(notification, record.getSbn().getPackageName());
|
sendAccessibilityEvent(record);
|
||||||
sentAccessibilityEvent = true;
|
sentAccessibilityEvent = true;
|
||||||
}
|
}
|
||||||
if (DBG) Slog.v(TAG, "Interrupting!");
|
if (DBG) Slog.v(TAG, "Interrupting!");
|
||||||
@@ -8261,17 +8269,30 @@ public class NotificationManagerService extends SystemService {
|
|||||||
return (x < low) ? low : ((x > high) ? high : x);
|
return (x < low) ? low : ((x > high) ? high : x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
|
void sendAccessibilityEvent(NotificationRecord record) {
|
||||||
if (!mAccessibilityManager.isEnabled()) {
|
if (!mAccessibilityManager.isEnabled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessibilityEvent event =
|
final Notification notification = record.getNotification();
|
||||||
|
final CharSequence packageName = record.getSbn().getPackageName();
|
||||||
|
final AccessibilityEvent event =
|
||||||
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
|
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
|
||||||
event.setPackageName(packageName);
|
event.setPackageName(packageName);
|
||||||
event.setClassName(Notification.class.getName());
|
event.setClassName(Notification.class.getName());
|
||||||
event.setParcelableData(notification);
|
final int visibilityOverride = record.getPackageVisibilityOverride();
|
||||||
CharSequence tickerText = notification.tickerText;
|
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);
|
||||||
|
}
|
||||||
|
final CharSequence tickerText = notification.tickerText;
|
||||||
if (!TextUtils.isEmpty(tickerText)) {
|
if (!TextUtils.isEmpty(tickerText)) {
|
||||||
event.getText().add(tickerText);
|
event.getText().add(tickerText);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
|
import android.app.KeyguardManager;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.Notification.Builder;
|
import android.app.Notification.Builder;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
@@ -111,6 +112,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
|
|||||||
NotificationUsageStats mUsageStats;
|
NotificationUsageStats mUsageStats;
|
||||||
@Mock
|
@Mock
|
||||||
IAccessibilityManager mAccessibilityService;
|
IAccessibilityManager mAccessibilityService;
|
||||||
|
@Mock
|
||||||
|
KeyguardManager mKeyguardManager;
|
||||||
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
|
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
|
||||||
private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
|
private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
|
||||||
1 << 30);
|
1 << 30);
|
||||||
@@ -153,6 +156,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
|
|||||||
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
|
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
|
||||||
when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
|
when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
|
||||||
when(mVibrator.hasFrequencyControl()).thenReturn(false);
|
when(mVibrator.hasFrequencyControl()).thenReturn(false);
|
||||||
|
when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
|
||||||
|
|
||||||
long serviceReturnValue = IntPair.of(
|
long serviceReturnValue = IntPair.of(
|
||||||
AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
|
AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
|
||||||
@@ -174,6 +178,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
|
|||||||
mService.setScreenOn(false);
|
mService.setScreenOn(false);
|
||||||
mService.setUsageStats(mUsageStats);
|
mService.setUsageStats(mUsageStats);
|
||||||
mService.setAccessibilityManager(accessibilityManager);
|
mService.setAccessibilityManager(accessibilityManager);
|
||||||
|
mService.setKeyguardManager(mKeyguardManager);
|
||||||
mService.mScreenOn = false;
|
mService.mScreenOn = false;
|
||||||
mService.mInCallStateOffHook = false;
|
mService.mInCallStateOffHook = false;
|
||||||
mService.mNotificationPulseEnabled = true;
|
mService.mNotificationPulseEnabled = true;
|
||||||
@@ -495,6 +500,94 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
|
|||||||
assertNotEquals(-1, r.getLastAudiblyAlertedMs());
|
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
|
@Test
|
||||||
public void testBeepInsistently() throws Exception {
|
public void testBeepInsistently() throws Exception {
|
||||||
NotificationRecord r = getInsistentBeepyNotification();
|
NotificationRecord r = getInsistentBeepyNotification();
|
||||||
|
|||||||
Reference in New Issue
Block a user