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 | |
Ted C
2017/03/29 17:43:51
wrap at 100 chars in java
Tima Vaisburd
2017/03/29 22:56:37
Done.
| |
22 * the focused frame and sends it to ContextSelectionProvider | |
23 * which does the classification itself. | |
24 */ | |
25 @JNINamespace("content") | |
26 public class ContextSelectionClient implements SelectionClient { | |
27 @IntDef({CLASSIFY, SUGGEST_AND_CLASSIFY}) | |
28 @Retention(RetentionPolicy.SOURCE) | |
29 private @interface RequestType {} | |
30 | |
31 // Request to obtain the type (e.g. phone number, e-mail address) and the mo st | |
32 // appropriate operation for the selected text. | |
33 private static final int CLASSIFY = 0; | |
34 | |
35 // Request to obtain the type (e.g. phone number, e-mail address), the most | |
36 // appropriate operation for the selected text and a better selection bounda ries. | |
37 private static final int SUGGEST_AND_CLASSIFY = 1; | |
38 | |
39 private long mNativeContextSelectionClient; | |
40 private ContextSelectionProvider mProvider; | |
41 private ContextSelectionProvider.ResultCallback mCallback; | |
42 | |
43 /** | |
44 * Creates the ContextSelectionClient. Returns null in case ContextSelection Provider | |
45 * does not exist in the system. | |
46 */ | |
47 public static ContextSelectionClient create(ContextSelectionProvider.ResultC allback callback, | |
48 WindowAndroid windowAndroid, WebContents webContent) { | |
49 ContextSelectionProvider provider = | |
50 ContentClassFactory.get().createContextSelectionProvider(callbac k, windowAndroid); | |
51 | |
52 // ContextSelectionProvider might not exist. | |
53 if (provider == null) return null; | |
54 | |
55 return new ContextSelectionClient(provider, callback, webContent); | |
56 } | |
57 | |
58 private ContextSelectionClient(ContextSelectionProvider provider, | |
59 ContextSelectionProvider.ResultCallback callback, WebContents webCon tents) { | |
60 mProvider = provider; | |
61 mCallback = callback; | |
62 mNativeContextSelectionClient = nativeInit(webContents); | |
63 } | |
64 | |
65 @CalledByNative | |
66 private void onNativeSideDestroyed(long nativeContextSelectionClient) { | |
67 assert nativeContextSelectionClient == mNativeContextSelectionClient; | |
68 mNativeContextSelectionClient = 0; | |
69 mProvider.cancelAllRequests(); | |
70 } | |
71 | |
72 // SelectionClient implementation | |
73 @Override | |
74 public void onSelectionChanged(String selection) {} | |
75 | |
76 @Override | |
77 public void onSelectionEvent(int eventType, float posXPix, float posYPix) { | |
78 switch (eventType) { | |
79 case SelectionEventType.SELECTION_HANDLES_SHOWN: | |
80 // This event is sent when the long press is detected which caus es | |
81 // selection to appear for the first time. Temporarily hiding th e | |
82 // handles that happens e.g. during scroll does not affect this event. | |
83 requestSurroundingText(SUGGEST_AND_CLASSIFY); | |
84 break; | |
85 | |
86 case SelectionEventType.SELECTION_HANDLES_CLEARED: | |
87 // The ActionMode should be stopped when this event comes. | |
88 cancelAllRequests(); | |
89 break; | |
90 | |
91 case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED: | |
92 // This event is sent after a user stopped dragging one of the | |
93 // selection handles, i.e. stopped modifying the selection. | |
94 requestSurroundingText(CLASSIFY); | |
95 break; | |
96 | |
97 default: | |
98 break; // ignore | |
99 } | |
100 } | |
101 | |
102 @Override | |
103 public void showUnhandledTapUIIfNeeded(int x, int y) {} | |
104 | |
105 @Override | |
106 public boolean sendsSelectionPopupUpdates() { | |
107 return true; | |
108 } | |
109 | |
110 private void cancelAllRequests() { | |
111 if (mNativeContextSelectionClient != 0) { | |
112 nativeCancelAllRequests(mNativeContextSelectionClient); | |
113 } | |
114 | |
115 mProvider.cancelAllRequests(); | |
116 } | |
117 | |
118 private void requestSurroundingText(@RequestType int callbackData) { | |
119 if (mNativeContextSelectionClient == 0) { | |
120 onSurroundingTextReceived(callbackData, "", 0, 0); | |
121 return; | |
122 } | |
123 | |
124 nativeRequestSurroundingText(mNativeContextSelectionClient, callbackData ); | |
125 } | |
126 | |
127 @CalledByNative | |
128 private void onSurroundingTextReceived( | |
129 @RequestType int callbackData, String text, int start, int end) { | |
130 if (TextUtils.isEmpty(text)) { | |
131 mCallback.onClassified(new ContextSelectionProvider.Result()); | |
132 return; | |
133 } | |
134 | |
135 switch (callbackData) { | |
136 case SUGGEST_AND_CLASSIFY: | |
137 mProvider.sendSuggestAndClassifyRequest(text, start, end); | |
138 break; | |
139 | |
140 case CLASSIFY: | |
141 mProvider.sendClassifyRequest(text, start, end); | |
142 break; | |
143 | |
144 default: | |
145 assert false : "Unexpected callback data"; | |
146 break; | |
147 } | |
148 } | |
149 | |
150 private native long nativeInit(WebContents webContents); | |
151 private native void nativeRequestSurroundingText( | |
152 long nativeContextSelectionClient, int callbackData); | |
153 private native void nativeCancelAllRequests(long nativeContextSelectionClien t); | |
154 } | |
OLD | NEW |