blob: 2fed3fca24e54856b5e0f4e5bac4c87cffa2fd92 [file] [log] [blame]
Joe Onorato86f9bd22010-06-30 17:03:42 -04001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Joe Onoratofd52b182010-11-10 18:00:52 -080017package com.android.systemui.statusbar.policy;
Joe Onorato86f9bd22010-06-30 17:03:42 -040018
Jason Monk0c37ba32014-09-08 15:34:23 -040019import android.app.ActivityManager;
Joe Onorato86f9bd22010-06-30 17:03:42 -040020import android.content.Context;
Adrian Roos3bab5152015-10-16 16:51:04 -070021import android.content.res.Configuration;
Joe Onorato86f9bd22010-06-30 17:03:42 -040022import android.content.res.TypedArray;
Jason Monk8457ad82016-01-24 10:15:55 -050023import android.graphics.drawable.Drawable;
24import android.graphics.drawable.Icon;
Jeff Brownac143512012-04-05 18:57:33 -070025import android.hardware.input.InputManager;
Jason Monk0c37ba32014-09-08 15:34:23 -040026import android.media.AudioManager;
Jason Monkcbf591b2017-03-31 15:42:27 -040027import android.metrics.LogMaker;
Jason Monk8457ad82016-01-24 10:15:55 -050028import android.os.AsyncTask;
Jorim Jaggi7beadfc2014-08-15 18:42:00 +020029import android.os.Bundle;
Joe Onorato86f9bd22010-06-30 17:03:42 -040030import android.os.SystemClock;
Matthew Ng83ef2f82018-01-29 16:11:40 -080031import android.os.VibrationEffect;
Joe Onorato86f9bd22010-06-30 17:03:42 -040032import android.util.AttributeSet;
Adrian Roos3bab5152015-10-16 16:51:04 -070033import android.util.TypedValue;
Daniel Sandler804eb852010-08-31 15:43:50 -040034import android.view.HapticFeedbackConstants;
Jeff Brownbbda99d2010-07-28 15:48:59 -070035import android.view.InputDevice;
Jeff Brown6b53e8d2010-11-10 16:03:06 -080036import android.view.KeyCharacterMap;
Joe Onorato86f9bd22010-06-30 17:03:42 -040037import android.view.KeyEvent;
38import android.view.MotionEvent;
Daniel Sandleraa051d62011-03-01 16:23:57 -050039import android.view.SoundEffectConstants;
Christian Robertson42310962014-09-14 02:14:46 -040040import android.view.View;
Daniel Sandler804eb852010-08-31 15:43:50 -040041import android.view.ViewConfiguration;
John Spurlockde84f0e2013-06-12 12:41:00 -040042import android.view.accessibility.AccessibilityEvent;
Jorim Jaggi7beadfc2014-08-15 18:42:00 +020043import android.view.accessibility.AccessibilityNodeInfo;
Joe Onorato86f9bd22010-06-30 17:03:42 -040044import android.widget.ImageView;
Joe Onorato86f9bd22010-06-30 17:03:42 -040045
Jason Monkcbf591b2017-03-31 15:42:27 -040046import com.android.internal.logging.MetricsLogger;
47import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
48import com.android.systemui.Dependency;
Matthew Ng83ef2f82018-01-29 16:11:40 -080049import com.android.systemui.OverviewProxyService;
Joe Onorato86f9bd22010-06-30 17:03:42 -040050import com.android.systemui.R;
Jason Monk197f4db2016-08-26 13:28:20 -040051import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface;
Winson Chungddf62972018-02-12 11:10:04 -080052import com.android.systemui.shared.system.ActivityManagerWrapper;
Matthew Ng5c0592e2018-03-08 14:51:36 -080053import com.android.systemui.statusbar.VibratorHelper;
Joe Onorato86f9bd22010-06-30 17:03:42 -040054
Winson Chung6a38fca2018-03-28 17:57:09 -070055import static android.view.KeyEvent.KEYCODE_HOME;
Jorim Jaggi7beadfc2014-08-15 18:42:00 +020056import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
57import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
Matthew Ng9a223632018-03-30 16:47:22 -070058import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_SCRUB_TOUCH_SLOP_PX;
59import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_STEP_TOUCH_SLOP_PX;
Jorim Jaggi7beadfc2014-08-15 18:42:00 +020060
Jason Monk197f4db2016-08-26 13:28:20 -040061public class KeyButtonView extends ImageView implements ButtonInterface {
Winson Chung58bd4392018-02-08 17:53:26 -080062 private static final String TAG = KeyButtonView.class.getSimpleName();
Daniel Sandler96f48182011-08-17 09:50:35 -040063
Jason Monk6c1e6ca2017-03-30 14:12:13 -040064 private final boolean mPlaySounds;
Adrian Roos3bab5152015-10-16 16:51:04 -070065 private int mContentDescriptionRes;
Adrian Rooscde52d72014-05-26 22:21:46 +020066 private long mDownTime;
67 private int mCode;
Matthew Ng83ef2f82018-01-29 16:11:40 -080068 private int mTouchDownX;
69 private int mTouchDownY;
Matthew Ng9a223632018-03-30 16:47:22 -070070 private boolean mIsVertical;
Adrian Rooscde52d72014-05-26 22:21:46 +020071 private boolean mSupportsLongpress = true;
Jason Monk0c37ba32014-09-08 15:34:23 -040072 private AudioManager mAudioManager;
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -070073 private boolean mGestureAborted;
Jorim Jaggi053f2182015-11-24 16:07:55 -080074 private boolean mLongClicked;
Jorim Jaggi05bce152016-08-25 18:14:14 -070075 private OnClickListener mOnClickListener;
Jorim Jaggi40db0292016-06-27 17:58:03 -070076 private final KeyButtonRipple mRipple;
Matthew Ng83ef2f82018-01-29 16:11:40 -080077 private final OverviewProxyService mOverviewProxyService;
Matthew Ng5c0592e2018-03-08 14:51:36 -080078 private final VibratorHelper mVibratorHelper;
Jason Monkcbf591b2017-03-31 15:42:27 -040079 private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
Daniel Sandleraa051d62011-03-01 16:23:57 -050080
Adrian Rooscde52d72014-05-26 22:21:46 +020081 private final Runnable mCheckLongPress = new Runnable() {
Daniel Sandler804eb852010-08-31 15:43:50 -040082 public void run() {
Matthew Ng3aa0dde2018-03-13 14:20:54 -070083 if (isPressed()) {
John Spurlockcd686b52013-06-05 10:13:46 -040084 // Log.d("KeyButtonView", "longpressed: " + this);
Jason Monk815e0572014-08-12 17:26:36 -040085 if (isLongClickable()) {
Daniel Sandlera375c942011-07-29 00:33:53 -040086 // Just an old-fashioned ImageView
87 performLongClick();
Jorim Jaggi053f2182015-11-24 16:07:55 -080088 mLongClicked = true;
Jorim Jaggi7e6571f2015-06-25 11:52:48 -070089 } else if (mSupportsLongpress) {
Jason Monk815e0572014-08-12 17:26:36 -040090 sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
91 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
Jorim Jaggi053f2182015-11-24 16:07:55 -080092 mLongClicked = true;
Daniel Sandlera375c942011-07-29 00:33:53 -040093 }
Daniel Sandler804eb852010-08-31 15:43:50 -040094 }
95 }
96 };
Joe Onorato86f9bd22010-06-30 17:03:42 -040097
98 public KeyButtonView(Context context, AttributeSet attrs) {
99 this(context, attrs, 0);
100 }
101
102 public KeyButtonView(Context context, AttributeSet attrs, int defStyle) {
103 super(context, attrs);
104
105 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView,
106 defStyle, 0);
107
108 mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
John Spurlock209bede2013-07-17 12:23:27 -0400109
Daniel Sandler44a46162011-08-09 16:48:21 -0400110 mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);
Jason Monk6c1e6ca2017-03-30 14:12:13 -0400111 mPlaySounds = a.getBoolean(R.styleable.KeyButtonView_playSound, true);
Daniel Sandlera375c942011-07-29 00:33:53 -0400112
Adrian Roos3bab5152015-10-16 16:51:04 -0700113 TypedValue value = new TypedValue();
114 if (a.getValue(R.styleable.KeyButtonView_android_contentDescription, value)) {
115 mContentDescriptionRes = value.resourceId;
116 }
117
Joe Onorato86f9bd22010-06-30 17:03:42 -0400118 a.recycle();
119
Joe Onorato641bad42011-01-06 15:54:23 -0800120 setClickable(true);
Jason Monk0c37ba32014-09-08 15:34:23 -0400121 mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
Jorim Jaggi40db0292016-06-27 17:58:03 -0700122
123 mRipple = new KeyButtonRipple(context, this);
Matthew Nge2b4d792018-03-09 13:42:18 -0800124 mVibratorHelper = Dependency.get(VibratorHelper.class);
Matthew Ng83ef2f82018-01-29 16:11:40 -0800125 mOverviewProxyService = Dependency.get(OverviewProxyService.class);
Jorim Jaggi40db0292016-06-27 17:58:03 -0700126 setBackground(mRipple);
Joe Onorato86f9bd22010-06-30 17:03:42 -0400127 }
128
Jason Monk9262c942017-07-28 14:35:13 -0400129 @Override
130 public boolean isClickable() {
131 return mCode != 0 || super.isClickable();
132 }
133
Jason Monk8457ad82016-01-24 10:15:55 -0500134 public void setCode(int code) {
135 mCode = code;
136 }
137
Jorim Jaggi05bce152016-08-25 18:14:14 -0700138 @Override
139 public void setOnClickListener(OnClickListener onClickListener) {
140 super.setOnClickListener(onClickListener);
141 mOnClickListener = onClickListener;
142 }
143
Jason Monkea05f872017-01-24 19:43:36 -0500144 public void loadAsync(Icon icon) {
145 new AsyncTask<Icon, Void, Drawable>() {
Jason Monk8457ad82016-01-24 10:15:55 -0500146 @Override
Jason Monkea05f872017-01-24 19:43:36 -0500147 protected Drawable doInBackground(Icon... params) {
148 return params[0].loadDrawable(mContext);
Jason Monk8457ad82016-01-24 10:15:55 -0500149 }
150
151 @Override
152 protected void onPostExecute(Drawable drawable) {
153 setImageDrawable(drawable);
154 }
Jason Monkea05f872017-01-24 19:43:36 -0500155 }.execute(icon);
Jason Monk8457ad82016-01-24 10:15:55 -0500156 }
157
Jorim Jaggi7beadfc2014-08-15 18:42:00 +0200158 @Override
Adrian Roos3bab5152015-10-16 16:51:04 -0700159 protected void onConfigurationChanged(Configuration newConfig) {
160 super.onConfigurationChanged(newConfig);
161
162 if (mContentDescriptionRes != 0) {
163 setContentDescription(mContext.getString(mContentDescriptionRes));
164 }
165 }
166
167 @Override
Jorim Jaggi7beadfc2014-08-15 18:42:00 +0200168 public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
169 super.onInitializeAccessibilityNodeInfo(info);
170 if (mCode != 0) {
171 info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null));
Jorim Jaggi7e6571f2015-06-25 11:52:48 -0700172 if (mSupportsLongpress || isLongClickable()) {
Jorim Jaggi7beadfc2014-08-15 18:42:00 +0200173 info.addAction(
174 new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, null));
175 }
176 }
177 }
178
179 @Override
Jorim Jaggib9e290c2014-10-28 19:04:20 +0100180 protected void onWindowVisibilityChanged(int visibility) {
181 super.onWindowVisibilityChanged(visibility);
182 if (visibility != View.VISIBLE) {
183 jumpDrawablesToCurrentState();
184 }
185 }
186
187 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800188 public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
Jorim Jaggi7beadfc2014-08-15 18:42:00 +0200189 if (action == ACTION_CLICK && mCode != 0) {
190 sendEvent(KeyEvent.ACTION_DOWN, 0, SystemClock.uptimeMillis());
191 sendEvent(KeyEvent.ACTION_UP, 0);
192 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
193 playSoundEffect(SoundEffectConstants.CLICK);
194 return true;
Jorim Jaggi7e6571f2015-06-25 11:52:48 -0700195 } else if (action == ACTION_LONG_CLICK && mCode != 0) {
Jorim Jaggi7beadfc2014-08-15 18:42:00 +0200196 sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
197 sendEvent(KeyEvent.ACTION_UP, 0);
198 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
199 return true;
200 }
Alan Viverettea54956a2015-01-07 16:05:02 -0800201 return super.performAccessibilityActionInternal(action, arguments);
Jorim Jaggi7beadfc2014-08-15 18:42:00 +0200202 }
203
Joe Onorato86f9bd22010-06-30 17:03:42 -0400204 public boolean onTouchEvent(MotionEvent ev) {
Winson Chungd95a2252018-04-04 17:02:29 +0000205 final boolean showSwipeUI = mOverviewProxyService.shouldShowSwipeUpUI();
Joe Onorato86f9bd22010-06-30 17:03:42 -0400206 final int action = ev.getAction();
207 int x, y;
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700208 if (action == MotionEvent.ACTION_DOWN) {
209 mGestureAborted = false;
210 }
211 if (mGestureAborted) {
Matthew Ng3aa0dde2018-03-13 14:20:54 -0700212 setPressed(false);
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700213 return false;
214 }
Joe Onorato86f9bd22010-06-30 17:03:42 -0400215
216 switch (action) {
217 case MotionEvent.ACTION_DOWN:
218 mDownTime = SystemClock.uptimeMillis();
Jorim Jaggi053f2182015-11-24 16:07:55 -0800219 mLongClicked = false;
Matthew Ng3aa0dde2018-03-13 14:20:54 -0700220 setPressed(true);
Matthew Ng2ea93b72018-03-14 19:43:18 +0000221
222 // Use raw X and Y to detect gestures in case a parent changes the x and y values
223 mTouchDownX = (int) ev.getRawX();
224 mTouchDownY = (int) ev.getRawY();
Jeff Brown98392ef2011-09-12 18:24:59 -0700225 if (mCode != 0) {
226 sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
227 } else {
228 // Provide the same haptic feedback that the system offers for virtual keys.
229 performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
230 }
Winson Chungd95a2252018-04-04 17:02:29 +0000231 if (!showSwipeUI) {
Matthew Ng83ef2f82018-01-29 16:11:40 -0800232 playSoundEffect(SoundEffectConstants.CLICK);
233 }
Jorim Jaggi7e6571f2015-06-25 11:52:48 -0700234 removeCallbacks(mCheckLongPress);
235 postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
Joe Onorato86f9bd22010-06-30 17:03:42 -0400236 break;
237 case MotionEvent.ACTION_MOVE:
Matthew Ng2ea93b72018-03-14 19:43:18 +0000238 x = (int)ev.getRawX();
239 y = (int)ev.getRawY();
Matthew Ng9a223632018-03-30 16:47:22 -0700240
241 boolean exceededTouchSlopX = Math.abs(x - mTouchDownX) >
242 (mIsVertical ? QUICK_SCRUB_TOUCH_SLOP_PX : QUICK_STEP_TOUCH_SLOP_PX);
243 boolean exceededTouchSlopY = Math.abs(y - mTouchDownY) >
244 (mIsVertical ? QUICK_STEP_TOUCH_SLOP_PX : QUICK_SCRUB_TOUCH_SLOP_PX);
Matthew Ng83ef2f82018-01-29 16:11:40 -0800245 if (exceededTouchSlopX || exceededTouchSlopY) {
Matthew Ng2fb239c2018-02-28 11:55:52 -0800246 // When quick step is enabled, prevent animating the ripple triggered by
247 // setPressed and decide to run it on touch up
Matthew Ng3aa0dde2018-03-13 14:20:54 -0700248 setPressed(false);
Matthew Ng83ef2f82018-01-29 16:11:40 -0800249 removeCallbacks(mCheckLongPress);
250 }
Joe Onoratoabb27772010-11-15 13:30:12 -0800251 break;
252 case MotionEvent.ACTION_CANCEL:
253 setPressed(false);
Jeff Brown98392ef2011-09-12 18:24:59 -0700254 if (mCode != 0) {
255 sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
256 }
Jorim Jaggi7e6571f2015-06-25 11:52:48 -0700257 removeCallbacks(mCheckLongPress);
Joe Onorato86f9bd22010-06-30 17:03:42 -0400258 break;
259 case MotionEvent.ACTION_UP:
Matthew Ng3aa0dde2018-03-13 14:20:54 -0700260 final boolean doIt = isPressed() && !mLongClicked;
261 setPressed(false);
Matthew Ng5c0592e2018-03-08 14:51:36 -0800262 final boolean doHapticFeedback = (SystemClock.uptimeMillis() - mDownTime) > 150;
Winson Chungd95a2252018-04-04 17:02:29 +0000263 if (showSwipeUI) {
Matthew Ng83ef2f82018-01-29 16:11:40 -0800264 if (doIt) {
Matthew Ng5c0592e2018-03-08 14:51:36 -0800265 if (doHapticFeedback) {
266 mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
267 }
Matthew Ng83ef2f82018-01-29 16:11:40 -0800268 playSoundEffect(SoundEffectConstants.CLICK);
269 }
Matthew Ng5c0592e2018-03-08 14:51:36 -0800270 } else if (doHapticFeedback && !mLongClicked) {
Matthew Ng83ef2f82018-01-29 16:11:40 -0800271 // Always send a release ourselves because it doesn't seem to be sent elsewhere
272 // and it feels weird to sometimes get a release haptic and other times not.
Jason Monk058cbcc2017-07-06 15:38:19 -0400273 performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
274 }
Jeff Brown98392ef2011-09-12 18:24:59 -0700275 if (mCode != 0) {
276 if (doIt) {
Winson Chung58bd4392018-02-08 17:53:26 -0800277 // If there was a pending remote recents animation, then we need to
Winson Chung6a38fca2018-03-28 17:57:09 -0700278 // cancel the animation now before we handle the button itself. In the case
279 // where we are going home and the recents animation has already started,
280 // just cancel the recents animation, leaving the home stack in place
281 boolean isHomeKey = mCode == KEYCODE_HOME;
282 ActivityManagerWrapper.getInstance().cancelRecentsAnimation(!isHomeKey);
283
Jeff Brown98392ef2011-09-12 18:24:59 -0700284 sendEvent(KeyEvent.ACTION_UP, 0);
285 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
Patrick Dubroy5ee1a3d2011-03-02 19:11:19 -0800286 } else {
Jeff Brown98392ef2011-09-12 18:24:59 -0700287 sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
Daniel Sandleraa051d62011-03-01 16:23:57 -0500288 }
Jeff Brown98392ef2011-09-12 18:24:59 -0700289 } else {
290 // no key code, just a regular ImageView
Jorim Jaggi05bce152016-08-25 18:14:14 -0700291 if (doIt && mOnClickListener != null) {
292 mOnClickListener.onClick(this);
293 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
Jeff Brown98392ef2011-09-12 18:24:59 -0700294 }
295 }
Jorim Jaggi7e6571f2015-06-25 11:52:48 -0700296 removeCallbacks(mCheckLongPress);
Joe Onorato86f9bd22010-06-30 17:03:42 -0400297 break;
298 }
299
300 return true;
301 }
302
Jason Monk0c37ba32014-09-08 15:34:23 -0400303 public void playSoundEffect(int soundConstant) {
Jason Monk6c1e6ca2017-03-30 14:12:13 -0400304 if (!mPlaySounds) return;
Jason Monk0c37ba32014-09-08 15:34:23 -0400305 mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
Jason Monk6c1e6ca2017-03-30 14:12:13 -0400306 }
Jason Monk0c37ba32014-09-08 15:34:23 -0400307
Jason Monk815e0572014-08-12 17:26:36 -0400308 public void sendEvent(int action, int flags) {
Jeff Brownbbda99d2010-07-28 15:48:59 -0700309 sendEvent(action, flags, SystemClock.uptimeMillis());
Joe Onorato86f9bd22010-06-30 17:03:42 -0400310 }
311
Jeff Brownbbda99d2010-07-28 15:48:59 -0700312 void sendEvent(int action, int flags, long when) {
Jason Monkcbf591b2017-03-31 15:42:27 -0400313 mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_NAV_BUTTON_EVENT)
314 .setType(MetricsEvent.TYPE_ACTION)
315 .setSubtype(mCode)
316 .addTaggedData(MetricsEvent.FIELD_NAV_ACTION, action)
317 .addTaggedData(MetricsEvent.FIELD_FLAGS, flags));
Jeff Brown98392ef2011-09-12 18:24:59 -0700318 final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
319 final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
320 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
321 flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
322 InputDevice.SOURCE_KEYBOARD);
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700323 InputManager.getInstance().injectInputEvent(ev,
324 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
Joe Onorato86f9bd22010-06-30 17:03:42 -0400325 }
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700326
Annie Chin1ea49352016-05-27 15:23:35 -0700327 @Override
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700328 public void abortCurrentGesture() {
329 setPressed(false);
Matthew Ng3aa0dde2018-03-13 14:20:54 -0700330 mRipple.abortDelayedRipple();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700331 mGestureAborted = true;
332 }
Annie Chin1ea49352016-05-27 15:23:35 -0700333
334 @Override
Jorim Jaggi40db0292016-06-27 17:58:03 -0700335 public void setDarkIntensity(float darkIntensity) {
336 Drawable drawable = getDrawable();
337 if (drawable != null) {
338 ((KeyButtonDrawable) getDrawable()).setDarkIntensity(darkIntensity);
Annie Chin1ea49352016-05-27 15:23:35 -0700339
Jorim Jaggi40db0292016-06-27 17:58:03 -0700340 // Since we reuse the same drawable for multiple views, we need to invalidate the view
341 // manually.
342 invalidate();
343 }
344 mRipple.setDarkIntensity(darkIntensity);
Annie Chin1ea49352016-05-27 15:23:35 -0700345 }
Annie Chin6fc46002016-07-07 18:38:12 -0700346
347 @Override
Matthew Nga8f24262017-12-19 11:54:24 -0800348 public void setDelayTouchFeedback(boolean shouldDelay) {
Matthew Ng3aa0dde2018-03-13 14:20:54 -0700349 mRipple.setDelayTouchFeedback(shouldDelay);
Matthew Nga8f24262017-12-19 11:54:24 -0800350 }
351
352 @Override
Xiaohui Chen40e978e2016-11-29 15:10:04 -0800353 public void setVertical(boolean vertical) {
Matthew Ng9a223632018-03-30 16:47:22 -0700354 mIsVertical = vertical;
Annie Chin6fc46002016-07-07 18:38:12 -0700355 }
Joe Onorato86f9bd22010-06-30 17:03:42 -0400356}
357
358