Loading core/java/android/provider/Settings.java +15 −0 Original line number Diff line number Diff line Loading @@ -1463,6 +1463,20 @@ public final class Settings { */ public static final String VIBRATE_ON = "vibrate_on"; /** * If 1, redirects the system vibrator to all currently attached input devices * that support vibration. If there are no such input devices, then the system * vibrator is used instead. * If 0, does not register the system vibrator. * * This setting is mainly intended to provide a compatibility mechanism for * applications that only know about the system vibrator and do not use the * input device vibrator API. * * @hide */ public static final String VIBRATE_INPUT_DEVICES = "vibrate_input_devices"; /** * Ringer volume. This is used internally, changing this value will not * change the volume. See AudioManager. Loading Loading @@ -1970,6 +1984,7 @@ public final class Settings { SCREEN_BRIGHTNESS_MODE, SCREEN_AUTO_BRIGHTNESS_ADJ, VIBRATE_ON, VIBRATE_INPUT_DEVICES, MODE_RINGER, MODE_RINGER_STREAMS_AFFECTED, MUTE_STREAMS_AFFECTED, Loading services/java/com/android/server/SystemServer.java +9 −1 Original line number Diff line number Diff line Loading @@ -115,6 +115,7 @@ class ServerThread extends Thread { LightsService lights = null; PowerManagerService power = null; BatteryService battery = null; VibratorService vibrator = null; AlarmManagerService alarm = null; NetworkManagementService networkManagement = null; NetworkStatsService networkStats = null; Loading Loading @@ -203,7 +204,8 @@ class ServerThread extends Thread { ServiceManager.addService("battery", battery); Slog.i(TAG, "Vibrator Service"); ServiceManager.addService("vibrator", new VibratorService(context)); vibrator = new VibratorService(context); ServiceManager.addService("vibrator", vibrator); // only initialize the power service after we have started the // lights service, content providers and the battery service. Loading Loading @@ -645,6 +647,12 @@ class ServerThread extends Thread { // It is now time to start up the app processes... try { vibrator.systemReady(); } catch (Throwable e) { reportWtf("making Vibrator Service ready", e); } if (devicePolicy != null) { try { devicePolicy.systemReady(); Loading services/java/com/android/server/VibratorService.java +139 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -112,8 +137,21 @@ 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) { Loading @@ -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); Loading Loading @@ -240,7 +279,7 @@ public class VibratorService extends IVibratorService.Stub { } mThread = null; } vibratorOff(); doVibratorOff(); mH.removeCallbacks(mVibrationRunnable); } Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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(); } Loading
core/java/android/provider/Settings.java +15 −0 Original line number Diff line number Diff line Loading @@ -1463,6 +1463,20 @@ public final class Settings { */ public static final String VIBRATE_ON = "vibrate_on"; /** * If 1, redirects the system vibrator to all currently attached input devices * that support vibration. If there are no such input devices, then the system * vibrator is used instead. * If 0, does not register the system vibrator. * * This setting is mainly intended to provide a compatibility mechanism for * applications that only know about the system vibrator and do not use the * input device vibrator API. * * @hide */ public static final String VIBRATE_INPUT_DEVICES = "vibrate_input_devices"; /** * Ringer volume. This is used internally, changing this value will not * change the volume. See AudioManager. Loading Loading @@ -1970,6 +1984,7 @@ public final class Settings { SCREEN_BRIGHTNESS_MODE, SCREEN_AUTO_BRIGHTNESS_ADJ, VIBRATE_ON, VIBRATE_INPUT_DEVICES, MODE_RINGER, MODE_RINGER_STREAMS_AFFECTED, MUTE_STREAMS_AFFECTED, Loading
services/java/com/android/server/SystemServer.java +9 −1 Original line number Diff line number Diff line Loading @@ -115,6 +115,7 @@ class ServerThread extends Thread { LightsService lights = null; PowerManagerService power = null; BatteryService battery = null; VibratorService vibrator = null; AlarmManagerService alarm = null; NetworkManagementService networkManagement = null; NetworkStatsService networkStats = null; Loading Loading @@ -203,7 +204,8 @@ class ServerThread extends Thread { ServiceManager.addService("battery", battery); Slog.i(TAG, "Vibrator Service"); ServiceManager.addService("vibrator", new VibratorService(context)); vibrator = new VibratorService(context); ServiceManager.addService("vibrator", vibrator); // only initialize the power service after we have started the // lights service, content providers and the battery service. Loading Loading @@ -645,6 +647,12 @@ class ServerThread extends Thread { // It is now time to start up the app processes... try { vibrator.systemReady(); } catch (Throwable e) { reportWtf("making Vibrator Service ready", e); } if (devicePolicy != null) { try { devicePolicy.systemReady(); Loading
services/java/com/android/server/VibratorService.java +139 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -112,8 +137,21 @@ 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) { Loading @@ -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); Loading Loading @@ -240,7 +279,7 @@ public class VibratorService extends IVibratorService.Stub { } mThread = null; } vibratorOff(); doVibratorOff(); mH.removeCallbacks(mVibrationRunnable); } Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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(); }