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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java

Issue 2703473002: [TTS] Extract tapped text before showing UI. (Closed)
Patch Set: Reworked icing notification, lots of cleanup, and a rebase. 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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.chrome.browser.contextualsearch; 5 package org.chromium.chrome.browser.contextualsearch;
6 6
7 import android.os.Handler;
8 import android.text.TextUtils; 7 import android.text.TextUtils;
9 8
10 import org.chromium.base.VisibleForTesting; 9 import org.chromium.base.VisibleForTesting;
11 import org.chromium.chrome.browser.ChromeActivity; 10 import org.chromium.chrome.browser.ChromeActivity;
12 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; 11 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel;
13 import org.chromium.chrome.browser.contextualsearch.ContextualSearchBlacklist.Bl acklistReason; 12 import org.chromium.chrome.browser.contextualsearch.ContextualSearchBlacklist.Bl acklistReason;
14 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; 13 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
15 import org.chromium.chrome.browser.tab.Tab; 14 import org.chromium.chrome.browser.tab.Tab;
16 import org.chromium.content.browser.ContentViewCore; 15 import org.chromium.content.browser.ContentViewCore;
17 import org.chromium.content_public.browser.GestureStateListener; 16 import org.chromium.content_public.browser.GestureStateListener;
(...skipping 10 matching lines...) Expand all
28 27
29 /** 28 /**
30 * The type of selection made by the user. 29 * The type of selection made by the user.
31 */ 30 */
32 public enum SelectionType { 31 public enum SelectionType {
33 UNDETERMINED, 32 UNDETERMINED,
34 TAP, 33 TAP,
35 LONG_PRESS 34 LONG_PRESS
36 } 35 }
37 36
38 // The number of milliseconds to wait for a selection change after a tap bef ore considering
39 // the tap invalid. This can't be too small or the subsequent taps may not have established
40 // a new selection in time. This is because selectWordAroundCaret doesn't a lways select.
41 // TODO(donnd): Fix in Blink, crbug.com/435778.
42 private static final int INVALID_IF_NO_SELECTION_CHANGE_AFTER_TAP_MS = 50;
43
44 // The default navigation-detection-delay in milliseconds.
45 private static final int TAP_NAVIGATION_DETECTION_DELAY = 16;
46
47 private static final String CONTAINS_WORD_PATTERN = "(\\w|\\p{L}|\\p{N})+"; 37 private static final String CONTAINS_WORD_PATTERN = "(\\w|\\p{L}|\\p{N})+";
48 // A URL is: 38 // A URL is:
49 // 1: scheme:// 39 // 1: scheme://
50 // 1+: any word char, _ or - 40 // 1+: any word char, _ or -
51 // 1+: . followed by 1+ of any word char, _ or - 41 // 1+: . followed by 1+ of any word char, _ or -
52 // 0-1: 0+ of any word char or .,@?^=%&:/~#- followed by any word char or @?^-%&/~+#- 42 // 0-1: 0+ of any word char or .,@?^=%&:/~#- followed by any word char or @?^-%&/~+#-
53 // TODO(twellington): expand accepted schemes? 43 // TODO(twellington): expand accepted schemes?
54 private static final Pattern URL_PATTERN = Pattern.compile("((http|https|fil e|ftp|ssh)://)" 44 private static final Pattern URL_PATTERN = Pattern.compile("((http|https|fil e|ftp|ssh)://)"
55 + "([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+# -])?"); 45 + "([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+# -])?");
56 46
57 // Max selection length must be limited or the entire request URL can go pas t the 2K limit. 47 // Max selection length must be limited or the entire request URL can go pas t the 2K limit.
58 private static final int MAX_SELECTION_LENGTH = 100; 48 private static final int MAX_SELECTION_LENGTH = 100;
59 49
60 private final ChromeActivity mActivity; 50 private final ChromeActivity mActivity;
61 private final ContextualSearchSelectionHandler mHandler; 51 private final ContextualSearchSelectionHandler mHandler;
62 private final Runnable mHandleInvalidTapRunnable;
63 private final Handler mRunnableHandler;
64 private final float mPxToDp; 52 private final float mPxToDp;
65 private final Pattern mContainsWordPattern; 53 private final Pattern mContainsWordPattern;
66 54
67 private String mSelectedText; 55 private String mSelectedText;
68 private SelectionType mSelectionType; 56 private SelectionType mSelectionType;
69 private boolean mWasTapGestureDetected; 57 private boolean mWasTapGestureDetected;
70 // Reflects whether the last tap was valid and whether we still have a tap-b ased selection. 58 // Reflects whether the last tap was valid and whether we still have a tap-b ased selection.
71 private ContextualSearchTapState mLastTapState; 59 private ContextualSearchTapState mLastTapState;
72 private TapSuppressionHeuristics mTapHeuristics;
73 private boolean mIsWaitingForInvalidTapDetection; 60 private boolean mIsWaitingForInvalidTapDetection;
74 private boolean mShouldHandleSelectionModification; 61 private boolean mShouldHandleSelectionModification;
75 private boolean mDidExpandSelection; 62 private boolean mDidExpandSelection;
76 63
77 // Position of the selection. 64 // Position of the selection.
78 private float mX; 65 private float mX;
79 private float mY; 66 private float mY;
80 67
81 // The time of the most last scroll activity, or 0 if none. 68 // The time of the most last scroll activity, or 0 if none.
82 private long mLastScrollTimeNs; 69 private long mLastScrollTimeNs;
83 70
71 // When the last tap gesture happened.
72 private long mTapTimeNanoseconds;
73
84 // Tracks whether a Context Menu has just been shown and the UX has been dis missed. 74 // Tracks whether a Context Menu has just been shown and the UX has been dis missed.
85 // The selection may be unreliable until the next reset. See crbug.com/6284 36. 75 // The selection may be unreliable until the next reset. See crbug.com/6284 36.
86 private boolean mIsContextMenuShown; 76 private boolean mIsContextMenuShown;
87 77
88 private class ContextualSearchGestureStateListener extends GestureStateListe ner { 78 private class ContextualSearchGestureStateListener extends GestureStateListe ner {
89 @Override 79 @Override
90 public void onScrollStarted(int scrollOffsetY, int scrollExtentY) { 80 public void onScrollStarted(int scrollOffsetY, int scrollExtentY) {
91 mHandler.handleScroll(); 81 mHandler.handleScroll();
92 } 82 }
93 83
94 @Override 84 @Override
95 public void onScrollEnded(int scrollOffsetY, int scrollExtentY) { 85 public void onScrollEnded(int scrollOffsetY, int scrollExtentY) {
96 mLastScrollTimeNs = System.nanoTime(); 86 mLastScrollTimeNs = System.nanoTime();
97 } 87 }
98 88
99 @Override 89 @Override
100 public void onScrollUpdateGestureConsumed() { 90 public void onScrollUpdateGestureConsumed() {
101 // The onScrollEnded notification is unreliable, so mark time during scroll updates too. 91 // The onScrollEnded notification is unreliable, so mark time during scroll updates too.
102 // See crbug.com/600863. 92 // See crbug.com/600863.
103 mLastScrollTimeNs = System.nanoTime(); 93 mLastScrollTimeNs = System.nanoTime();
104 } 94 }
105 95
106 // TODO(donnd): Remove this once we get notification of the selection ch anging 96 // TODO(donnd): Remove this once we get notification of the selection ch anging
107 // after a tap-select gets a subsequent tap nearby. Currently there's n o 97 // after a tap-select gets a subsequent tap nearby. Currently there's n o
108 // notification in this case. 98 // notification in this case.
109 // See crbug.com/444114. 99 // See crbug.com/444114.
110 @Override 100 @Override
111 public void onSingleTap(boolean consumed) { 101 public void onSingleTap(boolean consumed) {
112 // We may be notified that a tap has happened even when the system c onsumed the event. 102 // TODO(donnd): remove completely!
113 // This is being used to support tapping on an existing selection to show the selection
114 // handles. We should process this tap unless we have already shown the selection
115 // handles (have a long-press selection) and the tap was consumed.
116 if (!(consumed && mSelectionType == SelectionType.LONG_PRESS)) {
117 scheduleInvalidTapNotification();
118 }
119 } 103 }
120 } 104 }
121 105
122 /** 106 /**
123 * Constructs a new Selection controller for the given activity. Callbacks will be issued 107 * Constructs a new Selection controller for the given activity. Callbacks will be issued
124 * through the given selection handler. 108 * through the given selection handler.
125 * @param activity The {@link ChromeActivity} to control. 109 * @param activity The {@link ChromeActivity} to control.
126 * @param handler The handler for callbacks. 110 * @param handler The handler for callbacks.
127 */ 111 */
128 public ContextualSearchSelectionController(ChromeActivity activity, 112 public ContextualSearchSelectionController(ChromeActivity activity,
129 ContextualSearchSelectionHandler handler) { 113 ContextualSearchSelectionHandler handler) {
130 mActivity = activity; 114 mActivity = activity;
131 mHandler = handler; 115 mHandler = handler;
132 mPxToDp = 1.f / mActivity.getResources().getDisplayMetrics().density; 116 mPxToDp = 1.f / mActivity.getResources().getDisplayMetrics().density;
133
134 mRunnableHandler = new Handler();
135 mHandleInvalidTapRunnable = new Runnable() {
136 @Override
137 public void run() {
138 onInvalidTapDetectionTimeout();
139 }
140 };
141
142 mContainsWordPattern = Pattern.compile(CONTAINS_WORD_PATTERN); 117 mContainsWordPattern = Pattern.compile(CONTAINS_WORD_PATTERN);
143 } 118 }
144 119
145 /** 120 /**
146 * Notifies that the base page has started loading a page. 121 * Notifies that the base page has started loading a page.
147 */ 122 */
148 void onBasePageLoadStarted() { 123 void onBasePageLoadStarted() {
149 resetAllStates(); 124 resetAllStates();
150 } 125 }
151 126
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 * @param selection The selection portion of the context. 214 * @param selection The selection portion of the context.
240 */ 215 */
241 void handleSelectionChanged(String selection) { 216 void handleSelectionChanged(String selection) {
242 if (mDidExpandSelection) { 217 if (mDidExpandSelection) {
243 mSelectedText = selection; 218 mSelectedText = selection;
244 mDidExpandSelection = false; 219 mDidExpandSelection = false;
245 return; 220 return;
246 } 221 }
247 222
248 if (selection == null || selection.isEmpty()) { 223 if (selection == null || selection.isEmpty()) {
249 scheduleInvalidTapNotification(); 224 mHandler.handleSelectionCleared();
250 // When the user taps on the page it will place the caret in that po sition, which 225 // When the user taps on the page it will place the caret in that po sition, which
251 // will trigger a onSelectionChanged event with an empty string. 226 // will trigger a onSelectionChanged event with an empty string.
252 if (mSelectionType == SelectionType.TAP) { 227 if (mSelectionType == SelectionType.TAP) {
253 // Since we mostly ignore a selection that's empty, we only need to partially reset. 228 // Since we mostly ignore a selection that's empty, we only need to partially reset.
254 resetSelectionStates(); 229 resetSelectionStates();
255 return; 230 return;
256 } 231 }
257 } 232 }
258 if (!selection.isEmpty()) {
259 unscheduleInvalidTapNotification();
260 }
261 233
262 mSelectedText = selection; 234 mSelectedText = selection;
263 235
264 if (mWasTapGestureDetected) { 236 if (mWasTapGestureDetected) {
265 mSelectionType = SelectionType.TAP; 237 assert mSelectionType == SelectionType.TAP;
266 handleSelection(selection, mSelectionType); 238 handleSelection(selection, mSelectionType);
267 mWasTapGestureDetected = false; 239 mWasTapGestureDetected = false;
268 } else { 240 } else {
269 boolean isValidSelection = validateSelectionSuppression(selection); 241 boolean isValidSelection = validateSelectionSuppression(selection);
270 mHandler.handleSelectionModification(selection, isValidSelection, mX , mY); 242 mHandler.handleSelectionModification(selection, isValidSelection, mX , mY);
271 } 243 }
272 } 244 }
273 245
274 /** 246 /**
275 * Handles a notification that a selection event took place. 247 * Handles a notification that a selection event took place.
276 * @param eventType The type of event that took place. 248 * @param eventType The type of event that took place.
277 * @param posXPix The x coordinate of the selection start handle. 249 * @param posXPix The x coordinate of the selection start handle.
278 * @param posYPix The y coordinate of the selection start handle. 250 * @param posYPix The y coordinate of the selection start handle.
279 */ 251 */
280 void handleSelectionEvent(int eventType, float posXPix, float posYPix) { 252 void handleSelectionEvent(int eventType, float posXPix, float posYPix) {
281 boolean shouldHandleSelection = false; 253 boolean shouldHandleSelection = false;
282 switch (eventType) { 254 switch (eventType) {
283 case SelectionEventType.SELECTION_HANDLES_SHOWN: 255 case SelectionEventType.SELECTION_HANDLES_SHOWN:
284 if (!mIsContextMenuShown) { 256 if (!mIsContextMenuShown) {
285 mWasTapGestureDetected = false; 257 mWasTapGestureDetected = false;
286 mSelectionType = SelectionType.LONG_PRESS; 258 mSelectionType = SelectionType.LONG_PRESS;
287 shouldHandleSelection = true; 259 shouldHandleSelection = true;
288 // Since we're showing pins, we don't care if the previous t ap was invalid 260 // Since we're showing pins, we don't care if the previous t ap was invalid
289 // anymore. 261 // anymore.
Theresa 2017/04/25 17:30:42 Can we remove this comment too?
Donn Denman 2017/04/25 22:35:38 Done.
290 unscheduleInvalidTapNotification();
291 } 262 }
292 break; 263 break;
293 case SelectionEventType.SELECTION_HANDLES_CLEARED: 264 case SelectionEventType.SELECTION_HANDLES_CLEARED:
294 mHandler.handleSelectionDismissal(); 265 mHandler.handleSelectionDismissal();
295 resetAllStates(); 266 resetAllStates();
296 break; 267 break;
297 case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED: 268 case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED:
298 shouldHandleSelection = mShouldHandleSelectionModification; 269 shouldHandleSelection = mShouldHandleSelectionModification;
299 break; 270 break;
300 default: 271 default:
(...skipping 26 matching lines...) Expand all
327 } 298 }
328 299
329 /** 300 /**
330 * Resets all internal state of this class, including the tap state. 301 * Resets all internal state of this class, including the tap state.
331 */ 302 */
332 private void resetAllStates() { 303 private void resetAllStates() {
333 resetSelectionStates(); 304 resetSelectionStates();
334 mLastTapState = null; 305 mLastTapState = null;
335 mLastScrollTimeNs = 0; 306 mLastScrollTimeNs = 0;
336 mIsContextMenuShown = false; 307 mIsContextMenuShown = false;
308 mTapTimeNanoseconds = 0;
309 mDidExpandSelection = false;
337 } 310 }
338 311
339 /** 312 /**
340 * Resets all of the internal state of this class that handles the selection . 313 * Resets all of the internal state of this class that handles the selection .
341 */ 314 */
342 private void resetSelectionStates() { 315 private void resetSelectionStates() {
343 mSelectionType = SelectionType.UNDETERMINED; 316 mSelectionType = SelectionType.UNDETERMINED;
344 mSelectedText = null; 317 mSelectedText = null;
345 318
346 mWasTapGestureDetected = false; 319 mWasTapGestureDetected = false;
(...skipping 10 matching lines...) Expand all
357 /** 330 /**
358 * Handles an unhandled tap gesture. 331 * Handles an unhandled tap gesture.
359 * @param x The x coordinate in px. 332 * @param x The x coordinate in px.
360 * @param y The y coordinate in px. 333 * @param y The y coordinate in px.
361 */ 334 */
362 void handleShowUnhandledTapUIIfNeeded(int x, int y) { 335 void handleShowUnhandledTapUIIfNeeded(int x, int y) {
363 mWasTapGestureDetected = false; 336 mWasTapGestureDetected = false;
364 // TODO(donnd): refactor to avoid needing a new handler API method as su ggested by Pedro. 337 // TODO(donnd): refactor to avoid needing a new handler API method as su ggested by Pedro.
365 if (mSelectionType != SelectionType.LONG_PRESS) { 338 if (mSelectionType != SelectionType.LONG_PRESS) {
366 mWasTapGestureDetected = true; 339 mWasTapGestureDetected = true;
367 long tapTimeNanoseconds = System.nanoTime(); 340 mSelectionType = SelectionType.TAP;
368 // TODO(donnd): add a policy method to get adjusted tap count. 341 mTapTimeNanoseconds = System.nanoTime();
369 ChromePreferenceManager prefs = ChromePreferenceManager.getInstance( );
370 int adjustedTapsSinceOpen = prefs.getContextualSearchTapCount()
371 - prefs.getContextualSearchTapQuickAnswerCount();
372 // Explicitly destroy the old heuristics so native code can dispose data.
373 if (mTapHeuristics != null) mTapHeuristics.destroy();
374 mTapHeuristics =
375 new TapSuppressionHeuristics(this, mLastTapState, x, y, adju stedTapsSinceOpen);
376 // TODO(donnd): Move to be called when the panel closes to work with states that change.
377 mTapHeuristics.logConditionState();
378 // Tell the manager what it needs in order to log metrics on whether the tap would have
379 // been suppressed if each of the heuristics were satisfied.
380 mHandler.handleMetricsForWouldSuppressTap(mTapHeuristics);
381 mX = x; 342 mX = x;
382 mY = y; 343 mY = y;
383 boolean shouldSuppressTap = mTapHeuristics.shouldSuppressTap(); 344 mHandler.handleValidTap();
384 if (shouldSuppressTap) {
385 mHandler.handleSuppressedTap();
386 } else {
387 // TODO(donnd): Find a better way to determine that a navigation will be triggered
388 // by the tap, or merge with other time-consuming actions like g athering surrounding
389 // text or detecting page mutations.
390 new Handler().postDelayed(new Runnable() {
391 @Override
392 public void run() {
393 mHandler.handleValidTap();
394 }
395 }, TAP_NAVIGATION_DETECTION_DELAY);
396 }
397 // Remember the tap state for subsequent tap evaluation.
398 mLastTapState =
399 new ContextualSearchTapState(x, y, tapTimeNanoseconds, shoul dSuppressTap);
400 } else { 345 } else {
401 // Long press; reset last tap state. 346 // Long press; reset last tap state.
402 mLastTapState = null; 347 mLastTapState = null;
403 mHandler.handleInvalidTap(); 348 mHandler.handleInvalidTap();
404 } 349 }
405 } 350 }
406 351
407 /** 352 /**
353 * Handles Tap suppression by making a callback to either the handler's hand leSuppressedTap or
Theresa 2017/04/25 17:30:42 nit: #handleSuppressedTap() or #handleNonSuppresse
Donn Denman 2017/04/25 22:35:37 Done.
354 * handleNonSuppressedTap after a possible delay.
355 * This should be called when the context is fully build (by gathering surro unding text
Theresa 2017/04/25 17:30:42 nit: s/build/built
Donn Denman 2017/04/25 22:35:38 Done.
356 * if needed, etc) but before showing any UX.
357 */
358 void handleShouldSuppressTap() {
359 int x = (int) mX;
360 int y = (int) mY;
361
362 // TODO(donnd): add a policy method to get adjusted tap count.
363 ChromePreferenceManager prefs = ChromePreferenceManager.getInstance();
364 int adjustedTapsSinceOpen = prefs.getContextualSearchTapCount()
365 - prefs.getContextualSearchTapQuickAnswerCount();
366 TapSuppressionHeuristics tapHeuristics =
367 new TapSuppressionHeuristics(this, mLastTapState, x, y, adjusted TapsSinceOpen);
368 // TODO(donnd): Move to be called when the panel closes to work with sta tes that change.
369 tapHeuristics.logConditionState();
370 // Tell the manager what it needs in order to log metrics on whether the tap would have
371 // been suppressed if each of the heuristics were satisfied.
372 mHandler.handleMetricsForWouldSuppressTap(tapHeuristics);
373
374 boolean shouldSuppressTap = tapHeuristics.shouldSuppressTap();
375 if (mTapTimeNanoseconds != 0) {
376 // Remember the tap state for subsequent tap evaluation.
377 mLastTapState =
378 new ContextualSearchTapState(x, y, mTapTimeNanoseconds, shou ldSuppressTap);
379 } else {
380 mLastTapState = null;
381 }
382
383 if (shouldSuppressTap) {
384 mHandler.handleSuppressedTap();
385 } else {
386 mHandler.handleNonSuppressedTap();
387 }
388 }
389
390 /**
408 * Gets the base page ContentViewCore. 391 * Gets the base page ContentViewCore.
409 * Deprecated, use getBaseWebContents instead. 392 * Deprecated, use getBaseWebContents instead.
410 * @return The Base Page's {@link ContentViewCore}, or {@code null} if there is no current tab. 393 * @return The Base Page's {@link ContentViewCore}, or {@code null} if there is no current tab.
411 */ 394 */
412 @Deprecated 395 @Deprecated
413 ContentViewCore getBaseContentView() { 396 ContentViewCore getBaseContentView() {
414 Tab currentTab = mActivity.getActivityTab(); 397 Tab currentTab = mActivity.getActivityTab();
415 return currentTab != null ? currentTab.getContentViewCore() : null; 398 return currentTab != null ? currentTab.getContentViewCore() : null;
416 } 399 }
417 400
(...skipping 12 matching lines...) Expand all
430 } 413 }
431 414
432 /** 415 /**
433 * Expands the current selection by the specified amounts. 416 * Expands the current selection by the specified amounts.
434 * @param selectionStartAdjust The start offset adjustment of the selection to use to highlight 417 * @param selectionStartAdjust The start offset adjustment of the selection to use to highlight
435 * the search term. 418 * the search term.
436 * @param selectionEndAdjust The end offset adjustment of the selection to u se to highlight 419 * @param selectionEndAdjust The end offset adjustment of the selection to u se to highlight
437 * the search term. 420 * the search term.
438 */ 421 */
439 void adjustSelection(int selectionStartAdjust, int selectionEndAdjust) { 422 void adjustSelection(int selectionStartAdjust, int selectionEndAdjust) {
440 // TODO(donnd): add code to verify that the selection is still valid bef ore changing it.
441 // crbug.com/508354
Theresa 2017/04/25 17:30:42 Why is this TODO no longer neeeded?
Donn Denman 2017/04/25 22:35:37 Added a check in handleSearchTermResolutionRespons
442
443 if (selectionStartAdjust == 0 && selectionEndAdjust == 0) return; 423 if (selectionStartAdjust == 0 && selectionEndAdjust == 0) return;
444 WebContents basePageWebContents = getBaseWebContents(); 424 WebContents basePageWebContents = getBaseWebContents();
445 if (basePageWebContents != null) { 425 if (basePageWebContents != null) {
446 mDidExpandSelection = true; 426 mDidExpandSelection = true;
447 basePageWebContents.adjustSelectionByCharacterOffset( 427 basePageWebContents.adjustSelectionByCharacterOffset(
448 selectionStartAdjust, selectionEndAdjust); 428 selectionStartAdjust, selectionEndAdjust);
449 } 429 }
450 } 430 }
451 431
452 // ========================================================================= =================== 432 // ========================================================================= ===================
453 // Invalid Tap Notification
454 // ========================================================================= ===================
455
456 /**
457 * Schedules a notification to check if the tap was invalid.
458 * When we call selectWordAroundCaret it selects nothing in cases where the tap was invalid.
459 * We have no way to know other than scheduling a notification to check late r.
460 * This allows us to hide the bar when there's no selection.
461 */
462 private void scheduleInvalidTapNotification() {
463 // TODO(donnd): Fix selectWordAroundCaret to we can tell if it selects, instead
464 // of using a timer here! See crbug.com/435778.
465 mRunnableHandler.postDelayed(mHandleInvalidTapRunnable,
466 INVALID_IF_NO_SELECTION_CHANGE_AFTER_TAP_MS);
467 }
468
469 /**
470 * Un-schedules all pending notifications to check if a tap was invalid.
471 */
472 private void unscheduleInvalidTapNotification() {
473 mRunnableHandler.removeCallbacks(mHandleInvalidTapRunnable);
474 mIsWaitingForInvalidTapDetection = true;
475 }
476
477 /**
478 * Notify's the system that tap gesture has been completed.
479 */
480 private void onInvalidTapDetectionTimeout() {
481 mHandler.handleInvalidTap();
482 mIsWaitingForInvalidTapDetection = false;
483 }
484
485 // ========================================================================= ===================
486 // Selection Modification 433 // Selection Modification
487 // ========================================================================= =================== 434 // ========================================================================= ===================
488 435
489 /** 436 /**
490 * This method checks whether the selection modification should be handled. This method 437 * This method checks whether the selection modification should be handled. This method
491 * is needed to allow modifying selections that are occluded by the Panel. 438 * is needed to allow modifying selections that are occluded by the Panel.
492 * See crbug.com/489461. 439 * See crbug.com/489461.
493 * 440 *
494 * @param reason The reason the panel is closing. 441 * @param reason The reason the panel is closing.
495 * @return Whether the selection modification should be handled. 442 * @return Whether the selection modification should be handled.
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 // Starts are inclusive and ends are non-inclusive for both GSAContext & matcher. 568 // Starts are inclusive and ends are non-inclusive for both GSAContext & matcher.
622 while (matcher.find()) { 569 while (matcher.find()) {
623 if (startOffset >= matcher.start() && endOffset <= matcher.end()) { 570 if (startOffset >= matcher.start() && endOffset <= matcher.end()) {
624 return true; 571 return true;
625 } 572 }
626 } 573 }
627 574
628 return false; 575 return false;
629 } 576 }
630 } 577 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698