diff options
| author | 2020-01-17 01:39:04 +0000 | |
|---|---|---|
| committer | 2020-01-17 01:39:04 +0000 | |
| commit | 301beddcdbf5d5d08b3337fca04e650a9bbd8c19 (patch) | |
| tree | ffab0ceb7e25faa1ba08b394390f45c715957c8b | |
| parent | ad189b5e606a525ad905fd212675c232fc8e3858 (diff) | |
| parent | 9adedac3b94b0ae73b452e63f7be0eb550c5683a (diff) | |
Merge "Vibrator: Have Always-On Check DND/LowPower Modes"
| -rw-r--r-- | core/java/android/os/IVibratorService.aidl | 3 | ||||
| -rw-r--r-- | core/java/android/os/SystemVibrator.java | 5 | ||||
| -rw-r--r-- | core/java/android/os/Vibrator.java | 15 | ||||
| -rw-r--r-- | services/core/java/com/android/server/VibratorService.java | 125 |
4 files changed, 85 insertions, 63 deletions
diff --git a/core/java/android/os/IVibratorService.aidl b/core/java/android/os/IVibratorService.aidl index 6b881fecad56..264ab6038ea6 100644 --- a/core/java/android/os/IVibratorService.aidl +++ b/core/java/android/os/IVibratorService.aidl @@ -24,7 +24,8 @@ interface IVibratorService { boolean hasVibrator(); boolean hasAmplitudeControl(); - boolean setAlwaysOnEffect(int id, in VibrationEffect effect, in AudioAttributes attributes); + boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, in VibrationEffect effect, + in AudioAttributes attributes); void vibrate(int uid, String opPkg, in VibrationEffect effect, in AudioAttributes attributes, String reason, IBinder token); void cancelVibrate(IBinder token); diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java index f585c75b6bb7..11a425d54621 100644 --- a/core/java/android/os/SystemVibrator.java +++ b/core/java/android/os/SystemVibrator.java @@ -70,13 +70,14 @@ public class SystemVibrator extends Vibrator { } @Override - public boolean setAlwaysOnEffect(int id, VibrationEffect effect, AudioAttributes attributes) { + public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, VibrationEffect effect, + AudioAttributes attributes) { if (mService == null) { Log.w(TAG, "Failed to set always-on effect; no vibrator service."); return false; } try { - return mService.setAlwaysOnEffect(id, effect, attributes); + return mService.setAlwaysOnEffect(uid, opPkg, alwaysOnId, effect, attributes); } catch (RemoteException e) { Log.w(TAG, "Failed to set always-on effect.", e); } diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java index ccbb0f191f6f..ae75f3d0d7e6 100644 --- a/core/java/android/os/Vibrator.java +++ b/core/java/android/os/Vibrator.java @@ -155,7 +155,7 @@ public abstract class Vibrator { /** * Configure an always-on haptics effect. * - * @param id The board-specific always-on ID to configure. + * @param alwaysOnId The board-specific always-on ID to configure. * @param effect Vibration effect to assign to always-on id. Passing null will disable it. * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or @@ -164,8 +164,17 @@ public abstract class Vibrator { * @hide */ @RequiresPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON) - public boolean setAlwaysOnEffect(int id, @Nullable VibrationEffect effect, - @Nullable AudioAttributes attributes) { + public boolean setAlwaysOnEffect(int alwaysOnId, @Nullable VibrationEffect effect, + @Nullable AudioAttributes attributes) { + return setAlwaysOnEffect(Process.myUid(), mPackageName, alwaysOnId, effect, attributes); + } + + /** + * @hide + */ + @RequiresPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON) + public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, + @Nullable VibrationEffect effect, @Nullable AudioAttributes attributes) { Log.w(TAG, "Always-on effects aren't supported"); return false; } diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index a1480e305d9e..e7179e09c4b3 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -60,7 +60,6 @@ import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.util.DebugUtils; -import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.StatsLog; @@ -162,8 +161,7 @@ public class VibratorService extends IVibratorService.Stub private int mHapticFeedbackIntensity; private int mNotificationIntensity; private int mRingIntensity; - private SparseArray<Pair<VibrationEffect, AudioAttributes>> mAlwaysOnEffects = - new SparseArray<>(); + private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>(); static native boolean vibratorExists(); static native void vibratorInit(); @@ -477,6 +475,10 @@ public class VibratorService extends IVibratorService.Stub Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY), true, mSettingObserver, UserHandle.USER_ALL); + mContext.getContentResolver().registerContentObserver( + Settings.Global.getUriFor(Settings.Global.ZEN_MODE), + true, mSettingObserver, UserHandle.USER_ALL); + mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -524,7 +526,8 @@ public class VibratorService extends IVibratorService.Stub } @Override // Binder call - public boolean setAlwaysOnEffect(int id, VibrationEffect effect, AudioAttributes attrs) { + public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, VibrationEffect effect, + AudioAttributes attrs) { if (!hasPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON)) { throw new SecurityException("Requires VIBRATE_ALWAYS_ON permission"); } @@ -534,8 +537,8 @@ public class VibratorService extends IVibratorService.Stub } if (effect == null) { synchronized (mLock) { - mAlwaysOnEffects.delete(id); - vibratorAlwaysOnDisable(id); + mAlwaysOnEffects.delete(alwaysOnId); + vibratorAlwaysOnDisable(alwaysOnId); } } else { if (!verifyVibrationEffect(effect)) { @@ -545,14 +548,11 @@ public class VibratorService extends IVibratorService.Stub Slog.e(TAG, "Only prebaked effects supported for always-on."); return false; } - if (attrs == null) { - attrs = new AudioAttributes.Builder() - .setUsage(AudioAttributes.USAGE_UNKNOWN) - .build(); - } + attrs = fixupVibrationAttributes(attrs); synchronized (mLock) { - mAlwaysOnEffects.put(id, Pair.create(effect, attrs)); - updateAlwaysOnLocked(id, effect, attrs); + Vibration vib = new Vibration(null, effect, attrs, uid, opPkg, null); + mAlwaysOnEffects.put(alwaysOnId, vib); + updateAlwaysOnLocked(alwaysOnId, vib); } } return true; @@ -592,6 +592,25 @@ public class VibratorService extends IVibratorService.Stub return true; } + private AudioAttributes fixupVibrationAttributes(AudioAttributes attrs) { + if (attrs == null) { + attrs = new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_UNKNOWN) + .build(); + } + if (shouldBypassDnd(attrs)) { + if (!(hasPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) + || hasPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + || hasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING))) { + final int flags = attrs.getAllFlags() + & ~AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY; + attrs = new AudioAttributes.Builder(attrs).replaceFlags(flags).build(); + } + } + + return attrs; + } + private static long[] getLongIntArray(Resources r, int resid) { int[] ar = r.getIntArray(resid); if (ar == null) { @@ -621,21 +640,7 @@ public class VibratorService extends IVibratorService.Stub return; } - if (attrs == null) { - attrs = new AudioAttributes.Builder() - .setUsage(AudioAttributes.USAGE_UNKNOWN) - .build(); - } - - if (shouldBypassDnd(attrs)) { - if (!(hasPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) - || hasPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - || hasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING))) { - final int flags = attrs.getAllFlags() - & ~AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY; - attrs = new AudioAttributes.Builder(attrs).replaceFlags(flags).build(); - } - } + attrs = fixupVibrationAttributes(attrs); // If our current vibration is longer than the new vibration and is the same amplitude, // then just let the current one finish. @@ -796,29 +801,8 @@ public class VibratorService extends IVibratorService.Stub private void startVibrationLocked(final Vibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationLocked"); try { - if (!isAllowedToVibrateLocked(vib)) { - return; - } - final int intensity = getCurrentIntensityLocked(vib); - if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) { - return; - } - - if (vib.isRingtone() && !shouldVibrateForRingtone()) { - if (DEBUG) { - Slog.e(TAG, "Vibrate ignored, not vibrating for ringtones"); - } - return; - } - - final int mode = getAppOpMode(vib); - if (mode != AppOpsManager.MODE_ALLOWED) { - if (mode == AppOpsManager.MODE_ERRORED) { - // We might be getting calls from within system_server, so we don't actually - // want to throw a SecurityException here. - Slog.w(TAG, "Would be an error: vibrate from uid " + vib.uid); - } + if (!shouldVibrate(vib, intensity)) { return; } applyVibrationIntensityScalingLocked(vib, intensity); @@ -985,6 +969,35 @@ public class VibratorService extends IVibratorService.Stub return mode; } + private boolean shouldVibrate(Vibration vib, int intensity) { + if (!isAllowedToVibrateLocked(vib)) { + return false; + } + + if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) { + return false; + } + + if (vib.isRingtone() && !shouldVibrateForRingtone()) { + if (DEBUG) { + Slog.e(TAG, "Vibrate ignored, not vibrating for ringtones"); + } + return false; + } + + final int mode = getAppOpMode(vib); + if (mode != AppOpsManager.MODE_ALLOWED) { + if (mode == AppOpsManager.MODE_ERRORED) { + // We might be getting calls from within system_server, so we don't actually + // want to throw a SecurityException here. + Slog.w(TAG, "Would be an error: vibrate from uid " + vib.uid); + } + return false; + } + + return true; + } + @GuardedBy("mLock") private void reportFinishVibrationLocked() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked"); @@ -1096,14 +1109,12 @@ public class VibratorService extends IVibratorService.Stub mVibrator.getDefaultRingVibrationIntensity(), UserHandle.USER_CURRENT); } - private void updateAlwaysOnLocked(int id, VibrationEffect effect, AudioAttributes attrs) { - // TODO: Check DND and LowPower settings - final Vibration vib = new Vibration(null, effect, attrs, 0, null, null); + private void updateAlwaysOnLocked(int id, Vibration vib) { final int intensity = getCurrentIntensityLocked(vib); - if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) { + if (!shouldVibrate(vib, intensity)) { vibratorAlwaysOnDisable(id); } else { - final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect; + final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.effect; final int strength = intensityToEffectStrength(intensity); vibratorAlwaysOnEnable(id, prebaked.getId(), strength); } @@ -1112,8 +1123,8 @@ public class VibratorService extends IVibratorService.Stub private void updateAlwaysOnLocked() { for (int i = 0; i < mAlwaysOnEffects.size(); i++) { int id = mAlwaysOnEffects.keyAt(i); - Pair<VibrationEffect, AudioAttributes> pair = mAlwaysOnEffects.valueAt(i); - updateAlwaysOnLocked(id, pair.first, pair.second); + Vibration vib = mAlwaysOnEffects.valueAt(i); + updateAlwaysOnLocked(id, vib); } } |