Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.content.browser; | |
| 6 | |
| 7 import android.support.annotation.IntDef; | |
| 8 import android.text.TextUtils; | |
| 9 | |
| 10 import org.chromium.base.annotations.CalledByNative; | |
| 11 import org.chromium.base.annotations.JNINamespace; | |
| 12 import org.chromium.content_public.browser.WebContents; | |
| 13 import org.chromium.ui.base.WindowAndroid; | |
| 14 import org.chromium.ui.touch_selection.SelectionEventType; | |
| 15 | |
| 16 import java.lang.annotation.Retention; | |
| 17 import java.lang.annotation.RetentionPolicy; | |
| 18 | |
| 19 /** | |
| 20 * A class that controls the classification of the textual selection. | |
| 21 * It requests the selection together with its surrounding text from the focused frame and sends it | |
| 22 * to ContextSelectionProvider which does the classification itself. | |
| 23 */ | |
| 24 @JNINamespace("content") | |
| 25 public class ContextSelectionClient implements SelectionClient { | |
| 26 @IntDef({CLASSIFY, SUGGEST_AND_CLASSIFY}) | |
| 27 @Retention(RetentionPolicy.SOURCE) | |
| 28 private @interface RequestType {} | |
| 29 | |
| 30 // Request to obtain the type (e.g. phone number, e-mail address) and the mo st | |
| 31 // appropriate operation for the selected text. | |
| 32 private static final int CLASSIFY = 0; | |
| 33 | |
| 34 // Request to obtain the type (e.g. phone number, e-mail address), the most | |
| 35 // appropriate operation for the selected text and a better selection bounda ries. | |
| 36 private static final int SUGGEST_AND_CLASSIFY = 1; | |
| 37 | |
| 38 // The maximal number of characters on the left and on the right from the cu rrent selection. | |
| 39 // Used for surrounding text request. | |
| 40 private static final int NUM_EXTRA_CHARS = 100; | |
| 41 | |
| 42 private long mNativeContextSelectionClient; | |
| 43 private ContextSelectionProvider mProvider; | |
| 44 private ContextSelectionProvider.ResultCallback mCallback; | |
| 45 | |
| 46 /** | |
| 47 * Creates the ContextSelectionClient. Returns null in case ContextSelection Provider | |
| 48 * does not exist in the system. | |
| 49 */ | |
| 50 public static ContextSelectionClient create(ContextSelectionProvider.ResultC allback callback, | |
| 51 WindowAndroid windowAndroid, WebContents webContent) { | |
|
Ted C
2017/03/30 00:12:40
s/webContent/webContents
Tima Vaisburd
2017/03/30 01:03:13
Done.
| |
| 52 ContextSelectionProvider provider = | |
| 53 ContentClassFactory.get().createContextSelectionProvider(callbac k, windowAndroid); | |
|
Ted C
2017/03/30 00:12:39
FYI, the window android associated with a WebConte
Tima Vaisburd
2017/03/30 01:03:13
Yes, thank you. I will need to do either that or j
| |
| 54 | |
| 55 // ContextSelectionProvider might not exist. | |
| 56 if (provider == null) return null; | |
| 57 | |
| 58 return new ContextSelectionClient(provider, callback, webContent); | |
| 59 } | |
| 60 | |
| 61 private ContextSelectionClient(ContextSelectionProvider provider, | |
| 62 ContextSelectionProvider.ResultCallback callback, WebContents webCon tents) { | |
| 63 mProvider = provider; | |
| 64 mCallback = callback; | |
| 65 mNativeContextSelectionClient = nativeInit(webContents); | |
| 66 } | |
| 67 | |
| 68 @CalledByNative | |
| 69 private void onNativeSideDestroyed(long nativeContextSelectionClient) { | |
| 70 assert nativeContextSelectionClient == mNativeContextSelectionClient; | |
| 71 mNativeContextSelectionClient = 0; | |
| 72 mProvider.cancelAllRequests(); | |
| 73 } | |
| 74 | |
| 75 // SelectionClient implementation | |
| 76 @Override | |
| 77 public void onSelectionChanged(String selection) {} | |
| 78 | |
| 79 @Override | |
| 80 public void onSelectionEvent(int eventType, float posXPix, float posYPix) { | |
| 81 switch (eventType) { | |
| 82 case SelectionEventType.SELECTION_HANDLES_SHOWN: | |
| 83 // This event is sent when the long press is detected which caus es | |
| 84 // selection to appear for the first time. Temporarily hiding th e | |
| 85 // handles that happens e.g. during scroll does not affect this event. | |
| 86 requestSurroundingText(SUGGEST_AND_CLASSIFY); | |
| 87 break; | |
| 88 | |
| 89 case SelectionEventType.SELECTION_HANDLES_CLEARED: | |
| 90 // The ActionMode should be stopped when this event comes. | |
| 91 cancelAllRequests(); | |
| 92 break; | |
| 93 | |
| 94 case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED: | |
| 95 // This event is sent after a user stopped dragging one of the | |
| 96 // selection handles, i.e. stopped modifying the selection. | |
| 97 requestSurroundingText(CLASSIFY); | |
| 98 break; | |
| 99 | |
| 100 default: | |
| 101 break; // ignore | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 @Override | |
| 106 public void showUnhandledTapUIIfNeeded(int x, int y) {} | |
| 107 | |
| 108 @Override | |
| 109 public boolean sendsSelectionPopupUpdates() { | |
| 110 return true; | |
| 111 } | |
| 112 | |
| 113 private void cancelAllRequests() { | |
| 114 if (mNativeContextSelectionClient != 0) { | |
| 115 nativeCancelAllRequests(mNativeContextSelectionClient); | |
| 116 } | |
| 117 | |
| 118 mProvider.cancelAllRequests(); | |
| 119 } | |
| 120 | |
| 121 private void requestSurroundingText(@RequestType int callbackData) { | |
| 122 if (mNativeContextSelectionClient == 0) { | |
| 123 onSurroundingTextReceived(callbackData, "", 0, 0); | |
| 124 return; | |
| 125 } | |
| 126 | |
| 127 nativeRequestSurroundingText(mNativeContextSelectionClient, NUM_EXTRA_CH ARS, callbackData); | |
| 128 } | |
| 129 | |
| 130 @CalledByNative | |
| 131 private void onSurroundingTextReceived( | |
| 132 @RequestType int callbackData, String text, int start, int end) { | |
| 133 if (TextUtils.isEmpty(text)) { | |
| 134 mCallback.onClassified(new ContextSelectionProvider.Result()); | |
| 135 return; | |
| 136 } | |
| 137 | |
| 138 switch (callbackData) { | |
| 139 case SUGGEST_AND_CLASSIFY: | |
| 140 mProvider.sendSuggestAndClassifyRequest(text, start, end); | |
| 141 break; | |
| 142 | |
| 143 case CLASSIFY: | |
| 144 mProvider.sendClassifyRequest(text, start, end); | |
| 145 break; | |
| 146 | |
| 147 default: | |
| 148 assert false : "Unexpected callback data"; | |
| 149 break; | |
| 150 } | |
| 151 } | |
| 152 | |
| 153 private native long nativeInit(WebContents webContents); | |
| 154 private native void nativeRequestSurroundingText( | |
| 155 long nativeContextSelectionClient, int numExtraCharacters, int callb ackData); | |
| 156 private native void nativeCancelAllRequests(long nativeContextSelectionClien t); | |
| 157 } | |
| OLD | NEW |