Merge "Don't attach private Notification to A11yEvent when user locked" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
976266733d
@@ -110,6 +110,7 @@ import android.app.IActivityManager;
|
||||
import android.app.INotificationManager;
|
||||
import android.app.ITransientNotification;
|
||||
import android.app.IUriGrantsManager;
|
||||
import android.app.KeyguardManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationChannelGroup;
|
||||
@@ -423,6 +424,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<>();
|
||||
|
||||
@@ -1465,6 +1468,11 @@ public class NotificationManagerService extends SystemService {
|
||||
mAudioManager = audioMananger;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setKeyguardManager(KeyguardManager keyguardManager) {
|
||||
mKeyguardManager = keyguardManager;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setHints(int hints) {
|
||||
mListenerHints = hints;
|
||||
@@ -1920,6 +1928,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());
|
||||
@@ -5790,7 +5799,6 @@ public class NotificationManagerService extends SystemService {
|
||||
boolean beep = false;
|
||||
boolean blink = false;
|
||||
|
||||
final Notification notification = record.sbn.getNotification();
|
||||
final String key = record.getKey();
|
||||
|
||||
// Should this notification make noise, vibe, or use the LED?
|
||||
@@ -5809,7 +5817,7 @@ public class NotificationManagerService extends SystemService {
|
||||
// If the notification will appear in the status bar, it should send an accessibility
|
||||
// event
|
||||
if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN) {
|
||||
sendAccessibilityEvent(notification, record.sbn.getPackageName());
|
||||
sendAccessibilityEvent(record);
|
||||
sentAccessibilityEvent = true;
|
||||
}
|
||||
|
||||
@@ -5833,7 +5841,7 @@ public class NotificationManagerService extends SystemService {
|
||||
boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
|
||||
if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
|
||||
if (!sentAccessibilityEvent) {
|
||||
sendAccessibilityEvent(notification, record.sbn.getPackageName());
|
||||
sendAccessibilityEvent(record);
|
||||
sentAccessibilityEvent = true;
|
||||
}
|
||||
if (DBG) Slog.v(TAG, "Interrupting!");
|
||||
@@ -6500,17 +6508,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.sbn.getPackageName();
|
||||
final AccessibilityEvent event =
|
||||
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
|
||||
event.setPackageName(packageName);
|
||||
event.setClassName(Notification.class.getName());
|
||||
event.setParcelableData(notification);
|
||||
CharSequence tickerText = notification.tickerText;
|
||||
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);
|
||||
}
|
||||
final CharSequence tickerText = notification.tickerText;
|
||||
if (!TextUtils.isEmpty(tickerText)) {
|
||||
event.getText().add(tickerText);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,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;
|
||||
@@ -77,6 +78,7 @@ import com.android.server.lights.Light;
|
||||
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;
|
||||
@@ -96,6 +98,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
|
||||
NotificationUsageStats mUsageStats;
|
||||
@Mock
|
||||
IAccessibilityManager mAccessibilityService;
|
||||
@Mock
|
||||
KeyguardManager mKeyguardManager;
|
||||
private InjectableSystemClock mSystemClock = new FakeSystemClock();
|
||||
|
||||
private NotificationManagerService mService;
|
||||
@@ -136,6 +140,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,
|
||||
@@ -156,6 +161,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
|
||||
mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
|
||||
mService.setUsageStats(mUsageStats);
|
||||
mService.setAccessibilityManager(accessibilityManager);
|
||||
mService.setKeyguardManager(mKeyguardManager);
|
||||
mService.mScreenOn = false;
|
||||
mService.mInCall = false;
|
||||
mService.mNotificationPulseEnabled = true;
|
||||
@@ -433,6 +439,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();
|
||||
|
||||
Reference in New Issue
Block a user