Commit 3fc32c45 authored by Paul Sliwowski's avatar Paul Sliwowski
Browse files

Fixed issue where we vibrate even when System setting has it disabled.

Bug: 8833434
Change-Id: Ie5e8ddf348463d5932c735b4427a4c69f0da273d
(cherry picked from commit 29f325e9f0b5a84b36b0bf4d6ab38bc4867d6b5c)
parent 2994491d
package com.android.datetimepicker;
import android.app.Service;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.SystemClock;
import android.os.Vibrator;
import android.provider.Settings;
/**
* A simple utility class to handle haptic feedback.
*/
public class HapticFeedbackController {
private static final int VIBRATE_DELAY_MS = 125;
private static final int VIBRATE_LENGTH_MS = 5;
private static boolean checkGlobalSetting(Context context) {
return Settings.System.getInt(context.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 1;
}
private final Context mContext;
private final ContentObserver mContentObserver;
private Vibrator mVibrator;
private boolean mIsGloballyEnabled;
private long mLastVibrate;
public HapticFeedbackController(Context context) {
mContext = context;
mContentObserver = new ContentObserver(null) {
@Override
public void onChange(boolean selfChange) {
mIsGloballyEnabled = checkGlobalSetting(mContext);
}
};
}
/**
* Call to setup the controller.
*/
public void start() {
mVibrator = (Vibrator) mContext.getSystemService(Service.VIBRATOR_SERVICE);
// Setup a listener for changes in haptic feedback settings
mIsGloballyEnabled = checkGlobalSetting(mContext);
Uri uri = Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED);
mContext.getContentResolver().registerContentObserver(uri, false, mContentObserver);
}
/**
* Call this when you don't need the controller anymore.
*/
public void stop() {
mVibrator = null;
mContext.getContentResolver().unregisterContentObserver(mContentObserver);
}
/**
* Try to vibrate. To prevent this becoming a single continuous vibration, nothing will
* happen if we have vibrated very recently.
*/
public void tryVibrate() {
if (mVibrator != null && mIsGloballyEnabled) {
long now = SystemClock.uptimeMillis();
// We want to try to vibrate each individual tick discretely.
if (now - mLastVibrate >= VIBRATE_DELAY_MS) {
mVibrator.vibrate(VIBRATE_LENGTH_MS);
mLastVibrate = now;
}
}
}
}
......@@ -19,15 +19,9 @@ package com.android.datetimepicker.date;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.DialogFragment;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.Vibrator;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
......@@ -35,14 +29,13 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ViewAnimator;
import com.android.datetimepicker.HapticFeedbackController;
import com.android.datetimepicker.R;
import com.android.datetimepicker.Utils;
import com.android.datetimepicker.date.SimpleMonthAdapter.CalendarDay;
......@@ -105,8 +98,7 @@ public class DatePickerDialog extends DialogFragment implements
private int mMinYear = DEFAULT_START_YEAR;
private int mMaxYear = DEFAULT_END_YEAR;
private Vibrator mVibrator;
private long mLastVibrate;
private HapticFeedbackController mHapticFeedbackController;
private boolean mDelayAnimation = true;
......@@ -171,7 +163,6 @@ public class DatePickerDialog extends DialogFragment implements
final Activity activity = getActivity();
activity.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
mVibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
if (savedInstanceState != null) {
mCalendar.set(Calendar.YEAR, savedInstanceState.getInt(KEY_SELECTED_YEAR));
mCalendar.set(Calendar.MONTH, savedInstanceState.getInt(KEY_SELECTED_MONTH));
......@@ -274,9 +265,23 @@ public class DatePickerDialog extends DialogFragment implements
mYearPickerView.postSetSelectionFromTop(listPosition, listPositionOffset);
}
}
mHapticFeedbackController = new HapticFeedbackController(activity);
return view;
}
@Override
public void onResume() {
super.onResume();
mHapticFeedbackController.start();
}
@Override
public void onPause() {
super.onPause();
mHapticFeedbackController.stop();
}
private void setCurrentView(final int viewIndex) {
long millis = mCalendar.getTimeInMillis();
......@@ -453,19 +458,8 @@ public class DatePickerDialog extends DialogFragment implements
mListeners.remove(listener);
}
/**
* Try to vibrate. To prevent this becoming a single continuous vibration, nothing will
* happen if we have vibrated very recently.
*/
@Override
public void tryVibrate() {
if (mVibrator != null) {
long now = SystemClock.uptimeMillis();
// We want to try to vibrate each individual tick discretely.
if (now - mLastVibrate >= 125) {
mVibrator.vibrate(5);
mLastVibrate = now;
}
}
mHapticFeedbackController.tryVibrate();
}
}
......@@ -19,13 +19,11 @@ package com.android.datetimepicker.time;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.os.Vibrator;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.AttributeSet;
......@@ -42,8 +40,6 @@ import android.widget.FrameLayout;
import com.android.datetimepicker.R;
import java.util.HashMap;
public class RadialPickerLayout extends FrameLayout implements OnTouchListener {
private static final String TAG = "RadialPickerLayout";
......@@ -60,10 +56,9 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener {
private static final int AM = TimePickerDialog.AM;
private static final int PM = TimePickerDialog.PM;
private Vibrator mVibrator;
private long mLastVibrate;
private int mLastValueSelected;
private TimePickerDialog mController;
private OnValueSelectedListener mListener;
private boolean mTimeInitialized;
private int mCurrentHoursOfDay;
......@@ -125,8 +120,6 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener {
// Prepare mapping to snap touchable degrees to selectable degrees.
preparePrefer30sMap();
mVibrator = (Vibrator) context.getSystemService(Service.VIBRATOR_SERVICE);
mLastVibrate = 0;
mLastValueSelected = -1;
mInputEnabled = true;
......@@ -168,12 +161,14 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener {
* @param initialMinutes
* @param is24HourMode
*/
public void initialize(Context context, int initialHoursOfDay, int initialMinutes,
boolean is24HourMode) {
public void initialize(Context context, TimePickerDialog controller,
int initialHoursOfDay, int initialMinutes, boolean is24HourMode) {
if (mTimeInitialized) {
Log.e(TAG, "Time has already been initialized.");
return;
}
mController = controller;
mIs24HourMode = is24HourMode;
mHideAmPm = mAccessibilityManager.isTouchExplorationEnabled()? true : mIs24HourMode;
......@@ -582,7 +577,7 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener {
if (mIsTouchingAmOrPm == AM || mIsTouchingAmOrPm == PM) {
// If the touch is on AM or PM, set it as "touched" after the TAP_TIMEOUT
// in case the user moves their finger quickly.
tryVibrate();
mController.tryVibrate();
mDownDegrees = -1;
mHandler.postDelayed(new Runnable() {
@Override
......@@ -600,7 +595,7 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener {
if (mDownDegrees != -1) {
// If it's a legal touch, set that number as "selected" after the
// TAP_TIMEOUT in case the user moves their finger quickly.
tryVibrate();
mController.tryVibrate();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
......@@ -655,7 +650,7 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener {
if (degrees != -1) {
value = reselectSelector(degrees, isInnerCircle[0], false, true);
if (value != mLastValueSelected) {
tryVibrate();
mController.tryVibrate();
mLastValueSelected = value;
mListener.onValueSelected(getCurrentItemShowing(), value, false);
}
......@@ -714,21 +709,6 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener {
return false;
}
/**
* Try to vibrate. To prevent this becoming a single continuous vibration, nothing will
* happen if we have vibrated very recently.
*/
public void tryVibrate() {
if (mVibrator != null) {
long now = SystemClock.uptimeMillis();
// We want to try to vibrate each individual tick discretely.
if (now - mLastVibrate >= 125) {
mVibrator.vibrate(5);
mLastVibrate = now;
}
}
}
/**
* Set touch input as enabled or disabled, for use with keyboard mode.
*/
......
......@@ -34,6 +34,7 @@ import android.view.Window;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.datetimepicker.HapticFeedbackController;
import com.android.datetimepicker.R;
import com.android.datetimepicker.Utils;
import com.android.datetimepicker.time.RadialPickerLayout.OnValueSelectedListener;
......@@ -69,6 +70,8 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL
private OnTimeSetListener mCallback;
private HapticFeedbackController mHapticFeedbackController;
private TextView mDoneButton;
private TextView mHourView;
private TextView mHourSpaceView;
......@@ -199,7 +202,8 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL
mTimePicker = (RadialPickerLayout) view.findViewById(R.id.time_picker);
mTimePicker.setOnValueSelectedListener(this);
mTimePicker.setOnKeyListener(keyboardListener);
mTimePicker.initialize(getActivity(), mInitialHourOfDay, mInitialMinute, mIs24HourMode);
mTimePicker.initialize(getActivity(), this, mInitialHourOfDay, mInitialMinute,
mIs24HourMode);
int currentItemShowing = HOUR_INDEX;
if (savedInstanceState != null &&
savedInstanceState.containsKey(KEY_CURRENT_ITEM_SHOWING)) {
......@@ -208,18 +212,19 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL
setCurrentItemShowing(currentItemShowing, false, true, true);
mTimePicker.invalidate();
mHapticFeedbackController = new HapticFeedbackController(getActivity());
mHourView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setCurrentItemShowing(HOUR_INDEX, true, false, true);
mTimePicker.tryVibrate();
tryVibrate();
}
});
mMinuteView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setCurrentItemShowing(MINUTE_INDEX, true, false, true);
mTimePicker.tryVibrate();
tryVibrate();
}
});
......@@ -230,7 +235,7 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL
if (mInKbMode && isTypedTimeFullyLegal()) {
finishKbMode(false);
} else {
mTimePicker.tryVibrate();
tryVibrate();
}
if (mCallback != null) {
mCallback.onTimeSet(mTimePicker,
......@@ -257,7 +262,7 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL
mAmPmHitspace.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mTimePicker.tryVibrate();
tryVibrate();
int amOrPm = mTimePicker.getIsCurrentlyAmOrPm();
if (amOrPm == AM) {
amOrPm = PM;
......@@ -291,6 +296,22 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL
return view;
}
@Override
public void onResume() {
super.onResume();
mHapticFeedbackController.start();
}
@Override
public void onPause() {
super.onPause();
mHapticFeedbackController.stop();
}
public void tryVibrate() {
mHapticFeedbackController.tryVibrate();
}
private void updateAmPmDisplay(int amOrPm) {
if (amOrPm == AM) {
mAmPmTextView.setText(mAmText);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment