summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/VibratorService.java
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-04-13 20:38:38 -0700
committerJeff Brown <jeffbrown@google.com>2012-04-13 20:38:38 -0700
commit7f6c231a76f0bedaf9655a24707737d343244312 (patch)
tree63eaaa6255f04d34dd125da1459d2b2e70753002 /services/java/com/android/server/VibratorService.java
parent90aba7caac78b407347b930cfb6ff7d6658ac90a (diff)
downloadframeworks_base-7f6c231a76f0bedaf9655a24707737d343244312.zip
frameworks_base-7f6c231a76f0bedaf9655a24707737d343244312.tar.gz
frameworks_base-7f6c231a76f0bedaf9655a24707737d343244312.tar.bz2
Add setting to redirect vibrator to game controller.
Bug: 6334179 Change-Id: I70093e38824ea3e5cf9cf242d1d7b6d26115ed80
Diffstat (limited to 'services/java/com/android/server/VibratorService.java')
-rwxr-xr-xservices/java/com/android/server/VibratorService.java156
1 files changed, 139 insertions, 17 deletions
diff --git a/services/java/com/android/server/VibratorService.java b/services/java/com/android/server/VibratorService.java
index de25747..7561b0b 100755
--- a/services/java/com/android/server/VibratorService.java
+++ b/services/java/com/android/server/VibratorService.java
@@ -21,6 +21,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.IVibratorService;
import android.os.PowerManager;
@@ -29,18 +31,41 @@ import android.os.RemoteException;
import android.os.IBinder;
import android.os.Binder;
import android.os.SystemClock;
+import android.os.Vibrator;
import android.os.WorkSource;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
import android.util.Slog;
+import android.view.InputDevice;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.ListIterator;
-public class VibratorService extends IVibratorService.Stub {
+public class VibratorService extends IVibratorService.Stub
+ implements InputManager.InputDeviceListener {
private static final String TAG = "VibratorService";
private final LinkedList<Vibration> mVibrations;
private Vibration mCurrentVibration;
private final WorkSource mTmpWorkSource = new WorkSource();
+ private final Handler mH = new Handler();
+
+ private final Context mContext;
+ private final PowerManager.WakeLock mWakeLock;
+ private InputManager mIm;
+
+ volatile VibrateThread mThread;
+
+ // mInputDeviceVibrators lock should be acquired after mVibrations lock, if both are
+ // to be acquired
+ private final ArrayList<Vibrator> mInputDeviceVibrators = new ArrayList<Vibrator>();
+ private boolean mVibrateInputDevicesSetting; // guarded by mInputDeviceVibrators
+ private boolean mInputDeviceListenerRegistered; // guarded by mInputDeviceVibrators
+
+ native static boolean vibratorExists();
+ native static void vibratorOn(long milliseconds);
+ native static void vibratorOff();
private class Vibration implements IBinder.DeathRecipient {
private final IBinder mToken;
@@ -112,10 +137,23 @@ public class VibratorService extends IVibratorService.Stub {
context.registerReceiver(mIntentReceiver, filter);
}
+ public void systemReady() {
+ mIm = (InputManager)mContext.getSystemService(Context.INPUT_SERVICE);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES), true,
+ new ContentObserver(mH) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateVibrateInputDevicesSetting();
+ }
+ });
+ updateVibrateInputDevicesSetting();
+ }
+
public boolean hasVibrator() {
- return vibratorExists();
+ return doVibratorExists();
}
-
+
public void vibrate(long milliseconds, IBinder token) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
!= PackageManager.PERMISSION_GRANTED) {
@@ -131,6 +169,7 @@ public class VibratorService extends IVibratorService.Stub {
// longer than milliseconds.
return;
}
+
Vibration vib = new Vibration(token, milliseconds, uid);
synchronized (mVibrations) {
removeVibrationLocked(token);
@@ -240,7 +279,7 @@ public class VibratorService extends IVibratorService.Stub {
}
mThread = null;
}
- vibratorOff();
+ doVibratorOff();
mH.removeCallbacks(mVibrationRunnable);
}
@@ -257,7 +296,7 @@ public class VibratorService extends IVibratorService.Stub {
// Lock held on mVibrations
private void startVibrationLocked(final Vibration vib) {
if (vib.mTimeout != 0) {
- vibratorOn(vib.mTimeout);
+ doVibratorOn(vib.mTimeout);
mH.postDelayed(mVibrationRunnable, vib.mTimeout);
} else {
// mThread better be null here. doCancelVibrate should always be
@@ -295,6 +334,100 @@ public class VibratorService extends IVibratorService.Stub {
}
}
+ private void updateVibrateInputDevicesSetting() {
+ synchronized (mInputDeviceVibrators) {
+ mVibrateInputDevicesSetting = false;
+ try {
+ mVibrateInputDevicesSetting = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.VIBRATE_INPUT_DEVICES) > 0;
+ } catch (SettingNotFoundException snfe) {
+ }
+
+ if (mVibrateInputDevicesSetting) {
+ if (!mInputDeviceListenerRegistered) {
+ mInputDeviceListenerRegistered = true;
+ mIm.registerInputDeviceListener(this, mH);
+ }
+ } else {
+ if (mInputDeviceListenerRegistered) {
+ mInputDeviceListenerRegistered = false;
+ mIm.unregisterInputDeviceListener(this);
+ }
+ }
+
+ updateInputDeviceVibrators();
+ }
+ }
+
+ private void updateInputDeviceVibrators() {
+ synchronized (mVibrations) {
+ doCancelVibrateLocked();
+
+ synchronized (mInputDeviceVibrators) {
+ mInputDeviceVibrators.clear();
+ if (mVibrateInputDevicesSetting) {
+ int[] ids = mIm.getInputDeviceIds();
+ for (int i = 0; i < ids.length; i++) {
+ InputDevice device = mIm.getInputDevice(ids[i]);
+ Vibrator vibrator = device.getVibrator();
+ if (vibrator.hasVibrator()) {
+ mInputDeviceVibrators.add(vibrator);
+ }
+ }
+ }
+ }
+
+ startNextVibrationLocked();
+ }
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ updateInputDeviceVibrators();
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ updateInputDeviceVibrators();
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ updateInputDeviceVibrators();
+ }
+
+ private boolean doVibratorExists() {
+ synchronized (mInputDeviceVibrators) {
+ return !mInputDeviceVibrators.isEmpty() || vibratorExists();
+ }
+ }
+
+ private void doVibratorOn(long millis) {
+ synchronized (mInputDeviceVibrators) {
+ final int vibratorCount = mInputDeviceVibrators.size();
+ if (vibratorCount != 0) {
+ for (int i = 0; i < vibratorCount; i++) {
+ mInputDeviceVibrators.get(i).vibrate(millis);
+ }
+ } else {
+ vibratorOn(millis);
+ }
+ }
+ }
+
+ private void doVibratorOff() {
+ synchronized (mInputDeviceVibrators) {
+ final int vibratorCount = mInputDeviceVibrators.size();
+ if (vibratorCount != 0) {
+ for (int i = 0; i < vibratorCount; i++) {
+ mInputDeviceVibrators.get(i).cancel();
+ }
+ } else {
+ vibratorOff();
+ }
+ }
+ }
+
private class VibrateThread extends Thread {
final Vibration mVibration;
boolean mDone;
@@ -350,7 +483,7 @@ public class VibratorService extends IVibratorService.Stub {
// duration is saved for delay() at top of loop
duration = pattern[index++];
if (duration > 0) {
- VibratorService.this.vibratorOn(duration);
+ VibratorService.this.doVibratorOn(duration);
}
} else {
if (repeat < 0) {
@@ -394,15 +527,4 @@ public class VibratorService extends IVibratorService.Stub {
}
}
};
-
- private Handler mH = new Handler();
-
- private final Context mContext;
- private final PowerManager.WakeLock mWakeLock;
-
- volatile VibrateThread mThread;
-
- native static boolean vibratorExists();
- native static void vibratorOn(long milliseconds);
- native static void vibratorOff();
}