1package com.android.datetimepicker;
2
3import android.app.Service;
4import android.content.Context;
5import android.database.ContentObserver;
6import android.net.Uri;
7import android.os.SystemClock;
8import android.os.Vibrator;
9import android.provider.Settings;
10
11/**
12 * A simple utility class to handle haptic feedback.
13 */
14public class HapticFeedbackController {
15    private static final int VIBRATE_DELAY_MS = 125;
16    private static final int VIBRATE_LENGTH_MS = 5;
17
18    private static boolean checkGlobalSetting(Context context) {
19        return Settings.System.getInt(context.getContentResolver(),
20                Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 1;
21    }
22
23    private final Context mContext;
24    private final ContentObserver mContentObserver;
25
26    private Vibrator mVibrator;
27    private boolean mIsGloballyEnabled;
28    private long mLastVibrate;
29
30    public HapticFeedbackController(Context context) {
31        mContext = context;
32        mContentObserver = new ContentObserver(null) {
33            @Override
34            public void onChange(boolean selfChange) {
35                mIsGloballyEnabled = checkGlobalSetting(mContext);
36            }
37        };
38    }
39
40    /**
41     * Call to setup the controller.
42     */
43    public void start() {
44        mVibrator = (Vibrator) mContext.getSystemService(Service.VIBRATOR_SERVICE);
45
46        // Setup a listener for changes in haptic feedback settings
47        mIsGloballyEnabled = checkGlobalSetting(mContext);
48        Uri uri = Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED);
49        mContext.getContentResolver().registerContentObserver(uri, false, mContentObserver);
50    }
51
52    /**
53     * Call this when you don't need the controller anymore.
54     */
55    public void stop() {
56        mVibrator = null;
57        mContext.getContentResolver().unregisterContentObserver(mContentObserver);
58    }
59
60    /**
61     * Try to vibrate. To prevent this becoming a single continuous vibration, nothing will
62     * happen if we have vibrated very recently.
63     */
64    public void tryVibrate() {
65        if (mVibrator != null && mIsGloballyEnabled) {
66            long now = SystemClock.uptimeMillis();
67            // We want to try to vibrate each individual tick discretely.
68            if (now - mLastVibrate >= VIBRATE_DELAY_MS) {
69                mVibrator.vibrate(VIBRATE_LENGTH_MS);
70                mLastVibrate = now;
71            }
72        }
73    }
74}
75