diff options
author | Santos Cordon <santoscordon@google.com> | 2013-09-27 10:38:16 -0700 |
---|---|---|
committer | Santos Cordon <santoscordon@google.com> | 2013-09-27 10:50:22 -0700 |
commit | 58c12d112cee96d9a46f373e40cb21f542919eb4 (patch) | |
tree | 89923e918a34a18339a210734b59e5db381f7a09 | |
parent | 7330bc3fd1b98ddbef8f143d3cd27db4a86929fd (diff) |
Add deadzone to end call button.
inside perimeter previously had a deadzone around the inside perimeter
of the end call button to avoid unintentional hits.
This change reintroduces the SmallerHitTargetTouchListener in order
to add back the deadzone. Also added deadzone to the secondary call hit
target since that previously also implemented the deadzone.
SmallerHitTargetTouchListener.java copied from existing apps/Phone code.
bug:10884607
Change-Id: I7445b6a2e364878aabf6fcb2f7a3e4b1dee87578
3 files changed, 119 insertions, 0 deletions
diff --git a/InCallUI/src/com/android/incallui/CallButtonFragment.java b/InCallUI/src/com/android/incallui/CallButtonFragment.java index a508312e0..209869458 100644 --- a/InCallUI/src/com/android/incallui/CallButtonFragment.java +++ b/InCallUI/src/com/android/incallui/CallButtonFragment.java @@ -103,6 +103,10 @@ public class CallButtonFragment } }); + // make the hit target smaller for the end button so that is creates a deadzone + // along the inside perimeter of the button. + mEndCallButton.setOnTouchListener(new SmallerHitTargetTouchListener()); + mMuteButton = (ToggleButton) parent.findViewById(R.id.muteButton); mMuteButton.setOnClickListener(new OnClickListener() { @Override diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java index 5ea6e918f..0d26b82cc 100644 --- a/InCallUI/src/com/android/incallui/CallCardFragment.java +++ b/InCallUI/src/com/android/incallui/CallCardFragment.java @@ -495,6 +495,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr getPresenter().secondaryPhotoClicked(); } }); + mSecondaryPhotoOverlay.setOnTouchListener(new SmallerHitTargetTouchListener()); } } diff --git a/InCallUI/src/com/android/incallui/SmallerHitTargetTouchListener.java b/InCallUI/src/com/android/incallui/SmallerHitTargetTouchListener.java new file mode 100644 index 000000000..83feaf54a --- /dev/null +++ b/InCallUI/src/com/android/incallui/SmallerHitTargetTouchListener.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.incallui; + +import android.view.MotionEvent; +import android.view.View; + +/** + * OnTouchListener used to shrink the "hit target" of some onscreen buttons. + * + * We do this for a few specific buttons which are vulnerable to + * "false touches" because either (1) they're near the edge of the + * screen and might be unintentionally touched while holding the + * device in your hand, (2) they're in the upper corners and might + * be touched by the user's ear before the prox sensor has a chance to + * kick in, or (3) they are close to other buttons. + */ +public class SmallerHitTargetTouchListener implements View.OnTouchListener { + private static final String TAG = "SmallerHitTargetTouchListener"; + + /** + * Edge dimensions where a touch does not register an action (in DIP). + */ + private static final int HIT_TARGET_EDGE_IGNORE_DP_X = 30; + private static final int HIT_TARGET_EDGE_IGNORE_DP_Y = 10; + private static final int HIT_TARGET_MIN_SIZE_DP_X = HIT_TARGET_EDGE_IGNORE_DP_X * 3; + private static final int HIT_TARGET_MIN_SIZE_DP_Y = HIT_TARGET_EDGE_IGNORE_DP_Y * 3; + + // True if the most recent DOWN event was a "hit". + boolean mDownEventHit; + + /** + * Called when a touch event is dispatched to a view. This allows listeners to + * get a chance to respond before the target view. + * + * @return True if the listener has consumed the event, false otherwise. + * (In other words, we return true when the touch is *outside* + * the "smaller hit target", which will prevent the actual + * button from handling these events.) + */ + @Override + public boolean onTouch(View v, MotionEvent event) { + // if (DBG) log("SmallerHitTargetTouchListener: " + v + ", event " + event); + + if (event.getAction() == MotionEvent.ACTION_DOWN) { + // Note that event.getX() and event.getY() are already + // translated into the View's coordinates. (In other words, + // "0,0" is a touch on the upper-left-most corner of the view.) + final int touchX = (int) event.getX(); + final int touchY = (int) event.getY(); + + final int viewWidth = v.getWidth(); + final int viewHeight = v.getHeight(); + + final float pixelDensity = v.getResources().getDisplayMetrics().density; + final int targetMinSizeX = (int) (HIT_TARGET_MIN_SIZE_DP_X * pixelDensity); + final int targetMinSizeY = (int) (HIT_TARGET_MIN_SIZE_DP_Y * pixelDensity); + + int edgeIgnoreX = (int) (HIT_TARGET_EDGE_IGNORE_DP_X * pixelDensity); + int edgeIgnoreY = (int) (HIT_TARGET_EDGE_IGNORE_DP_Y * pixelDensity); + + // If we are dealing with smaller buttons where the dead zone defined by + // HIT_TARGET_EDGE_IGNORE_DP_[X|Y] is too large. + if (viewWidth < targetMinSizeX || viewHeight < targetMinSizeY) { + // This really should not happen given our two use cases (as of this writing) + // in the call edge button and secondary calling card. However, we leave + // this is as a precautionary measure. + Log.w(TAG, "onTouch: view is too small for SmallerHitTargetTouchListener"); + edgeIgnoreX = 0; + edgeIgnoreY = 0; + } + + final int minTouchX = edgeIgnoreX; + final int maxTouchX = viewWidth - edgeIgnoreX; + final int minTouchY = edgeIgnoreY; + final int maxTouchY = viewHeight - edgeIgnoreY; + + if (touchX < minTouchX || touchX > maxTouchX || + touchY < minTouchY || touchY > maxTouchY) { + // Missed! + // if (DBG) log(" -> MISSED!"); + mDownEventHit = false; + return true; // Consume this event; don't let the button see it + } else { + // Hit! + // if (DBG) log(" -> HIT!"); + mDownEventHit = true; + return false; // Let this event through to the actual button + } + } else { + // This is a MOVE, UP or CANCEL event. + // + // We only do the "smaller hit target" check on DOWN events. + // For the subsequent MOVE/UP/CANCEL events, we let them + // through to the actual button IFF the previous DOWN event + // got through to the actual button (i.e. it was a "hit".) + return !mDownEventHit; + } + } +} |