diff options
3 files changed, 42 insertions, 37 deletions
diff --git a/core/proto/android/server/vibrator/vibratormanagerservice.proto b/core/proto/android/server/vibrator/vibratormanagerservice.proto index 9151958e2b94..1d9b0db3218b 100644 --- a/core/proto/android/server/vibrator/vibratormanagerservice.proto +++ b/core/proto/android/server/vibrator/vibratormanagerservice.proto @@ -116,7 +116,7 @@ message VibrationProto { reserved 6; // prev int32 status // Also used by VibrationReported from frameworks/proto_logging/stats/atoms.proto. - // Next Tag: 26 + // Next Tag: 29 enum Status { UNKNOWN = 0; RUNNING = 1; @@ -135,7 +135,6 @@ message VibrationProto { IGNORED_ERROR_TOKEN= 14; IGNORED_APP_OPS = 15; IGNORED_BACKGROUND = 16; - IGNORED_UNKNOWN_VIBRATION = 17; IGNORED_UNSUPPORTED = 18; IGNORED_FOR_EXTERNAL = 19; IGNORED_FOR_HIGHER_IMPORTANCE = 20; @@ -146,6 +145,8 @@ message VibrationProto { IGNORED_SUPERSEDED = 25; IGNORED_FROM_VIRTUAL_DEVICE = 26; IGNORED_ON_WIRELESS_CHARGER = 27; + IGNORED_MISSING_PERMISSION = 28; + reserved 17; // prev IGNORED_UNKNOWN_VIBRATION } } diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java index ad54efcd11d3..84c37180d93c 100644 --- a/services/core/java/com/android/server/vibrator/Vibration.java +++ b/services/core/java/com/android/server/vibrator/Vibration.java @@ -75,7 +75,7 @@ abstract class Vibration { IGNORED_ERROR_TOKEN(VibrationProto.IGNORED_ERROR_TOKEN), IGNORED_APP_OPS(VibrationProto.IGNORED_APP_OPS), IGNORED_BACKGROUND(VibrationProto.IGNORED_BACKGROUND), - IGNORED_UNKNOWN_VIBRATION(VibrationProto.IGNORED_UNKNOWN_VIBRATION), + IGNORED_MISSING_PERMISSION(VibrationProto.IGNORED_MISSING_PERMISSION), IGNORED_UNSUPPORTED(VibrationProto.IGNORED_UNSUPPORTED), IGNORED_FOR_EXTERNAL(VibrationProto.IGNORED_FOR_EXTERNAL), IGNORED_FOR_HIGHER_IMPORTANCE(VibrationProto.IGNORED_FOR_HIGHER_IMPORTANCE), diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java index 8281ac1c9d28..09c24931d641 100644 --- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java +++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java @@ -436,26 +436,26 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { IBinder token, boolean fromIme) { HapticFeedbackVibrationProvider hapticVibrationProvider = getHapticVibrationProvider(); if (hapticVibrationProvider == null) { - Slog.w(TAG, "performHapticFeedback; haptic vibration provider not ready."); + Slog.e(TAG, "performHapticFeedback; haptic vibration provider not ready."); return null; } if (hapticVibrationProvider.isRestrictedHapticFeedback(constant) && !hasPermission(android.Manifest.permission.VIBRATE_SYSTEM_CONSTANTS)) { - Slog.w(TAG, "performHapticFeedback; no permission for effect " + constant); + Slog.w(TAG, "performHapticFeedback; no permission for system constant " + constant); return null; } VibrationEffect effect = hapticVibrationProvider.getVibrationForHapticFeedback(constant); if (effect == null) { - Slog.w(TAG, "performHapticFeedback; vibration absent for effect " + constant); + Slog.w(TAG, "performHapticFeedback; vibration absent for constant " + constant); return null; } - CombinedVibration combinedVibration = CombinedVibration.createParallel(effect); + CombinedVibration vib = CombinedVibration.createParallel(effect); VibrationAttributes attrs = hapticVibrationProvider.getVibrationAttributesForHapticFeedback( constant, /* bypassVibrationIntensitySetting= */ always, fromIme); + reason = "performHapticFeedback(constant=" + constant + "): " + reason; VibratorFrameworkStatsLogger.logPerformHapticsFeedbackIfKeyboard(uid, constant); - return vibrateWithoutPermissionCheck(uid, deviceId, opPkg, combinedVibration, attrs, - "performHapticFeedback: " + reason, token); + return vibrateWithoutPermissionCheck(uid, deviceId, opPkg, vib, attrs, reason, token); } /** @@ -1951,39 +1951,34 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /** Implementation of {@link IExternalVibratorService} to be triggered on external control. */ @VisibleForTesting final class ExternalVibratorService extends IExternalVibratorService.Stub { - private static final ExternalVibrationScale SCALE_MUTE = new ExternalVibrationScale(); - - static { - SCALE_MUTE.scaleLevel = ExternalVibrationScale.ScaleLevel.SCALE_MUTE; - } @Override public ExternalVibrationScale onExternalVibrationStart(ExternalVibration vib) { - if (!hasExternalControlCapability()) { - return SCALE_MUTE; - } - if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, - vib.getUid(), -1 /*owningUid*/, true /*exported*/) - != PackageManager.PERMISSION_GRANTED) { - Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid() - + " tried to play externally controlled vibration" - + " without VIBRATE permission, ignoring."); - return SCALE_MUTE; - } - // Create Vibration.Stats as close to the received request as possible, for tracking. ExternalVibrationHolder vibHolder = new ExternalVibrationHolder(vib); - VibrationAttributes attrs = fixupVibrationAttributes(vib.getVibrationAttributes(), - /* effect= */ null); - if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) { - // Force update of user settings before checking if this vibration effect should - // be ignored or scaled. - mVibrationSettings.update(); - } - + // Mute the request until we run all the checks and accept the vibration. + vibHolder.scale.scaleLevel = ExternalVibrationScale.ScaleLevel.SCALE_MUTE; boolean alreadyUnderExternalControl = false; boolean waitForCompletion = false; + synchronized (mLock) { + if (!hasExternalControlCapability()) { + endVibrationAndWriteStatsLocked(vibHolder, + new Vibration.EndInfo(Vibration.Status.IGNORED_UNSUPPORTED)); + return vibHolder.scale; + } + + if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, + vib.getUid(), -1 /*owningUid*/, true /*exported*/) + != PackageManager.PERMISSION_GRANTED) { + Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid() + + " tried to play externally controlled vibration" + + " without VIBRATE permission, ignoring."); + endVibrationAndWriteStatsLocked(vibHolder, + new Vibration.EndInfo(Vibration.Status.IGNORED_MISSING_PERMISSION)); + return vibHolder.scale; + } + Vibration.EndInfo vibrationEndInfo = shouldIgnoreVibrationLocked( vibHolder.callerInfo); @@ -2001,8 +1996,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } if (vibrationEndInfo != null) { - vibHolder.scale = SCALE_MUTE; - // Failed to start the vibration, end it and report metrics right away. endVibrationAndWriteStatsLocked(vibHolder, vibrationEndInfo); return vibHolder.scale; } @@ -2040,6 +2033,15 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { vibHolder.callerInfo), /* continueExternalControl= */ true); } + + VibrationAttributes attrs = fixupVibrationAttributes(vib.getVibrationAttributes(), + /* effect= */ null); + if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) { + // Force update of user settings before checking if this vibration effect should + // be ignored or scaled. + mVibrationSettings.update(); + } + mCurrentExternalVibration = vibHolder; vibHolder.linkToDeath(); vibHolder.scale.scaleLevel = mVibrationScaler.getScaleLevel(attrs.getUsage()); @@ -2055,8 +2057,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { endExternalVibrateLocked( new Vibration.EndInfo(Vibration.Status.IGNORED_ERROR_CANCELLING), /* continueExternalControl= */ false); + // Mute the request, vibration will be ignored. + vibHolder.scale.scaleLevel = ExternalVibrationScale.ScaleLevel.SCALE_MUTE; } - return SCALE_MUTE; + return vibHolder.scale; } } if (!alreadyUnderExternalControl) { |