summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java30
-rw-r--r--base/android/java/src/org/chromium/base/SystemMessageHandler.java141
-rw-r--r--content/browser/android/content_view_core_impl.cc22
-rw-r--r--content/browser/android/content_view_core_impl.h5
-rw-r--r--content/browser/renderer_host/input/touch_selection_controller.cc14
-rw-r--r--content/browser/renderer_host/input/touch_selection_controller.h3
-rw-r--r--content/browser/renderer_host/input/touch_selection_controller_unittest.cc25
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc9
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.h3
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java53
10 files changed, 179 insertions, 126 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index e47e0cc207..3b45089e0a 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -20,6 +20,7 @@ import android.net.http.SslCertificate;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
@@ -48,6 +49,7 @@ import org.chromium.content.browser.ContentSettings;
import org.chromium.content.browser.ContentViewClient;
import org.chromium.content.browser.ContentViewCore;
import org.chromium.content.browser.ContentViewStatics;
+import org.chromium.content.browser.SmartClipProvider;
import org.chromium.content.browser.WebContentsObserverAndroid;
import org.chromium.content.common.CleanupReference;
import org.chromium.content_public.browser.GestureStateListener;
@@ -80,7 +82,7 @@ import java.util.concurrent.Callable;
* continuous build & test in the open source SDK-based tree).
*/
@JNINamespace("android_webview")
-public class AwContents {
+public class AwContents implements SmartClipProvider {
private static final String TAG = "AwContents";
private static final String WEB_ARCHIVE_EXTENSION = ".mht";
@@ -2227,12 +2229,34 @@ public class AwContents {
return null;
}
+ @Override
public void extractSmartClipData(int x, int y, int width, int height) {
if (!isDestroyed()) mContentViewCore.extractSmartClipData(x, y, width, height);
}
- public void setSmartClipDataListener(ContentViewCore.SmartClipDataListener listener) {
- if (!isDestroyed()) mContentViewCore.setSmartClipDataListener(listener);
+ @Override
+ public void setSmartClipResultHandler(final Handler resultHandler) {
+ if (resultHandler == null) {
+ mContentViewCore.setSmartClipDataListener(null);
+ return;
+ }
+ mContentViewCore.setSmartClipDataListener(new ContentViewCore.SmartClipDataListener() {
+ public void onSmartClipDataExtracted(String text, String html, Rect clipRect) {
+ Bundle bundle = new Bundle();
+ bundle.putString("url", mContentViewCore.getWebContents().getVisibleUrl());
+ bundle.putString("title", mContentViewCore.getWebContents().getTitle());
+ bundle.putParcelable("rect", clipRect);
+ bundle.putString("text", text);
+ bundle.putString("html", html);
+ try {
+ Message msg = Message.obtain(resultHandler, 0);
+ msg.setData(bundle);
+ msg.sendToTarget();
+ } catch (Exception e) {
+ Log.e(TAG, "Error calling handler for smart clip data: ", e);
+ }
+ }
+ });
}
// --------------------------------------------------------------------------------------------
diff --git a/base/android/java/src/org/chromium/base/SystemMessageHandler.java b/base/android/java/src/org/chromium/base/SystemMessageHandler.java
index 42c8987ec6..fd3dc5a08b 100644
--- a/base/android/java/src/org/chromium/base/SystemMessageHandler.java
+++ b/base/android/java/src/org/chromium/base/SystemMessageHandler.java
@@ -5,12 +5,9 @@
package org.chromium.base;
import android.os.Handler;
-import android.os.Looper;
import android.os.Message;
-import android.os.MessageQueue;
import android.util.Log;
-import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -25,23 +22,31 @@ class SystemMessageHandler extends Handler {
private long mMessagePumpDelegateNative = 0;
private long mDelayedScheduledTimeTicks = 0;
- // The following members are used to detect and trace the presence of sync
- // barriers in Android's MessageQueue. Note that this detection is
- // experimental, temporary and intended only for diagnostic purposes.
- private MessageQueue mMessageQueue;
- private Field mMessageQueueMessageField;
- private Field mMessageTargetField;
- private boolean mQueueHasSyncBarrier;
- private long mSyncBarrierTraceId;
+ // Reflected API for marking a message as asynchronous. This is a workaround
+ // to provide fair Chromium task dispatch when served by the Android UI
+ // thread's Looper, avoiding stalls when the Looper has a sync barrier.
+ // Note: Use of this API is experimental and likely to evolve in the future.
+ private Method mMessageMethodSetAsynchronous;
private SystemMessageHandler(long messagePumpDelegateNative) {
mMessagePumpDelegateNative = messagePumpDelegateNative;
- tryEnableSyncBarrierDetection();
- }
+
+ try {
+ Class<?> messageClass = Class.forName("android.os.Message");
+ mMessageMethodSetAsynchronous = messageClass.getMethod(
+ "setAsynchronous", new Class[]{boolean.class});
+ } catch (ClassNotFoundException e) {
+ Log.e(TAG, "Failed to find android.os.Message class:" + e);
+ } catch (NoSuchMethodException e) {
+ Log.e(TAG, "Failed to load Message.setAsynchronous method:" + e);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Exception while loading Message.setAsynchronous method: " + e);
+ }
+
+ }
@Override
public void handleMessage(Message msg) {
- updateWhetherQueueHasBlockingSyncBarrier();
if (msg.what == DELAYED_SCHEDULED_WORK) {
mDelayedScheduledTimeTicks = 0;
}
@@ -51,9 +56,7 @@ class SystemMessageHandler extends Handler {
@SuppressWarnings("unused")
@CalledByNative
private void scheduleWork() {
- updateWhetherQueueHasBlockingSyncBarrier();
- if (mQueueHasSyncBarrier) TraceEvent.instant("SystemMessageHandler:immediateWorkBlocked");
- sendEmptyMessage(SCHEDULED_WORK);
+ sendMessage(obtainAsyncMessage(SCHEDULED_WORK));
}
@SuppressWarnings("unused")
@@ -63,99 +66,41 @@ class SystemMessageHandler extends Handler {
removeMessages(DELAYED_SCHEDULED_WORK);
}
mDelayedScheduledTimeTicks = delayedTimeTicks;
- updateWhetherQueueHasBlockingSyncBarrier();
- if (mQueueHasSyncBarrier) TraceEvent.instant("SystemMessageHandler:delayedWorkBlocked");
- sendEmptyMessageDelayed(DELAYED_SCHEDULED_WORK, millis);
+ sendMessageDelayed(obtainAsyncMessage(DELAYED_SCHEDULED_WORK), millis);
}
@SuppressWarnings("unused")
@CalledByNative
private void removeAllPendingMessages() {
- updateWhetherQueueHasBlockingSyncBarrier();
removeMessages(SCHEDULED_WORK);
removeMessages(DELAYED_SCHEDULED_WORK);
}
- private void updateWhetherQueueHasBlockingSyncBarrier() {
- if (mMessageQueue == null) return;
- // As barrier detection is only used for tracing, early out when tracing
- // is disabled to avoid any potential performance penalties.
- if (!TraceEvent.enabled()) {
- mQueueHasSyncBarrier = false;
- return;
- }
- Message queueHead = (Message) getField(mMessageQueue, mMessageQueueMessageField);
- setqueueHasSyncBarrier(isSyncBarrierMessage(queueHead));
- }
-
- private boolean isSyncBarrierMessage(Message message) {
- if (message == null) return false;
- // Sync barrier messages have null targets.
- return getField(message, mMessageTargetField) == null;
- }
-
- private void tryEnableSyncBarrierDetection() {
- assert mMessageQueue == null;
-
- boolean success = false;
- try {
- Method getQueueMethod = Looper.class.getMethod("getQueue", new Class[]{});
- mMessageQueue = (MessageQueue) getQueueMethod.invoke(getLooper());
-
- mMessageQueueMessageField = mMessageQueue.getClass().getDeclaredField("mMessages");
- mMessageQueueMessageField.setAccessible(true);
-
- mMessageTargetField = Message.class.getDeclaredField("target");
- mMessageTargetField.setAccessible(true);
-
- mSyncBarrierTraceId = hashCode();
-
- success = true;
- } catch (NoSuchMethodException e) {
- Log.e(TAG, "Failed to load method: " + e);
- } catch (NoSuchFieldException e) {
- Log.e(TAG, "Failed to load field: " + e);
- } catch (InvocationTargetException e) {
- Log.e(TAG, "Failed invocation: " + e);
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Illegal access to reflected invocation: " + e);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Illegal argument to reflected invocation: " + e);
- } catch (RuntimeException e) {
- Log.e(TAG, e.toString());
- } finally {
- if (!success) disableSyncBarrierDetection();
- }
- }
-
- private void disableSyncBarrierDetection() {
- Log.e(TAG, "Unexpected error with sync barrier detection, disabling.");
- mMessageQueue = null;
- mMessageQueueMessageField = null;
- mMessageTargetField = null;
- setqueueHasSyncBarrier(false);
- }
-
- private void setqueueHasSyncBarrier(boolean queueHasSyncBarrier) {
- if (queueHasSyncBarrier == mQueueHasSyncBarrier) return;
- mQueueHasSyncBarrier = queueHasSyncBarrier;
- if (mQueueHasSyncBarrier) {
- TraceEvent.startAsync("SyncBarrier", mSyncBarrierTraceId);
- } else {
- TraceEvent.finishAsync("SyncBarrier", mSyncBarrierTraceId);
+ private Message obtainAsyncMessage(int what) {
+ Message msg = Message.obtain();
+ msg.what = what;
+ if (mMessageMethodSetAsynchronous != null) {
+ // If invocation fails, assume this is indicative of future
+ // failures, and avoid log spam by nulling the reflected method.
+ try {
+ mMessageMethodSetAsynchronous.invoke(msg, true);
+ } catch (IllegalAccessException e) {
+ Log.e(TAG, "Illegal access to asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Illegal argument for asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ } catch (InvocationTargetException e) {
+ Log.e(TAG, "Invocation exception during asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Runtime exception during asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ }
}
+ return msg;
}
- private Object getField(Object object, Field field) {
- try {
- return field.get(object);
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Failed field access: " + e);
- disableSyncBarrierDetection();
- }
- return null;
- }
-
@CalledByNative
private static SystemMessageHandler create(long messagePumpDelegateNative) {
return new SystemMessageHandler(messagePumpDelegateNative);
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 9cd9679d40..fece49f90f 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -1077,15 +1077,23 @@ void ContentViewCoreImpl::SelectBetweenCoordinates(JNIEnv* env, jobject obj,
void ContentViewCoreImpl::MoveCaret(JNIEnv* env, jobject obj,
jfloat x, jfloat y) {
- if (GetRenderWidgetHostViewAndroid()) {
- GetRenderWidgetHostViewAndroid()->MoveCaret(
- gfx::Point(x / dpi_scale_, y / dpi_scale_));
- }
+ RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
+ if (rwhv)
+ rwhv->MoveCaret(gfx::Point(x / dpi_scale_, y / dpi_scale_));
}
-void ContentViewCoreImpl::HideTextHandles(JNIEnv* env, jobject obj) {
- if (GetRenderWidgetHostViewAndroid())
- GetRenderWidgetHostViewAndroid()->HideTextHandles();
+void ContentViewCoreImpl::DismissTextHandles(JNIEnv* env, jobject obj) {
+ RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
+ if (rwhv)
+ rwhv->DismissTextHandles();
+}
+
+void ContentViewCoreImpl::SetTextHandlesTemporarilyHidden(JNIEnv* env,
+ jobject obj,
+ jboolean hidden) {
+ RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
+ if (rwhv)
+ rwhv->SetTextHandlesTemporarilyHidden(hidden);
}
void ContentViewCoreImpl::ResetGestureDetection(JNIEnv* env, jobject obj) {
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index 9887c0e404..d7f2711c10 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -143,7 +143,10 @@ class ContentViewCoreImpl : public ContentViewCore,
jfloat x1, jfloat y1,
jfloat x2, jfloat y2);
void MoveCaret(JNIEnv* env, jobject obj, jfloat x, jfloat y);
- void HideTextHandles(JNIEnv* env, jobject obj);
+ void DismissTextHandles(JNIEnv* env, jobject obj);
+ void SetTextHandlesTemporarilyHidden(JNIEnv* env,
+ jobject obj,
+ jboolean hidden);
void ResetGestureDetection(JNIEnv* env, jobject obj);
void SetDoubleTapSupportEnabled(JNIEnv* env, jobject obj, jboolean enabled);
diff --git a/content/browser/renderer_host/input/touch_selection_controller.cc b/content/browser/renderer_host/input/touch_selection_controller.cc
index d57b96f0aa..e904e283ee 100644
--- a/content/browser/renderer_host/input/touch_selection_controller.cc
+++ b/content/browser/renderer_host/input/touch_selection_controller.cc
@@ -160,6 +160,20 @@ void TouchSelectionController::HideAndDisallowShowingAutomatically() {
activate_selection_automatically_ = false;
}
+void TouchSelectionController::SetTemporarilyHidden(bool hidden) {
+ if (temporarily_hidden_ == hidden)
+ return;
+ temporarily_hidden_ = hidden;
+
+ TouchHandle::AnimationStyle animation_style = GetAnimationStyle(true);
+ if (is_selection_active_) {
+ start_selection_handle_->SetVisible(GetStartVisible(), animation_style);
+ end_selection_handle_->SetVisible(GetEndVisible(), animation_style);
+ }
+ if (is_insertion_active_)
+ insertion_handle_->SetVisible(GetStartVisible(), animation_style);
+}
+
void TouchSelectionController::OnSelectionEditable(bool editable) {
if (selection_editable_ == editable)
return;
diff --git a/content/browser/renderer_host/input/touch_selection_controller.h b/content/browser/renderer_host/input/touch_selection_controller.h
index 452dde0cc3..13031e12b9 100644
--- a/content/browser/renderer_host/input/touch_selection_controller.h
+++ b/content/browser/renderer_host/input/touch_selection_controller.h
@@ -69,6 +69,9 @@ class CONTENT_EXPORT TouchSelectionController : public TouchHandleClient {
// showing allowance.
void HideAndDisallowShowingAutomatically();
+ // Override the handle visibility according to |hidden|.
+ void SetTemporarilyHidden(bool hidden);
+
// To be called when the editability of the focused region changes.
void OnSelectionEditable(bool editable);
diff --git a/content/browser/renderer_host/input/touch_selection_controller_unittest.cc b/content/browser/renderer_host/input/touch_selection_controller_unittest.cc
index c3422077dd..5bdf57273f 100644
--- a/content/browser/renderer_host/input/touch_selection_controller_unittest.cc
+++ b/content/browser/renderer_host/input/touch_selection_controller_unittest.cc
@@ -632,6 +632,31 @@ TEST_F(TouchSelectionControllerTest, Animation) {
EXPECT_FALSE(GetAndResetNeedsAnimate());
}
+TEST_F(TouchSelectionControllerTest, TemporarilyHidden) {
+ controller().OnTapEvent();
+ controller().OnSelectionEditable(true);
+
+ gfx::RectF insertion_rect(5, 5, 0, 10);
+
+ bool visible = true;
+ ChangeInsertion(insertion_rect, visible);
+ EXPECT_FALSE(GetAndResetNeedsAnimate());
+
+ controller().SetTemporarilyHidden(true);
+ EXPECT_TRUE(GetAndResetNeedsAnimate());
+
+ visible = false;
+ ChangeInsertion(insertion_rect, visible);
+ EXPECT_FALSE(GetAndResetNeedsAnimate());
+
+ visible = true;
+ ChangeInsertion(insertion_rect, visible);
+ EXPECT_FALSE(GetAndResetNeedsAnimate());
+
+ controller().SetTemporarilyHidden(false);
+ EXPECT_TRUE(GetAndResetNeedsAnimate());
+}
+
TEST_F(TouchSelectionControllerTest, SelectionClearOnTap) {
gfx::RectF start_rect(5, 5, 0, 10);
gfx::RectF end_rect(50, 5, 0, 10);
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 66c9fcdd74..a20a7da14e 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1523,11 +1523,16 @@ void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
host_->MoveCaret(point);
}
-void RenderWidgetHostViewAndroid::HideTextHandles() {
+void RenderWidgetHostViewAndroid::DismissTextHandles() {
if (selection_controller_)
selection_controller_->HideAndDisallowShowingAutomatically();
}
+void RenderWidgetHostViewAndroid::SetTextHandlesTemporarilyHidden(bool hidden) {
+ if (selection_controller_)
+ selection_controller_->SetTemporarilyHidden(hidden);
+}
+
void RenderWidgetHostViewAndroid::OnShowingPastePopup(
const gfx::PointF& point) {
if (!selection_controller_)
@@ -1542,7 +1547,7 @@ void RenderWidgetHostViewAndroid::OnShowingPastePopup(
insertion_bound.visible = true;
insertion_bound.edge_top = point;
insertion_bound.edge_bottom = point;
- HideTextHandles();
+ DismissTextHandles();
ShowSelectionHandlesAutomatically();
selection_controller_->OnSelectionEditable(true);
selection_controller_->OnSelectionEmpty(true);
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index 5393856a92..22bb69446c 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -259,7 +259,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
bool HasValidFrame() const;
void MoveCaret(const gfx::Point& point);
- void HideTextHandles();
+ void DismissTextHandles();
+ void SetTextHandlesTemporarilyHidden(bool hidden);
void OnShowingPastePopup(const gfx::PointF& point);
void SynchronousFrameMetadata(
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 001238487c..196f83d9de 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -545,7 +545,7 @@ public class ContentViewCore
public void onImeEvent() {
mPopupZoomer.hide(true);
getContentViewClient().onImeEvent();
- if (mFocusedNodeEditable) hideTextHandles();
+ if (mFocusedNodeEditable) dismissTextHandles();
}
@Override
@@ -1289,6 +1289,10 @@ public class ContentViewCore
private void hidePopupsAndClearSelection() {
mUnselectAllOnActionModeDismiss = true;
hidePopups();
+ // Clear the selection. The selection is cleared on destroying IME
+ // and also here since we may receive destroy first, for example
+ // when focus is lost in webview.
+ clearUserSelection();
}
private void hidePopupsAndPreserveSelection() {
@@ -1296,12 +1300,23 @@ public class ContentViewCore
hidePopups();
}
+ private void clearUserSelection() {
+ if (isSelectionEditable()) {
+ if (mInputConnection != null) {
+ int selectionEnd = Selection.getSelectionEnd(mEditable);
+ mInputConnection.setSelection(selectionEnd, selectionEnd);
+ }
+ } else if (mImeAdapter != null) {
+ mImeAdapter.unselect();
+ }
+ }
+
private void hidePopups() {
hideSelectActionBar();
hidePastePopup();
hideSelectPopup();
mPopupZoomer.hide(false);
- if (mUnselectAllOnActionModeDismiss) hideTextHandles();
+ if (mUnselectAllOnActionModeDismiss) dismissTextHandles();
}
private void restoreSelectionPopupsIfNecessary() {
@@ -1330,6 +1345,7 @@ public class ContentViewCore
@SuppressWarnings("javadoc")
public void onAttachedToWindow() {
setAccessibilityState(mAccessibilityManager.isEnabled());
+ setTextHandlesTemporarilyHidden(false);
restoreSelectionPopupsIfNecessary();
ScreenOrientationListener.getInstance().addObserver(this, mContext);
GamepadList.onAttachedToWindow(mContext);
@@ -1342,12 +1358,19 @@ public class ContentViewCore
@SuppressLint("MissingSuperCall")
public void onDetachedFromWindow() {
setInjectedAccessibility(false);
- hidePopupsAndPreserveSelection();
mZoomControlsDelegate.dismissZoomPicker();
unregisterAccessibilityContentObserver();
ScreenOrientationListener.getInstance().removeObserver(this);
GamepadList.onDetachedFromWindow();
+
+ // WebView uses PopupWindows for handle rendering, which may remain
+ // unintentionally visible even after the WebView has been detached.
+ // Override the handle visibility explicitly to address this, but
+ // preserve the underlying selection for detachment cases like screen
+ // locking and app switching.
+ setTextHandlesTemporarilyHidden(true);
+ hidePopupsAndPreserveSelection();
}
/**
@@ -1908,13 +1931,8 @@ public class ContentViewCore
public void onDestroyActionMode() {
mActionMode = null;
if (mUnselectAllOnActionModeDismiss) {
- hideTextHandles();
- if (isSelectionEditable()) {
- int selectionEnd = Selection.getSelectionEnd(mEditable);
- mInputConnection.setSelection(selectionEnd, selectionEnd);
- } else {
- mImeAdapter.unselect();
- }
+ dismissTextHandles();
+ clearUserSelection();
}
getContentViewClient().onContextualActionBarHidden();
}
@@ -2043,10 +2061,15 @@ public class ContentViewCore
getContentViewClient().onSelectionEvent(eventType, posXDip * scale, posYDip * scale);
}
- private void hideTextHandles() {
+ private void dismissTextHandles() {
mHasSelection = false;
mHasInsertion = false;
- if (mNativeContentViewCore != 0) nativeHideTextHandles(mNativeContentViewCore);
+ if (mNativeContentViewCore != 0) nativeDismissTextHandles(mNativeContentViewCore);
+ }
+
+ private void setTextHandlesTemporarilyHidden(boolean hide) {
+ if (mNativeContentViewCore == 0) return;
+ nativeSetTextHandlesTemporarilyHidden(mNativeContentViewCore, hide);
}
/**
@@ -2296,7 +2319,7 @@ public class ContentViewCore
@Override
public void paste() {
mImeAdapter.paste();
- hideTextHandles();
+ dismissTextHandles();
}
});
}
@@ -3009,7 +3032,9 @@ public class ContentViewCore
private native void nativeMoveCaret(long nativeContentViewCoreImpl, float x, float y);
- private native void nativeHideTextHandles(long nativeContentViewCoreImpl);
+ private native void nativeDismissTextHandles(long nativeContentViewCoreImpl);
+ private native void nativeSetTextHandlesTemporarilyHidden(
+ long nativeContentViewCoreImpl, boolean hidden);
private native void nativeResetGestureDetection(long nativeContentViewCoreImpl);