summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/input/InputManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/input/InputManagerService.java')
-rw-r--r--services/java/com/android/server/input/InputManagerService.java90
1 files changed, 90 insertions, 0 deletions
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index ce7671f..e819432 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -105,6 +105,12 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
mTempInputDevicesChangedListenersToNotify =
new ArrayList<InputDevicesChangedListenerRecord>(); // handler thread only
+ // State for vibrator tokens.
+ private Object mVibratorLock = new Object();
+ private HashMap<IBinder, VibratorToken> mVibratorTokens =
+ new HashMap<IBinder, VibratorToken>();
+ private int mNextVibratorTokenValue;
+
// State for the currently installed input filter.
final Object mInputFilterLock = new Object();
InputFilter mInputFilter; // guarded by mInputFilterLock
@@ -142,6 +148,9 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
InputChannel fromChannel, InputChannel toChannel);
private static native void nativeSetPointerSpeed(int ptr, int speed);
private static native void nativeSetShowTouches(int ptr, boolean enabled);
+ private static native void nativeVibrate(int ptr, int deviceId, long[] pattern,
+ int repeat, int token);
+ private static native void nativeCancelVibrate(int ptr, int deviceId, int token);
private static native String nativeDump(int ptr);
private static native void nativeMonitor(int ptr);
@@ -792,6 +801,65 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
return result;
}
+ // Binder call
+ @Override
+ public void vibrate(int deviceId, long[] pattern, int repeat, IBinder token) {
+ if (repeat >= pattern.length) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ VibratorToken v;
+ synchronized (mVibratorLock) {
+ v = mVibratorTokens.get(token);
+ if (v == null) {
+ v = new VibratorToken(deviceId, token, mNextVibratorTokenValue++);
+ try {
+ token.linkToDeath(v, 0);
+ } catch (RemoteException ex) {
+ // give up
+ throw new RuntimeException(ex);
+ }
+ mVibratorTokens.put(token, v);
+ }
+ }
+
+ synchronized (v) {
+ v.mVibrating = true;
+ nativeVibrate(mPtr, deviceId, pattern, repeat, v.mTokenValue);
+ }
+ }
+
+ // Binder call
+ @Override
+ public void cancelVibrate(int deviceId, IBinder token) {
+ VibratorToken v;
+ synchronized (mVibratorLock) {
+ v = mVibratorTokens.get(token);
+ if (v == null || v.mDeviceId != deviceId) {
+ return; // nothing to cancel
+ }
+ }
+
+ cancelVibrateIfNeeded(v);
+ }
+
+ void onVibratorTokenDied(VibratorToken v) {
+ synchronized (mVibratorLock) {
+ mVibratorTokens.remove(v.mToken);
+ }
+
+ cancelVibrateIfNeeded(v);
+ }
+
+ private void cancelVibrateIfNeeded(VibratorToken v) {
+ synchronized (v) {
+ if (v.mVibrating) {
+ nativeCancelVibrate(mPtr, v.mDeviceId, v.mTokenValue);
+ v.mVibrating = false;
+ }
+ }
+ }
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
@@ -1108,4 +1176,26 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
}
}
}
+
+ private final class VibratorToken implements DeathRecipient {
+ public final int mDeviceId;
+ public final IBinder mToken;
+ public final int mTokenValue;
+
+ public boolean mVibrating;
+
+ public VibratorToken(int deviceId, IBinder token, int tokenValue) {
+ mDeviceId = deviceId;
+ mToken = token;
+ mTokenValue = tokenValue;
+ }
+
+ @Override
+ public void binderDied() {
+ if (DEBUG) {
+ Slog.d(TAG, "Vibrator token died.");
+ }
+ onVibratorTokenDied(this);
+ }
+ }
}