Index: content/public/android/java/src/org/chromium/content/browser/ContextSelectionClient.java |
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContextSelectionClient.java b/content/public/android/java/src/org/chromium/content/browser/ContextSelectionClient.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f18ad66ddcc1c3f09bcdfec555333461fb8600c9 |
--- /dev/null |
+++ b/content/public/android/java/src/org/chromium/content/browser/ContextSelectionClient.java |
@@ -0,0 +1,168 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.content.browser; |
+ |
+import android.support.annotation.IntDef; |
+import android.text.TextUtils; |
+ |
+import org.chromium.base.annotations.CalledByNative; |
+import org.chromium.base.annotations.JNINamespace; |
+import org.chromium.content_public.browser.WebContents; |
+import org.chromium.ui.base.WindowAndroid; |
+import org.chromium.ui.touch_selection.SelectionEventType; |
+ |
+import java.lang.annotation.Retention; |
+import java.lang.annotation.RetentionPolicy; |
+ |
+/** |
+ * A class that controls the classification of the textual selection. |
+ * It requests the selection together with its surrounding text from |
+ * the focused frame and sends it to ContextSelectionProvider |
+ * which does the classification itself. |
+ */ |
+@JNINamespace("content") |
+public class ContextSelectionClient implements SelectionClient { |
+ private static final String TAG = "ContextSelClient"; // 20 char limit |
boliu
2017/03/20 20:27:26
not used
Tima Vaisburd
2017/03/21 02:07:02
Removed.
|
+ |
+ @IntDef({CLASSIFY, SUGGEST_AND_CLASSIFY}) |
+ @Retention(RetentionPolicy.SOURCE) |
+ private @interface RequestType {} |
+ |
+ private static final int CLASSIFY = 0; |
+ private static final int SUGGEST_AND_CLASSIFY = 1; |
+ |
+ // The callback that would receive the information from ContextSelectionProvider. |
+ private class ProviderCallback implements ContextSelectionProvider.ResultCallback { |
+ @Override |
+ public void onClassified(ContextSelectionProvider.Result result) { |
+ mOuterCallback.onClassified(result); |
+ } |
+ }; |
+ |
+ private long mNativeContextSelectionClient; |
+ private ContextSelectionProvider mProvider; |
+ private ProviderCallback mProviderCallback; |
+ private ContextSelectionProvider.ResultCallback mOuterCallback; |
+ |
+ /** |
+ * Creates the ContextSelectionClient. Returns null in case ContextSelectionProvider |
+ * does not exist in the system. |
+ */ |
+ public static ContextSelectionClient create(ContextSelectionProvider.ResultCallback callback, |
+ WindowAndroid windowAndroid, WebContents webContent) { |
+ ContextSelectionClient client = new ContextSelectionClient(callback); |
+ if (!client.initialize(windowAndroid, webContent)) client = null; |
+ return client; |
+ } |
+ |
+ private ContextSelectionClient(ContextSelectionProvider.ResultCallback callback) { |
+ mOuterCallback = callback; |
+ } |
+ |
+ private boolean initialize(WindowAndroid windowAndroid, WebContents webContents) { |
+ // We make a chain of callbacks: this class receiive result from provider through |
+ // mProviderCallback and passes the info to embedder with mOuterCallback. |
+ mProviderCallback = new ProviderCallback(); |
+ mProvider = ContentClassFactory.get().createContextSelectionProvider( |
+ mProviderCallback, windowAndroid); |
+ |
+ // ContextSelectionProvider might not exist. |
+ if (mProvider == null) { |
+ return false; |
+ } |
+ |
+ mNativeContextSelectionClient = nativeInit(webContents); |
+ return true; |
+ } |
+ |
+ @CalledByNative |
+ private void onNativeSideDestroyed(long nativeContextSelectionClient) { |
+ assert nativeContextSelectionClient == mNativeContextSelectionClient; |
+ mNativeContextSelectionClient = 0; |
+ } |
+ |
+ // SelectionClient implementation |
+ @Override |
+ public void onSelectionChanged(String selection) {} |
+ |
+ @Override |
+ public void onSelectionEvent(int eventType, float posXPix, float posYPix) { |
+ switch (eventType) { |
+ case SelectionEventType.SELECTION_HANDLES_SHOWN: |
+ // This event is sent when the long press is detected which causes |
+ // selection to appear for the first time. Temporarily hiding the |
+ // handles that happens e.g. during scroll does not affect this event. |
+ requestSurroundingText(SUGGEST_AND_CLASSIFY); |
+ break; |
+ |
+ case SelectionEventType.SELECTION_HANDLES_CLEARED: |
+ // The ActionMode should be stopped when this event comes. |
+ cancelAllRequests(); |
+ break; |
+ |
+ case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED: |
+ // This event is sent after a user stopped dragging one of the |
+ // selection handles, i.e. stopped modifying the selection. |
+ requestSurroundingText(CLASSIFY); |
+ break; |
+ |
+ default: |
+ break; // ignore |
+ } |
+ } |
+ |
+ @Override |
+ public void showUnhandledTapUIIfNeeded(int x, int y) {} |
+ |
+ @Override |
+ public boolean sendsMenuUpdates() { |
+ return true; |
+ } |
+ |
+ private void cancelAllRequests() { |
+ if (mNativeContextSelectionClient != 0) { |
+ nativeCancelAllRequests(mNativeContextSelectionClient); |
+ } |
+ |
+ mProvider.cancelAllRequests(); |
+ } |
+ |
+ private void requestSurroundingText(@RequestType int callbackData) { |
+ if (mNativeContextSelectionClient == 0) { |
+ onSurroundingTextReceived(callbackData, "", 0, 0); |
+ return; |
+ } |
+ |
+ nativeRequestSurroundingText(mNativeContextSelectionClient, callbackData); |
+ } |
+ |
+ @CalledByNative |
+ private void onSurroundingTextReceived( |
+ @RequestType int callbackData, String text, int start, int end) { |
+ if (TextUtils.isEmpty(text)) { |
+ mOuterCallback.onClassified(new ContextSelectionProvider.Result()); |
+ return; |
+ } |
+ |
+ switch (callbackData) { |
+ case SUGGEST_AND_CLASSIFY: |
+ mProvider.sendSuggestAndClassifyRequest(text, start, end); |
+ break; |
+ |
+ case CLASSIFY: |
+ mProvider.sendClassifyRequest(text, start, end); |
+ break; |
+ |
+ default: |
+ assert false : "Unexpected callback data"; |
+ break; |
+ } |
+ } |
+ |
+ private native long nativeInit(WebContents webContents); |
+ private native void nativeRequestSurroundingText( |
+ long nativeContextSelectionClient, int callbackData); |
+ private native void nativeCancelAllRequests(long nativeContextSelectionClient); |
+} |