| Index: content/public/android/java/src/org/chromium/content/browser/WebActionMode.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/WebActionMode.java b/content/public/android/java/src/org/chromium/content/browser/WebActionMode.java
|
| index befbb81b1f5279794a6f65c0b750c90474912206..6c0008954994aea0ef1a6e4c5bb443bef58b7883 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/WebActionMode.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/WebActionMode.java
|
| @@ -4,7 +4,10 @@
|
|
|
| package org.chromium.content.browser;
|
|
|
| +import android.annotation.TargetApi;
|
| +import android.os.Build;
|
| import android.view.ActionMode;
|
| +import android.view.View;
|
|
|
| import org.chromium.base.Log;
|
|
|
| @@ -12,18 +15,36 @@ import org.chromium.base.Log;
|
| * An ActionMode for in-page web content selection. This class wraps an ActionMode created
|
| * by the associated View, providing modified interaction with that ActionMode.
|
| */
|
| +@TargetApi(Build.VERSION_CODES.M)
|
| public class WebActionMode {
|
| - private static final String TAG = "cr.SelectActionMode";
|
| + private static final String TAG = "cr.WebActionMode";
|
|
|
| protected final ActionMode mActionMode;
|
| + private final View mView;
|
| + private boolean mHidden;
|
| + private boolean mPendingInvalidateContentRect;
|
| +
|
| + // Self-repeating task that repeatedly hides the ActionMode. This is
|
| + // required because ActionMode only exposes a temporary hide routine.
|
| + private final Runnable mRepeatingHideRunnable;
|
|
|
| /**
|
| * Constructs a SelectActionMode instance wrapping a concrete ActionMode.
|
| * @param actionMode the wrapped ActionMode.
|
| */
|
| - public WebActionMode(ActionMode actionMode) {
|
| + public WebActionMode(ActionMode actionMode, View view) {
|
| assert actionMode != null;
|
| + assert view != null;
|
| mActionMode = actionMode;
|
| + mView = view;
|
| + mRepeatingHideRunnable = new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + assert mHidden;
|
| + mView.postDelayed(mRepeatingHideRunnable, ActionMode.DEFAULT_HIDE_DURATION - 1);
|
| + hideTemporarily(ActionMode.DEFAULT_HIDE_DURATION);
|
| + }
|
| + };
|
| }
|
|
|
| /**
|
| @@ -35,8 +56,17 @@ public class WebActionMode {
|
|
|
| /**
|
| * @see ActionMode#invalidate()
|
| + * Note that invalidation will also reset visibility state. The caller
|
| + * should account for this when making subsequent visibility updates.
|
| */
|
| public void invalidate() {
|
| + if (mHidden) {
|
| + assert canHide();
|
| + mHidden = false;
|
| + mView.removeCallbacks(mRepeatingHideRunnable);
|
| + mPendingInvalidateContentRect = false;
|
| + }
|
| +
|
| // Try/catch necessary for framework bug, crbug.com/446717.
|
| try {
|
| mActionMode.invalidate();
|
| @@ -48,5 +78,65 @@ public class WebActionMode {
|
| /**
|
| * @see ActionMode#invalidateContentRect()
|
| */
|
| - public void invalidateContentRect() {}
|
| + public void invalidateContentRect() {
|
| + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
| + if (mHidden) {
|
| + mPendingInvalidateContentRect = true;
|
| + } else {
|
| + mPendingInvalidateContentRect = false;
|
| + mActionMode.invalidateContentRect();
|
| + }
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @see ActionMode#onWindowFocusChanged()
|
| + */
|
| + public void onWindowFocusChanged(boolean hasWindowFocus) {
|
| + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
| + mActionMode.onWindowFocusChanged(hasWindowFocus);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Hide or reveal the ActionMode. Note that this only has visible
|
| + * side-effects if the underlying ActionMode supports hiding.
|
| + * @param hide whether to hide or show the ActionMode.
|
| + */
|
| + public void hide(boolean hide) {
|
| + if (!canHide()) return;
|
| + if (mHidden == hide) return;
|
| + mHidden = hide;
|
| + if (mHidden) {
|
| + mRepeatingHideRunnable.run();
|
| + } else {
|
| + mHidden = false;
|
| + mView.removeCallbacks(mRepeatingHideRunnable);
|
| + // Delay the reveal slightly as there could be trailing content
|
| + // rect invalidations soon after showing (which would temporarily
|
| + // hide the ActionMode yet again).
|
| + hideTemporarily(300);
|
| + if (mPendingInvalidateContentRect) {
|
| + mPendingInvalidateContentRect = false;
|
| + invalidateContentRect();
|
| + }
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @see ActionMode#hide(long)
|
| + */
|
| + private void hideTemporarily(long duration) {
|
| + assert canHide();
|
| + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
| + mActionMode.hide(duration);
|
| + }
|
| + }
|
| +
|
| + private boolean canHide() {
|
| + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
| + return mActionMode.getType() == ActionMode.TYPE_FLOATING;
|
| + }
|
| + return false;
|
| + }
|
| }
|
|
|