Migrate TextView to use OnBackInvokedDispatcher.

The OnBackInvokedCallback will be called when an app is requesting the new back dispatch behavior. Otherwise we keep dispatching KEYCODE_BACK to TextViews.

Test: Use backTestApp WidgetTestsActivity. Try selecting texts and
dimisss selection by swiping back. Both on TextView and EditText and
AutoCompleteTextView.

Change-Id: I9422f28ab650c5d77c75394fe6dcf2a3981f79c7
This commit is contained in:
Shan Huang
2022-03-03 18:50:29 +00:00
parent 7c722ca403
commit 76561c0ce8

View File

@@ -111,6 +111,7 @@ import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -129,6 +130,9 @@ import android.view.textclassifier.TextClassificationManager;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView.Drawables;
import android.widget.TextView.OnEditorActionListener;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
import android.window.WindowOnBackInvokedDispatcher;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.EditableInputConnection;
@@ -235,6 +239,14 @@ public class Editor {
private boolean mSelectionControllerEnabled;
private final boolean mHapticTextHandleEnabled;
/** Handles OnBackInvokedCallback back dispatch */
private final OnBackInvokedCallback mBackCallback = new OnBackInvokedCallback() {
@Override
public void onBackInvoked() {
stopTextActionMode();
}
};
private boolean mBackCallbackRegistered;
@Nullable
private MagnifierMotionAnimator mMagnifierAnimator;
@@ -753,6 +765,35 @@ public class Editor {
stopTextActionModeWithPreservingSelection();
mDefaultOnReceiveContentListener.clearInputConnectionInfo();
unregisterOnBackInvokedCallback();
}
private void unregisterOnBackInvokedCallback() {
if (!mBackCallbackRegistered) {
return;
}
ViewRootImpl viewRootImpl = getTextView().getViewRootImpl();
if (viewRootImpl != null
&& WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
viewRootImpl.mContext)) {
viewRootImpl.getOnBackInvokedDispatcher()
.unregisterOnBackInvokedCallback(mBackCallback);
mBackCallbackRegistered = false;
}
}
private void registerOnBackInvokedCallback() {
if (mBackCallbackRegistered) {
return;
}
ViewRootImpl viewRootImpl = mTextView.getViewRootImpl();
if (viewRootImpl != null
&& WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
viewRootImpl.mContext)) {
viewRootImpl.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT, mBackCallback);
mBackCallbackRegistered = true;
}
}
private void discardTextDisplayLists() {
@@ -2370,6 +2411,7 @@ public class Editor {
new TextActionModeCallback(TextActionMode.INSERTION);
mTextActionMode = mTextView.startActionMode(
actionModeCallback, ActionMode.TYPE_FLOATING);
registerOnBackInvokedCallback();
if (mTextActionMode != null && getInsertionController() != null) {
getInsertionController().show();
}
@@ -2485,6 +2527,7 @@ public class Editor {
ActionMode.Callback actionModeCallback = new TextActionModeCallback(actionMode);
mTextActionMode = mTextView.startActionMode(actionModeCallback, ActionMode.TYPE_FLOATING);
registerOnBackInvokedCallback();
final boolean selectableText = mTextView.isTextEditable() || mTextView.isTextSelectable();
if (actionMode == TextActionMode.TEXT_LINK && !selectableText
@@ -2660,6 +2703,7 @@ public class Editor {
// This will hide the mSelectionModifierCursorController
mTextActionMode.finish();
}
unregisterOnBackInvokedCallback();
}
private void stopTextActionModeWithPreservingSelection() {