diff options
5 files changed, 62 insertions, 9 deletions
diff --git a/core/proto/android/server/vibrator/vibratormanagerservice.proto b/core/proto/android/server/vibrator/vibratormanagerservice.proto index 5a4d6dbdc085..12804d43b04e 100644 --- a/core/proto/android/server/vibrator/vibratormanagerservice.proto +++ b/core/proto/android/server/vibrator/vibratormanagerservice.proto @@ -147,6 +147,7 @@ message VibrationProto { IGNORED_ON_WIRELESS_CHARGER = 27; IGNORED_MISSING_PERMISSION = 28; CANCELLED_BY_APP_OPS = 29; + CANCELLED_BY_FOREGROUND_USER = 30; reserved 17; // prev IGNORED_UNKNOWN_VIBRATION } } diff --git a/services/core/java/com/android/server/pm/BackgroundUserSoundNotifier.java b/services/core/java/com/android/server/pm/BackgroundUserSoundNotifier.java index 58b14b14fdef..15e758cf6ffd 100644 --- a/services/core/java/com/android/server/pm/BackgroundUserSoundNotifier.java +++ b/services/core/java/com/android/server/pm/BackgroundUserSoundNotifier.java @@ -37,7 +37,6 @@ import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; -import android.os.Vibrator; import android.util.Log; import com.android.internal.R; @@ -47,9 +46,9 @@ public class BackgroundUserSoundNotifier { private static final boolean DEBUG = false; private static final String LOG_TAG = BackgroundUserSoundNotifier.class.getSimpleName(); - public static final String BUSN_CHANNEL_ID = "bg_user_sound_channel"; - public static final String BUSN_CHANNEL_NAME = "BackgroundUserSound"; - private static final String ACTION_MUTE_SOUND = "com.android.server.ACTION_MUTE_BG_USER"; + private static final String BUSN_CHANNEL_ID = "bg_user_sound_channel"; + private static final String BUSN_CHANNEL_NAME = "BackgroundUserSound"; + public static final String ACTION_MUTE_SOUND = "com.android.server.ACTION_MUTE_BG_USER"; private static final String EXTRA_NOTIFICATION_ID = "com.android.server.EXTRA_CLIENT_UID"; private static final String EXTRA_CURRENT_USER_ID = "com.android.server.EXTRA_CURRENT_USER_ID"; private static final String ACTION_SWITCH_USER = "com.android.server.ACTION_SWITCH_TO_USER"; @@ -144,6 +143,7 @@ public class BackgroundUserSoundNotifier { -1) + " current user id " + intent.getIntExtra( EXTRA_CURRENT_USER_ID, -1)); } + mUserWithNotification = -1; mNotificationManager.cancelAsUser(LOG_TAG, notificationId, UserHandle.of(intent.getIntExtra(EXTRA_CURRENT_USER_ID, -1))); if (ACTION_MUTE_SOUND.equals(intent.getAction())) { @@ -159,10 +159,6 @@ public class BackgroundUserSoundNotifier { } } } - Vibrator vibrator = mSystemUserContext.getSystemService(Vibrator.class); - if (vibrator != null && vibrator.isVibrating()) { - vibrator.cancel(); - } } else if (ACTION_SWITCH_USER.equals(intent.getAction())) { service.switchUser(intent.getIntExtra(Intent.EXTRA_USER_ID, -1)); } diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java index 6537228583ec..5fab13bdc402 100644 --- a/services/core/java/com/android/server/vibrator/Vibration.java +++ b/services/core/java/com/android/server/vibrator/Vibration.java @@ -67,6 +67,7 @@ abstract class Vibration { CANCELLED_BY_SCREEN_OFF(VibrationProto.CANCELLED_BY_SCREEN_OFF), CANCELLED_BY_SETTINGS_UPDATE(VibrationProto.CANCELLED_BY_SETTINGS_UPDATE), CANCELLED_BY_USER(VibrationProto.CANCELLED_BY_USER), + CANCELLED_BY_FOREGROUND_USER(VibrationProto.CANCELLED_BY_FOREGROUND_USER), CANCELLED_BY_UNKNOWN_REASON(VibrationProto.CANCELLED_BY_UNKNOWN_REASON), CANCELLED_SUPERSEDED(VibrationProto.CANCELLED_SUPERSEDED), CANCELLED_BY_APP_OPS(VibrationProto.CANCELLED_BY_APP_OPS), diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java index 4437a2ddf3a7..bff175fec1dd 100644 --- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java +++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java @@ -16,6 +16,7 @@ package com.android.server.vibrator; +import static android.os.VibrationAttributes.USAGE_CLASS_ALARM; import static android.os.VibrationEffect.VibrationParameter.targetAmplitude; import static android.os.VibrationEffect.VibrationParameter.targetFrequency; @@ -73,6 +74,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.server.SystemService; +import com.android.server.pm.BackgroundUserSoundNotifier; import libcore.util.NativeAllocationRegistry; @@ -173,7 +175,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @Nullable private HapticFeedbackVibrationProvider mHapticFeedbackVibrationProvider; - private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { + @VisibleForTesting + BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { @@ -190,6 +193,19 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /* immediate= */ false); } } + } else if (android.multiuser.Flags.addUiForSoundsFromBackgroundUsers() + && intent.getAction().equals(BackgroundUserSoundNotifier.ACTION_MUTE_SOUND)) { + synchronized (mLock) { + if (shouldCancelOnFgUserRequest(mNextVibration)) { + clearNextVibrationLocked(new Vibration.EndInfo( + Vibration.Status.CANCELLED_BY_FOREGROUND_USER)); + } + if (shouldCancelOnFgUserRequest(mCurrentVibration)) { + mCurrentVibration.notifyCancelled(new Vibration.EndInfo( + Vibration.Status.CANCELLED_BY_FOREGROUND_USER), + /* immediate= */ false); + } + } } } }; @@ -299,6 +315,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); + if (android.multiuser.Flags.addUiForSoundsFromBackgroundUsers()) { + filter.addAction(BackgroundUserSoundNotifier.ACTION_MUTE_SOUND); + } context.registerReceiver(mIntentReceiver, filter, Context.RECEIVER_NOT_EXPORTED); injector.addService(EXTERNAL_VIBRATOR_SERVICE, new ExternalVibratorService()); @@ -1423,6 +1442,14 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } @GuardedBy("mLock") + private boolean shouldCancelOnFgUserRequest(@Nullable VibrationStepConductor conductor) { + if (conductor == null) { + return false; + } + return conductor.getVibration().callerInfo.attrs.getUsageClass() == USAGE_CLASS_ALARM; + } + + @GuardedBy("mLock") private void onAllVibratorsLocked(Consumer<VibratorController> consumer) { for (int i = 0; i < mVibrators.size(); i++) { consumer.accept(mVibrators.valueAt(i)); diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java index ef944dbba3ca..5ae5677b9b53 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java @@ -47,6 +47,7 @@ import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.ContextWrapper; +import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.res.Resources; @@ -103,6 +104,7 @@ import com.android.internal.util.test.FakeSettingsProvider; import com.android.internal.util.test.FakeSettingsProviderRule; import com.android.server.LocalServices; import com.android.server.companion.virtual.VirtualDeviceManagerInternal; +import com.android.server.pm.BackgroundUserSoundNotifier; import org.junit.After; import org.junit.Before; @@ -809,6 +811,32 @@ public class VibratorManagerServiceTest { } @Test + @RequiresFlagsEnabled(android.multiuser.Flags.FLAG_ADD_UI_FOR_SOUNDS_FROM_BACKGROUND_USERS) + public void vibrate_thenFgUserRequestsMute_getsCancelled() throws Throwable { + mockVibrators(1); + VibratorManagerService service = createSystemReadyService(); + + var vib = vibrate(service, + VibrationEffect.createWaveform(new long[]{100, 100, 100, 100}, 0), ALARM_ATTRS); + + assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); + + + service.mIntentReceiver.onReceive(mContextSpy, new Intent( + BackgroundUserSoundNotifier.ACTION_MUTE_SOUND)); + + assertTrue(waitUntil(s -> vib.hasEnded(), service, TEST_TIMEOUT_MILLIS)); + + var statsInfoCaptor = ArgumentCaptor.forClass(VibrationStats.StatsInfo.class); + verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS)) + .writeVibrationReportedAsync(statsInfoCaptor.capture()); + + VibrationStats.StatsInfo touchMetrics = statsInfoCaptor.getAllValues().get(0); + assertEquals(Vibration.Status.CANCELLED_BY_FOREGROUND_USER.getProtoEnumValue(), + touchMetrics.status); + } + + @Test public void vibrate_withVibrationAttributes_usesCorrespondingAudioUsageInAppOpsManager() { VibratorManagerService service = createSystemReadyService(); |