Merge "Send a11y updates for updated notifications" into oc-mr1-dev
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4e46535..842ee91 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -281,6 +281,7 @@
private WindowManagerInternal mWindowManagerInternal;
private AlarmManager mAlarmManager;
private ICompanionDeviceManager mCompanionManager;
+ private AccessibilityManager mAccessibilityManager;
final IBinder mForegroundToken = new Binder();
private WorkerHandler mHandler;
@@ -1190,6 +1191,12 @@
mUsageStats = us;
}
+ @VisibleForTesting
+ void setAccessibilityManager(AccessibilityManager am) {
+ mAccessibilityManager = am;
+ }
+
+
// TODO: All tests should use this init instead of the one-off setters above.
@VisibleForTesting
void init(Looper looper, IPackageManager packageManager,
@@ -1204,6 +1211,8 @@
Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE);
+ mAccessibilityManager =
+ (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
mAm = ActivityManager.getService();
mPackageManager = packageManager;
mPackageManagerClient = packageManagerClient;
@@ -4015,13 +4024,16 @@
// These are set inside the conditional if the notification is allowed to make noise.
boolean hasValidVibrate = false;
boolean hasValidSound = false;
+ boolean sentAccessibilityEvent = false;
+ // 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());
+ sentAccessibilityEvent = true;
+ }
if (aboveThreshold && isNotificationForCurrentUser(record)) {
- // 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());
- }
+
if (mSystemReady && mAudioManager != null) {
Uri soundUri = record.getSound();
hasValidSound = soundUri != null && !Uri.EMPTY.equals(soundUri);
@@ -4039,6 +4051,10 @@
boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
+ if (!sentAccessibilityEvent) {
+ sendAccessibilityEvent(notification, record.sbn.getPackageName());
+ sentAccessibilityEvent = true;
+ }
if (DBG) Slog.v(TAG, "Interrupting!");
if (hasValidSound) {
mSoundNotificationKey = key;
@@ -4556,8 +4572,7 @@
}
void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
- AccessibilityManager manager = AccessibilityManager.getInstance(getContext());
- if (!manager.isEnabled()) {
+ if (!mAccessibilityManager.isEnabled()) {
return;
}
@@ -4571,7 +4586,7 @@
event.getText().add(tickerText);
}
- manager.sendAccessibilityEvent(event);
+ mAccessibilityManager.sendAccessibilityEvent(event);
}
/**
diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 9fa1d68..0b4d61f 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -19,6 +19,7 @@
import static android.app.Notification.GROUP_ALERT_CHILDREN;
import static android.app.Notification.GROUP_ALERT_SUMMARY;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
@@ -57,7 +58,13 @@
import android.service.notification.StatusBarNotification;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Slog;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IAccessibilityManager;
+import android.view.accessibility.IAccessibilityManagerClient;
+import com.android.internal.util.IntPair;
import com.android.server.lights.Light;
import org.junit.Before;
@@ -67,6 +74,8 @@
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -80,6 +89,8 @@
NotificationManagerService.WorkerHandler mHandler;
@Mock
NotificationUsageStats mUsageStats;
+ @Mock
+ IAccessibilityManager mAccessibilityService;
private NotificationManagerService mService;
private String mPkg = "com.android.server.notification";
@@ -111,17 +122,25 @@
private static final int MAX_VIBRATION_DELAY = 1000;
@Before
- public void setUp() {
+ public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mAudioManager.isAudioFocusExclusive()).thenReturn(false);
when(mAudioManager.getRingtonePlayer()).thenReturn(mRingtonePlayer);
when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
-
when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
- mService = new NotificationManagerService(getContext());
+ long serviceReturnValue = IntPair.of(
+ AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
+ AccessibilityEvent.TYPES_ALL_MASK);
+ when(mAccessibilityService.addClient(any(), anyInt())).thenReturn(serviceReturnValue);
+ AccessibilityManager accessibilityManager =
+ new AccessibilityManager(Handler.getMain(), mAccessibilityService, 0);
+ verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt());
+ assertTrue(accessibilityManager.isEnabled());
+
+ mService = spy(new NotificationManagerService(getContext()));
mService.setAudioManager(mAudioManager);
mService.setVibrator(mVibrator);
mService.setSystemReady(true);
@@ -130,6 +149,7 @@
mService.setScreenOn(false);
mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
mService.setUsageStats(mUsageStats);
+ mService.setAccessibilityManager(accessibilityManager);
}
//
@@ -381,6 +401,7 @@
verifyBeepLooped();
verifyNeverVibrate();
+ verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
}
@Test
@@ -435,6 +456,7 @@
r.isUpdate = true;
mService.buzzBeepBlinkLocked(r);
verifyBeepLooped();
+ verify(mAccessibilityService, times(2)).sendAccessibilityEvent(any(), anyInt());
}
@Test
@@ -450,6 +472,7 @@
// update should not beep
mService.buzzBeepBlinkLocked(s);
verifyNeverBeep();
+ verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
}
@Test
@@ -547,7 +570,7 @@
mService.mInCall = true;
mService.buzzBeepBlinkLocked(r);
- //verify(mService, times(1)).playInCallNotification();
+ verify(mService, times(1)).playInCallNotification();
verifyNeverBeep(); // doesn't play normal beep
}
@@ -842,7 +865,6 @@
mService.addNotification(r);
mService.buzzBeepBlinkLocked(r);
-
verifyNeverBeep();
}
@@ -870,7 +892,6 @@
summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
mService.buzzBeepBlinkLocked(summary);
-
verify(mUsageStats, never()).isAlertRateLimited(any());
}
@@ -889,6 +910,30 @@
verifyNeverBeep();
}
+ @Test
+ public void testA11yMinInitialPost() throws Exception {
+ NotificationRecord r = getQuietNotification();
+ r.setImportance(IMPORTANCE_MIN, "");
+ mService.buzzBeepBlinkLocked(r);
+ verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt());
+ }
+
+ @Test
+ public void testA11yQuietInitialPost() throws Exception {
+ NotificationRecord r = getQuietNotification();
+ mService.buzzBeepBlinkLocked(r);
+ verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
+ }
+
+ @Test
+ public void testA11yQuietUpdate() throws Exception {
+ NotificationRecord r = getQuietNotification();
+ mService.buzzBeepBlinkLocked(r);
+ r.isUpdate = true;
+ mService.buzzBeepBlinkLocked(r);
+ verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
+ }
+
static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
private final int mRepeatIndex;
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 8210403..163250d 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -296,6 +296,7 @@
Notification n = new Notification.Builder(NotificationTestList.this, "min")
.setSmallIcon(R.drawable.icon2)
.setContentTitle("Min priority")
+ .setTicker("Min priority")
.build();
mNM.notify("min", 7000, n);
}
@@ -306,6 +307,7 @@
Notification n = new Notification.Builder(NotificationTestList.this, "low")
.setSmallIcon(R.drawable.icon2)
.setContentTitle("Low priority")
+ .setTicker("Low priority")
.build();
mNM.notify("low", 7002, n);
}
@@ -326,6 +328,7 @@
Notification n = new Notification.Builder(NotificationTestList.this, "high")
.setSmallIcon(R.drawable.icon2)
.setContentTitle("High priority")
+ .setTicker("High priority")
.build();
mNM.notify("high", 7006, n);
}