diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index a7606339b7d96..40d09d4b42287 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -7153,15 +7153,7 @@ public class NotificationManagerService extends SystemService { // so need to check the notification still valide for vibrate. synchronized (mNotificationLock) { if (mNotificationsByKey.get(record.getKey()) != null) { - // Vibrator checks the appops for the op package, not the caller, - // so we need to add the bypass dnd flag to be heard. it's ok to - // always add this flag here because we've already checked that we can - // bypass dnd - AudioAttributes.Builder aab = - new AudioAttributes.Builder(record.getAudioAttributes()) - .setFlags(FLAG_BYPASS_INTERRUPTION_POLICY); - mVibrator.vibrate(record.getSbn().getUid(), record.getSbn().getOpPkg(), - effect, "Notification (delayed)", aab.build()); + vibrate(record, effect, true); } else { Slog.e(TAG, "No vibration for canceled notification : " + record.getKey()); @@ -7169,8 +7161,7 @@ public class NotificationManagerService extends SystemService { } }).start(); } else { - mVibrator.vibrate(record.getSbn().getUid(), record.getSbn().getPackageName(), - effect, "Notification", record.getAudioAttributes()); + vibrate(record, effect, false); } return true; } finally{ @@ -7178,6 +7169,16 @@ public class NotificationManagerService extends SystemService { } } + private void vibrate(NotificationRecord record, VibrationEffect effect, boolean delayed) { + // We need to vibrate as "android" so we can breakthrough DND. VibratorManagerService + // doesn't have a concept of vibrating on an app's behalf, so add the app information + // to the reason so we can still debug from bugreports + String reason = "Notification (" + record.getSbn().getOpPkg() + " " + + record.getSbn().getUid() + ") " + (delayed ? "(Delayed)" : ""); + mVibrator.vibrate(Process.SYSTEM_UID, PackageManagerService.PLATFORM_PACKAGE_NAME, + effect, reason, record.getAudioAttributes()); + } + private boolean isNotificationForCurrentUser(NotificationRecord record) { final int currentUser; final long token = Binder.clearCallingIdentity(); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java index 2e0f1992478d0..cfda07c552084 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -57,6 +57,7 @@ import android.media.AudioAttributes; import android.media.AudioManager; import android.net.Uri; import android.os.Handler; +import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.os.VibrationEffect; @@ -77,10 +78,12 @@ import com.android.internal.logging.InstanceIdSequenceFake; import com.android.internal.util.IntPair; import com.android.server.UiServiceTestCase; import com.android.server.lights.LogicalLight; +import com.android.server.pm.PackageManagerService; 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; @@ -407,12 +410,17 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { } private void verifyVibrate() { + ArgumentCaptor captor = ArgumentCaptor.forClass(AudioAttributes.class); verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), argThat(mVibrateOnceMatcher), - anyString(), any()); + anyString(), captor.capture()); + assertEquals(0, (captor.getValue().getAllFlags() + & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)); } private void verifyVibrate(int times) { - verify(mVibrator, times(times)).vibrate(anyInt(), anyString(), any(), anyString(), any()); + verify(mVibrator, times(times)).vibrate(eq(Process.SYSTEM_UID), + eq(PackageManagerService.PLATFORM_PACKAGE_NAME), any(), anyString(), + any(AudioAttributes.class)); } private void verifyVibrateLooped() {