Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(379)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/PopupZoomer.java

Issue 2775013002: Add a UMA counter for tap disambiguation result. (Closed)
Patch Set: Make TappedInside the last value for possible append of subdivision of it later Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.content.browser; 5 package org.chromium.content.browser;
6 6
7 import android.annotation.SuppressLint; 7 import android.annotation.SuppressLint;
8 import android.content.Context; 8 import android.content.Context;
9 import android.content.res.Resources; 9 import android.content.res.Resources;
10 import android.graphics.Bitmap; 10 import android.graphics.Bitmap;
(...skipping 12 matching lines...) Expand all
23 import android.graphics.drawable.Drawable; 23 import android.graphics.drawable.Drawable;
24 import android.os.SystemClock; 24 import android.os.SystemClock;
25 import android.view.GestureDetector; 25 import android.view.GestureDetector;
26 import android.view.MotionEvent; 26 import android.view.MotionEvent;
27 import android.view.View; 27 import android.view.View;
28 import android.view.animation.Interpolator; 28 import android.view.animation.Interpolator;
29 import android.view.animation.OvershootInterpolator; 29 import android.view.animation.OvershootInterpolator;
30 30
31 import org.chromium.base.ApiCompatibilityUtils; 31 import org.chromium.base.ApiCompatibilityUtils;
32 import org.chromium.base.Log; 32 import org.chromium.base.Log;
33 import org.chromium.base.metrics.RecordHistogram;
33 import org.chromium.content.R; 34 import org.chromium.content.R;
34 35
35 /** 36 /**
36 * PopupZoomer is used to show the on-demand link zooming popup. It handles mani pulation of the 37 * PopupZoomer is used to show the tap disambiguation popup. When a tap lands a mbiguously
37 * canvas and touch events to display the on-demand zoom magnifier. 38 * between two tiny touch targets (usually links) on a desktop site viewed on a phone,
39 * a magnified view of the content is shown, the screen is grayed out and the us er
40 * must re-tap the magnified content in order to clarify their intent.
38 */ 41 */
39 class PopupZoomer extends View { 42 class PopupZoomer extends View {
40 private static final String TAG = "cr.PopupZoomer"; 43 private static final String TAG = "cr.PopupZoomer";
41 44
42 // The padding between the edges of the view and the popup. Note that there is a mirror 45 // The padding between the edges of the view and the popup. Note that there is a mirror
43 // constant in content/renderer/render_view_impl.cc which should be kept in sync if 46 // constant in content/renderer/render_view_impl.cc which should be kept in sync if
44 // this is changed. 47 // this is changed.
45 private static final int ZOOM_BOUNDS_MARGIN = 25; 48 private static final int ZOOM_BOUNDS_MARGIN = 25;
46 // Time it takes for the animation to finish in ms. 49 // Time it takes for the animation to finish in ms.
47 private static final long ANIMATION_DURATION = 300; 50 private static final long ANIMATION_DURATION = 300;
48 51
52 // Note that these values should be cross-checked against
53 // tools/metrics/histograms/histograms.xml. Values should only be appended,
54 // not changed or removed.
55 private static final String UMA_TAPDISAMBIGUATION = "Touchscreen.TapDisambig uation";
56 private static final int UMA_TAPDISAMBIGUATION_OTHER = 0;
57 private static final int UMA_TAPDISAMBIGUATION_BACKBUTTON = 1;
58 private static final int UMA_TAPDISAMBIGUATION_TAPPEDOUTSIDE = 2;
59 private static final int UMA_TAPDISAMBIGUATION_TAPPEDINSIDE = 3;
60 private static final int UMA_TAPDISAMBIGUATION_COUNT = 4;
61
62 private void recordHistogram(int value) {
63 RecordHistogram.recordEnumeratedHistogram(
64 UMA_TAPDISAMBIGUATION, value, UMA_TAPDISAMBIGUATION_COUNT);
65 }
66
49 /** 67 /**
50 * Interface to be implemented to listen for touch events inside the zoomed area. 68 * Interface to be implemented to listen for touch events inside the zoomed area.
51 * The MotionEvent coordinates correspond to original unzoomed view. 69 * The MotionEvent coordinates correspond to original unzoomed view.
52 */ 70 */
53 public static interface OnTapListener { 71 public static interface OnTapListener {
54 public boolean onSingleTap(View v, MotionEvent event); 72 public boolean onSingleTap(View v, MotionEvent event);
55 public boolean onLongPress(View v, MotionEvent event); 73 public boolean onLongPress(View v, MotionEvent event);
56 } 74 }
57 75
58 private OnTapListener mOnTapListener; 76 private OnTapListener mOnTapListener;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 setFocusableInTouchMode(true); 199 setFocusableInTouchMode(true);
182 200
183 GestureDetector.SimpleOnGestureListener listener = 201 GestureDetector.SimpleOnGestureListener listener =
184 new GestureDetector.SimpleOnGestureListener() { 202 new GestureDetector.SimpleOnGestureListener() {
185 @Override 203 @Override
186 public boolean onScroll(MotionEvent e1, MotionEvent e2, 204 public boolean onScroll(MotionEvent e1, MotionEvent e2,
187 float distanceX, float distanceY) { 205 float distanceX, float distanceY) {
188 if (mAnimating) return true; 206 if (mAnimating) return true;
189 207
190 if (isTouchOutsideArea(e1.getX(), e1.getY())) { 208 if (isTouchOutsideArea(e1.getX(), e1.getY())) {
191 hide(true); 209 tappedOutside();
192 } else { 210 } else {
193 scroll(distanceX, distanceY); 211 scroll(distanceX, distanceY);
194 } 212 }
195 return true; 213 return true;
196 } 214 }
197 215
198 @Override 216 @Override
199 public boolean onSingleTapUp(MotionEvent e) { 217 public boolean onSingleTapUp(MotionEvent e) {
200 return handleTapOrPress(e, false); 218 return handleTapOrPress(e, false);
201 } 219 }
202 220
203 @Override 221 @Override
204 public void onLongPress(MotionEvent e) { 222 public void onLongPress(MotionEvent e) {
205 handleTapOrPress(e, true); 223 handleTapOrPress(e, true);
206 } 224 }
207 225
208 private boolean handleTapOrPress(MotionEvent e, boolean isLo ngPress) { 226 private boolean handleTapOrPress(MotionEvent e, boolean isLo ngPress) {
209 if (mAnimating) return true; 227 if (mAnimating) return true;
210 228
211 float x = e.getX(); 229 float x = e.getX();
212 float y = e.getY(); 230 float y = e.getY();
213 if (isTouchOutsideArea(x, y)) { 231 if (isTouchOutsideArea(x, y)) {
214 // User clicked on area outside the popup. 232 tappedOutside();
215 hide(true);
216 } else if (mOnTapListener != null) { 233 } else if (mOnTapListener != null) {
217 PointF converted = convertTouchPoint(x, y); 234 PointF converted = convertTouchPoint(x, y);
218 MotionEvent event = MotionEvent.obtainNoHistory(e); 235 MotionEvent event = MotionEvent.obtainNoHistory(e);
219 event.setLocation(converted.x, converted.y); 236 event.setLocation(converted.x, converted.y);
220 if (isLongPress) { 237 if (isLongPress) {
221 mOnTapListener.onLongPress(PopupZoomer.this, eve nt); 238 mOnTapListener.onLongPress(PopupZoomer.this, eve nt);
222 } else { 239 } else {
223 mOnTapListener.onSingleTap(PopupZoomer.this, eve nt); 240 mOnTapListener.onSingleTap(PopupZoomer.this, eve nt);
224 } 241 }
225 hide(true); 242 tappedInside();
226 } 243 }
227 return true; 244 return true;
228 } 245 }
229 }; 246 };
230 mGestureDetector = new GestureDetector(context, listener); 247 mGestureDetector = new GestureDetector(context, listener);
231 } 248 }
232 249
233 /** 250 /**
234 * Sets the OnTapListener. 251 * Sets the OnTapListener.
235 */ 252 */
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 * Show the PopupZoomer view with given target bounds. 519 * Show the PopupZoomer view with given target bounds.
503 */ 520 */
504 public void show(Rect rect) { 521 public void show(Rect rect) {
505 if (mShowing || mZoomedBitmap == null) return; 522 if (mShowing || mZoomedBitmap == null) return;
506 523
507 setTargetBounds(rect); 524 setTargetBounds(rect);
508 startAnimation(true); 525 startAnimation(true);
509 } 526 }
510 527
511 /** 528 /**
512 * Hide the PopupZoomer view. 529 * Hide the PopupZoomer view because of some external event such as focus
530 * change, JS-originating scroll, etc.
513 * @param animation true if hide with animation. 531 * @param animation true if hide with animation.
514 */ 532 */
515 public void hide(boolean animation) { 533 public void hide(boolean animation) {
516 if (!mShowing) return; 534 if (!mShowing) return;
535 recordHistogram(UMA_TAPDISAMBIGUATION_OTHER);
517 536
518 if (animation) { 537 if (animation) {
519 startAnimation(false); 538 startAnimation(false);
520 } else { 539 } else {
521 hideImmediately(); 540 hideImmediately();
522 } 541 }
523 } 542 }
543 private void tappedInside() {
544 if (!mShowing) return;
545 recordHistogram(UMA_TAPDISAMBIGUATION_TAPPEDINSIDE);
546
547 startAnimation(false);
548 }
549
550 private void tappedOutside() {
551 if (!mShowing) return;
552 recordHistogram(UMA_TAPDISAMBIGUATION_TAPPEDOUTSIDE);
553
554 startAnimation(false);
555 }
556
557 public void backButtonPressed() {
558 if (!mShowing) return;
559 recordHistogram(UMA_TAPDISAMBIGUATION_BACKBUTTON);
560
561 startAnimation(false);
562 }
524 563
525 /** 564 /**
526 * Converts the coordinates to a point on the original un-zoomed view. 565 * Converts the coordinates to a point on the original un-zoomed view.
527 */ 566 */
528 private PointF convertTouchPoint(float x, float y) { 567 private PointF convertTouchPoint(float x, float y) {
529 x -= mShiftX; 568 x -= mShiftX;
530 y -= mShiftY; 569 y -= mShiftY;
531 x = mTouch.x + (x - mTouch.x - mPopupScrollX) / mScale; 570 x = mTouch.x + (x - mTouch.x - mPopupScrollX) / mScale;
532 y = mTouch.y + (y - mTouch.y - mPopupScrollY) / mScale; 571 y = mTouch.y + (y - mTouch.y - mPopupScrollY) / mScale;
533 return new PointF(x, y); 572 return new PointF(x, y);
(...skipping 21 matching lines...) Expand all
555 } 594 }
556 595
557 @Override 596 @Override
558 public float getInterpolation(float input) { 597 public float getInterpolation(float input) {
559 input = 1.0f - input; 598 input = 1.0f - input;
560 if (mInterpolator == null) return input; 599 if (mInterpolator == null) return input;
561 return mInterpolator.getInterpolation(input); 600 return mInterpolator.getInterpolation(input);
562 } 601 }
563 } 602 }
564 } 603 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698