Add an optional reason field to vibrator service

Test: Run vibration test, see reason written to log and trace.
Bug: 109654229
Change-Id: I13db6968c125e7c2b2483a14faad5b6ea9b4cda6
This commit is contained in:
Alexey Kuzmin
2018-06-20 17:48:43 +01:00
parent f94dcd9818
commit e1f06b88e8
14 changed files with 74 additions and 50 deletions

View File

@@ -1191,8 +1191,8 @@ public final class InputManager {
* @hide
*/
@Override
public void vibrate(int uid, String opPkg,
VibrationEffect effect, AudioAttributes attributes) {
public void vibrate(int uid, String opPkg, VibrationEffect effect,
String reason, AudioAttributes attributes) {
long[] pattern;
int repeat;
if (effect instanceof VibrationEffect.OneShot) {

View File

@@ -23,7 +23,8 @@ interface IVibratorService
{
boolean hasVibrator();
boolean hasAmplitudeControl();
void vibrate(int uid, String opPkg, in VibrationEffect effect, int usageHint, IBinder token);
void vibrate(int uid, String opPkg, in VibrationEffect effect, int usageHint, String reason,
IBinder token);
void cancelVibrate(IBinder token);
}

View File

@@ -44,8 +44,8 @@ public class NullVibrator extends Vibrator {
}
@Override
public void vibrate(int uid, String opPkg,
VibrationEffect effect, AudioAttributes attributes) {
public void vibrate(int uid, String opPkg, VibrationEffect effect,
String reason, AudioAttributes attributes) {
}
@Override

View File

@@ -67,14 +67,14 @@ public class SystemVibrator extends Vibrator {
}
@Override
public void vibrate(int uid, String opPkg,
VibrationEffect effect, AudioAttributes attributes) {
public void vibrate(int uid, String opPkg, VibrationEffect effect,
String reason, AudioAttributes attributes) {
if (mService == null) {
Log.w(TAG, "Failed to vibrate; no vibrator service.");
return;
}
try {
mService.vibrate(uid, opPkg, effect, usageForAttributes(attributes), mToken);
mService.vibrate(uid, opPkg, effect, usageForAttributes(attributes), reason, mToken);
} catch (RemoteException e) {
Log.w(TAG, "Failed to vibrate.", e);
}

View File

@@ -248,17 +248,17 @@ public abstract class Vibrator {
@RequiresPermission(android.Manifest.permission.VIBRATE)
public void vibrate(VibrationEffect vibe, AudioAttributes attributes) {
vibrate(Process.myUid(), mPackageName, vibe, attributes);
vibrate(Process.myUid(), mPackageName, vibe, null, attributes);
}
/**
* Like {@link #vibrate(VibrationEffect, AudioAttributes)}, but allowing the caller to specify
* that the vibration is owned by someone else.
* Like {@link #vibrate(int, String, VibrationEffect, AudioAttributes)}, but allows the
* caller to specify the vibration is owned by someone else and set reason for vibration.
* @hide
*/
@RequiresPermission(android.Manifest.permission.VIBRATE)
public abstract void vibrate(int uid, String opPkg,
VibrationEffect vibe, AudioAttributes attributes);
public abstract void vibrate(int uid, String opPkg, VibrationEffect vibe,
String reason, AudioAttributes attributes);
/**
* Turn the vibrator off.

View File

@@ -66,6 +66,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Date;
public class VibratorService extends IVibratorService.Stub
@@ -158,6 +159,7 @@ public class VibratorService extends IVibratorService.Stub
public final int usageHint;
public final int uid;
public final String opPkg;
public final String reason;
// The actual effect to be played.
public VibrationEffect effect;
@@ -167,7 +169,7 @@ public class VibratorService extends IVibratorService.Stub
public VibrationEffect originalEffect;
private Vibration(IBinder token, VibrationEffect effect,
int usageHint, int uid, String opPkg) {
int usageHint, int uid, String opPkg, String reason) {
this.token = token;
this.effect = effect;
this.startTime = SystemClock.elapsedRealtime();
@@ -175,6 +177,7 @@ public class VibratorService extends IVibratorService.Stub
this.usageHint = usageHint;
this.uid = uid;
this.opPkg = opPkg;
this.reason = reason;
}
public void binderDied() {
@@ -233,7 +236,7 @@ public class VibratorService extends IVibratorService.Stub
public VibrationInfo toInfo() {
return new VibrationInfo(
startTimeDebug, effect, originalEffect, usageHint, uid, opPkg);
startTimeDebug, effect, originalEffect, usageHint, uid, opPkg, reason);
}
}
@@ -244,15 +247,18 @@ public class VibratorService extends IVibratorService.Stub
private final int mUsageHint;
private final int mUid;
private final String mOpPkg;
private final String mReason;
public VibrationInfo(long startTimeDebug, VibrationEffect effect,
VibrationEffect originalEffect, int usageHint, int uid, String opPkg) {
VibrationEffect originalEffect, int usageHint, int uid,
String opPkg, String reason) {
mStartTimeDebug = startTimeDebug;
mEffect = effect;
mOriginalEffect = originalEffect;
mUsageHint = usageHint;
mUid = uid;
mOpPkg = opPkg;
mReason = reason;
}
@Override
@@ -270,6 +276,8 @@ public class VibratorService extends IVibratorService.Stub
.append(mUid)
.append(", opPkg: ")
.append(mOpPkg)
.append(", reason: ")
.append(mReason)
.toString();
}
}
@@ -482,9 +490,9 @@ public class VibratorService extends IVibratorService.Stub
}
@Override // Binder call
public void vibrate(int uid, String opPkg, VibrationEffect effect, int usageHint,
public void vibrate(int uid, String opPkg, VibrationEffect effect, int usageHint, String reason,
IBinder token) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate");
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason = " + reason);
try {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
!= PackageManager.PERMISSION_GRANTED) {
@@ -531,10 +539,11 @@ public class VibratorService extends IVibratorService.Stub
return;
}
Vibration vib = new Vibration(token, effect, usageHint, uid, opPkg);
Vibration vib = new Vibration(token, effect, usageHint, uid, opPkg, reason);
linkVibration(vib);
long ident = Binder.clearCallingIdentity();
try {
doCancelVibrateLocked();
startVibrationLocked(vib);
addToPreviousVibrationsLocked(vib);
@@ -1001,8 +1010,8 @@ public class VibratorService extends IVibratorService.Stub
Slog.w(TAG, "Failed to play prebaked effect, no fallback");
return 0;
}
Vibration fallbackVib =
new Vibration(vib.token, effect, vib.usageHint, vib.uid, vib.opPkg);
Vibration fallbackVib = new Vibration(vib.token, effect, vib.usageHint, vib.uid,
vib.opPkg, vib.reason + " (fallback)");
final int intensity = getCurrentIntensityLocked(fallbackVib);
linkVibration(fallbackVib);
applyVibrationIntensityScalingLocked(fallbackVib, intensity);
@@ -1292,7 +1301,7 @@ public class VibratorService extends IVibratorService.Stub
VibrationEffect effect =
VibrationEffect.createOneShot(duration, VibrationEffect.DEFAULT_AMPLITUDE);
vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN,
mToken);
"Shell Command", mToken);
return 0;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);

View File

@@ -2580,12 +2580,12 @@ public class AudioService extends IAudioService.Stub
toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate;
break;
}
maybeVibrate(effect);
maybeVibrate(effect, reason);
setRingerModeInternal(ringerMode, reason);
Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show();
}
private boolean maybeVibrate(VibrationEffect effect) {
private boolean maybeVibrate(VibrationEffect effect, String reason) {
if (!mHasVibrator) {
return false;
}
@@ -2598,8 +2598,8 @@ public class AudioService extends IAudioService.Stub
if (effect == null) {
return false;
}
mVibrator.vibrate(
Binder.getCallingUid(), mContext.getOpPackageName(), effect, VIBRATION_ATTRIBUTES);
mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect,
reason, VIBRATION_ATTRIBUTES);
return true;
}

View File

@@ -5033,11 +5033,11 @@ public class NotificationManagerService extends SystemService {
Thread.sleep(waitMs);
} catch (InterruptedException e) { }
mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
effect, record.getAudioAttributes());
effect, "Notification (delayed)", record.getAudioAttributes());
}).start();
} else {
mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
effect, record.getAudioAttributes());
effect, "Notification", record.getAudioAttributes());
}
return true;
} finally{

View File

@@ -1035,7 +1035,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void onWakeUp() {
synchronized (mLock) {
if (shouldEnableWakeGestureLp()) {
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false,
"Wake Up");
wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromWakeGesture,
"android.policy:GESTURE");
}
@@ -1608,19 +1609,22 @@ public class PhoneWindowManager implements WindowManagerPolicy {
break;
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false,
"Power - Long Press - Global Actions");
showGlobalActionsInternal();
break;
case LONG_PRESS_POWER_SHUT_OFF:
case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
mPowerKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false,
"Power - Long Press - Shut Off");
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
break;
case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
mPowerKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false,
"Power - Long Press - Go To Voice Assist");
final boolean keyguardActive = mKeyguardDelegate == null
? false
: mKeyguardDelegate.isShowing();
@@ -1642,7 +1646,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
break;
case VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false,
"Power - Very Long Press - Show Global Actions");
showGlobalActionsInternal();
break;
}
@@ -1797,7 +1802,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public void run() {
mEndCallKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false,
"End Call - Long Press - Show Global Actions");
showGlobalActionsInternal();
}
};
@@ -1924,7 +1930,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return;
}
mHomeConsumed = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false,
"Home - Long Press");
switch (mLongPressOnHomeBehavior) {
case LONG_PRESS_HOME_ALL_APPS:
launchAllAppsAction();
@@ -4249,7 +4256,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
private void launchAssistLongPressAction() {
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false,
"Assist - Long Press");
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
// launch the search activity
@@ -6373,7 +6381,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
if (useHapticFeedback) {
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false,
"Virtual Key - Press");
}
if (isWakeKey) {
@@ -7531,7 +7540,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void setSafeMode(boolean safeMode) {
mSafeMode = safeMode;
if (safeMode) {
performHapticFeedbackLw(null, HapticFeedbackConstants.SAFE_MODE_ENABLED, true);
performHapticFeedbackLw(null, HapticFeedbackConstants.SAFE_MODE_ENABLED, true,
"Safe Mode Enabled");
}
}
@@ -8011,7 +8021,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) {
public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always,
String reason) {
if (!mVibrator.hasVibrator()) {
return false;
}
@@ -8035,7 +8046,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
owningUid = android.os.Process.myUid();
owningPackage = mContext.getOpPackageName();
}
mVibrator.vibrate(owningUid, owningPackage, effect, VIBRATION_ATTRIBUTES);
mVibrator.vibrate(owningUid, owningPackage, effect, reason, VIBRATION_ATTRIBUTES);
return true;
}

View File

@@ -1492,7 +1492,8 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
/**
* Call from application to perform haptic feedback on its window.
*/
public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always);
public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always,
String reason);
/**
* Called when we have started keeping the screen on because a window

View File

@@ -287,7 +287,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
try {
return mService.mPolicy.performHapticFeedbackLw(
mService.windowForClientLocked(this, window, true),
effectId, always);
effectId, always, null);
} finally {
Binder.restoreCallingIdentity(ident);
}

View File

@@ -443,7 +443,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public boolean performHapticFeedbackLw(WindowState win, int effectId,
boolean always) {
boolean always, String reason) {
return false;
}

View File

@@ -364,22 +364,23 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
private void verifyNeverVibrate() {
verify(mVibrator, never()).vibrate(anyInt(), anyString(), (VibrationEffect) anyObject(),
(AudioAttributes) anyObject());
anyString(), (AudioAttributes) anyObject());
}
private void verifyVibrate() {
verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), argThat(mVibrateOnceMatcher),
(AudioAttributes) anyObject());
anyString(), (AudioAttributes) anyObject());
}
private void verifyVibrateLooped() {
verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), argThat(mVibrateLoopMatcher),
(AudioAttributes) anyObject());
anyString(), (AudioAttributes) anyObject());
}
private void verifyDelayedVibrateLooped() {
verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(),
argThat(mVibrateLoopMatcher), (AudioAttributes) anyObject());
argThat(mVibrateLoopMatcher), anyString(),
(AudioAttributes) anyObject());
}
private void verifyStopVibrate() {
@@ -646,7 +647,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
VibrationEffect effect = VibrationEffect.createWaveform(r.getVibration(), -1);
verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(),
eq(effect), (AudioAttributes) anyObject());
eq(effect), anyString(),
(AudioAttributes) anyObject());
assertTrue(r.isInterruptive());
}
@@ -680,7 +682,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
mService.buzzBeepBlinkLocked(r);
verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(),
eq(FALLBACK_VIBRATION), (AudioAttributes) anyObject());
eq(FALLBACK_VIBRATION), anyString(), (AudioAttributes) anyObject());
verify(mRingtonePlayer, never()).playAsync
(anyObject(), anyObject(), anyBoolean(), anyObject());
assertTrue(r.isInterruptive());

View File

@@ -52,7 +52,7 @@ public class VibratorServicePermissionTest extends TestCase {
final VibrationEffect effect =
VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE);
mVibratorService.vibrate(Process.myUid(), null, effect, AudioManager.STREAM_ALARM,
new Binder());
"testVibrate", new Binder());
fail("vibrate did not throw SecurityException as expected");
} catch (SecurityException e) {
// expected