13fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowskipackage com.android.datetimepicker;
23fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski
33fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowskiimport android.app.Service;
43fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowskiimport android.content.Context;
53fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowskiimport android.database.ContentObserver;
63fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowskiimport android.net.Uri;
73fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowskiimport android.os.SystemClock;
83fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowskiimport android.os.Vibrator;
93fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowskiimport android.provider.Settings;
103fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski
113fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski/**
123fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski * A simple utility class to handle haptic feedback.
133fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski */
143fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowskipublic class HapticFeedbackController {
153fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    private static final int VIBRATE_DELAY_MS = 125;
163fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    private static final int VIBRATE_LENGTH_MS = 5;
173fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski
183fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    private static boolean checkGlobalSetting(Context context) {
193fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        return Settings.System.getInt(context.getContentResolver(),
203fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski                Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 1;
213fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    }
223fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski
233fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    private final Context mContext;
243fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    private final ContentObserver mContentObserver;
253fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski
263fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    private Vibrator mVibrator;
273fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    private boolean mIsGloballyEnabled;
283fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    private long mLastVibrate;
293fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski
303fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    public HapticFeedbackController(Context context) {
313fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        mContext = context;
323fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        mContentObserver = new ContentObserver(null) {
333fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski            @Override
343fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski            public void onChange(boolean selfChange) {
353fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski                mIsGloballyEnabled = checkGlobalSetting(mContext);
363fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski            }
373fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        };
383fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    }
393fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski
403fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    /**
413fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski     * Call to setup the controller.
423fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski     */
433fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    public void start() {
443fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        mVibrator = (Vibrator) mContext.getSystemService(Service.VIBRATOR_SERVICE);
453fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski
463fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        // Setup a listener for changes in haptic feedback settings
473fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        mIsGloballyEnabled = checkGlobalSetting(mContext);
483fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        Uri uri = Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED);
493fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        mContext.getContentResolver().registerContentObserver(uri, false, mContentObserver);
503fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    }
513fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski
523fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    /**
533fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski     * Call this when you don't need the controller anymore.
543fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski     */
553fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    public void stop() {
563fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        mVibrator = null;
573fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        mContext.getContentResolver().unregisterContentObserver(mContentObserver);
583fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    }
593fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski
603fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    /**
613fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski     * Try to vibrate. To prevent this becoming a single continuous vibration, nothing will
623fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski     * happen if we have vibrated very recently.
633fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski     */
643fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    public void tryVibrate() {
653fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        if (mVibrator != null && mIsGloballyEnabled) {
663fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski            long now = SystemClock.uptimeMillis();
673fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski            // We want to try to vibrate each individual tick discretely.
683fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski            if (now - mLastVibrate >= VIBRATE_DELAY_MS) {
693fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski                mVibrator.vibrate(VIBRATE_LENGTH_MS);
703fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski                mLastVibrate = now;
713fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski            }
723fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski        }
733fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski    }
743fc32c45f5efc4ce4b91cbcdd925d9b30f67046ePaul Sliwowski}
75