Use DeviceConfig flags for cursor drag and insertion handle gestures
Bug: 149751656 Test: Manually and ran automated tests atest FrameworksCoreTests:TextViewActivityTest atest FrameworksCoreTests:EditorCursorDragTest Change-Id: I431dd7c13b573d7acd9ce20e16a6476370202b5f
This commit is contained in:
@@ -151,9 +151,6 @@ public class Editor {
|
||||
private static final String TAG = "Editor";
|
||||
private static final boolean DEBUG_UNDO = false;
|
||||
|
||||
// Specifies whether to allow starting a cursor drag by dragging anywhere over the text.
|
||||
@VisibleForTesting
|
||||
public static boolean FLAG_ENABLE_CURSOR_DRAG = true;
|
||||
// Specifies whether to use the magnifier when pressing the insertion or selection handles.
|
||||
private static final boolean FLAG_USE_MAGNIFIER = true;
|
||||
|
||||
@@ -387,9 +384,8 @@ public class Editor {
|
||||
|
||||
private final SuggestionHelper mSuggestionHelper = new SuggestionHelper();
|
||||
|
||||
// Specifies whether the cursor control feature set is enabled.
|
||||
// This can only be true if the text view is editable.
|
||||
private boolean mCursorControlEnabled;
|
||||
private boolean mFlagCursorDragFromAnywhereEnabled;
|
||||
private boolean mFlagInsertionHandleGesturesEnabled;
|
||||
|
||||
// Specifies whether the new magnifier (with fish-eye effect) is enabled.
|
||||
private final boolean mNewMagnifierEnabled;
|
||||
@@ -402,26 +398,40 @@ public class Editor {
|
||||
mHapticTextHandleEnabled = mTextView.getContext().getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_enableHapticTextHandle);
|
||||
|
||||
mCursorControlEnabled = AppGlobals.getIntCoreSetting(
|
||||
WidgetFlags.KEY_ENABLE_CURSOR_CONTROL , 0) != 0;
|
||||
mFlagCursorDragFromAnywhereEnabled = AppGlobals.getIntCoreSetting(
|
||||
WidgetFlags.KEY_ENABLE_CURSOR_DRAG_FROM_ANYWHERE , 1) != 0;
|
||||
mFlagInsertionHandleGesturesEnabled = AppGlobals.getIntCoreSetting(
|
||||
WidgetFlags.KEY_ENABLE_INSERTION_HANDLE_GESTURES , 0) != 0;
|
||||
mNewMagnifierEnabled = AppGlobals.getIntCoreSetting(
|
||||
WidgetFlags.KEY_ENABLE_NEW_MAGNIFIER, 0) != 0;
|
||||
if (TextView.DEBUG_CURSOR) {
|
||||
logCursor("Editor", "Cursor control is %s.",
|
||||
mCursorControlEnabled ? "enabled" : "disabled");
|
||||
logCursor("Editor", "Cursor drag from anywhere is %s.",
|
||||
mFlagCursorDragFromAnywhereEnabled ? "enabled" : "disabled");
|
||||
logCursor("Editor", "Insertion handle gestures is %s.",
|
||||
mFlagInsertionHandleGesturesEnabled ? "enabled" : "disabled");
|
||||
logCursor("Editor", "New magnifier is %s.",
|
||||
mNewMagnifierEnabled ? "enabled" : "disabled");
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setCursorControlEnabled(boolean enabled) {
|
||||
mCursorControlEnabled = enabled;
|
||||
public boolean getFlagCursorDragFromAnywhereEnabled() {
|
||||
return mFlagCursorDragFromAnywhereEnabled;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public boolean getCursorControlEnabled() {
|
||||
return mCursorControlEnabled;
|
||||
public void setFlagCursorDragFromAnywhereEnabled(boolean enabled) {
|
||||
mFlagCursorDragFromAnywhereEnabled = enabled;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public boolean getFlagInsertionHandleGesturesEnabled() {
|
||||
return mFlagInsertionHandleGesturesEnabled;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setFlagInsertionHandleGesturesEnabled(boolean enabled) {
|
||||
mFlagInsertionHandleGesturesEnabled = enabled;
|
||||
}
|
||||
|
||||
// Lazy creates the magnifier animator.
|
||||
@@ -5259,7 +5269,7 @@ public class Editor {
|
||||
|
||||
int deltaHeight = 0;
|
||||
int opacity = 255;
|
||||
if (mCursorControlEnabled) {
|
||||
if (mFlagInsertionHandleGesturesEnabled) {
|
||||
deltaHeight = AppGlobals.getIntCoreSetting(
|
||||
WidgetFlags.KEY_INSERTION_HANDLE_DELTA_HEIGHT, 25);
|
||||
opacity = AppGlobals.getIntCoreSetting(
|
||||
@@ -5329,7 +5339,7 @@ public class Editor {
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (mCursorControlEnabled) {
|
||||
if (mFlagInsertionHandleGesturesEnabled) {
|
||||
final int height = Math.max(
|
||||
getPreferredHeight() + mDeltaHeight, mDrawable.getIntrinsicHeight());
|
||||
setMeasuredDimension(getPreferredWidth(), height);
|
||||
@@ -5340,7 +5350,7 @@ public class Editor {
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
if (mCursorControlEnabled && FLAG_ENABLE_CURSOR_DRAG) {
|
||||
if (mFlagInsertionHandleGesturesEnabled && mFlagCursorDragFromAnywhereEnabled) {
|
||||
// Should only enable touch through when cursor drag is enabled.
|
||||
// Otherwise the insertion handle view cannot be moved.
|
||||
return touchThrough(ev);
|
||||
@@ -6025,7 +6035,7 @@ public class Editor {
|
||||
}
|
||||
if (mIsDraggingCursor) {
|
||||
performCursorDrag(event);
|
||||
} else if (FLAG_ENABLE_CURSOR_DRAG
|
||||
} else if (mFlagCursorDragFromAnywhereEnabled
|
||||
&& mTextView.getLayout() != null
|
||||
&& mTextView.isFocused()
|
||||
&& mTouchState.isMovedEnoughForDrag()
|
||||
|
||||
@@ -17,23 +17,36 @@
|
||||
package android.widget;
|
||||
|
||||
/**
|
||||
* Keeps the flags related to the Widget namespace in {@link DeviceConfig}.
|
||||
* Flags in the {@link android.provider.DeviceConfig#NAMESPACE_WIDGET "widget" namespace}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class WidgetFlags {
|
||||
|
||||
/**
|
||||
* Whether the cursor control feature set is enabled.
|
||||
* TODO: Makes this flag key visible to webview/chrome.
|
||||
* Whether starting a cursor drag from anywhere in the text should be enabled.
|
||||
*/
|
||||
public static final String ENABLE_CURSOR_CONTROL =
|
||||
"CursorControlFeature__enable_cursor_control";
|
||||
public static final String ENABLE_CURSOR_DRAG_FROM_ANYWHERE =
|
||||
"CursorControlFeature__enable_cursor_drag_from_anywhere";
|
||||
|
||||
/**
|
||||
* The key name used in app core settings for enable cursor control.
|
||||
* The key used in app core settings for the flag {@link #ENABLE_CURSOR_DRAG_FROM_ANYWHERE}.
|
||||
*/
|
||||
public static final String KEY_ENABLE_CURSOR_CONTROL = "widget__enable_cursor_control";
|
||||
public static final String KEY_ENABLE_CURSOR_DRAG_FROM_ANYWHERE =
|
||||
"widget__enable_cursor_drag_from_anywhere";
|
||||
|
||||
/**
|
||||
* Whether additional gestures should be enabled for the insertion cursor handle (e.g.
|
||||
* long-press or double-tap on the handle to trigger selection).
|
||||
*/
|
||||
public static final String ENABLE_INSERTION_HANDLE_GESTURES =
|
||||
"CursorControlFeature__enable_insertion_handle_gestures";
|
||||
|
||||
/**
|
||||
* The key used in app core settings for the flag {@link #ENABLE_INSERTION_HANDLE_GESTURES}.
|
||||
*/
|
||||
public static final String KEY_ENABLE_INSERTION_HANDLE_GESTURES =
|
||||
"widget__enable_insertion_handle_gestures";
|
||||
|
||||
/**
|
||||
* The flag of delta height applies to the insertion handle when cursor control flag is enabled.
|
||||
|
||||
@@ -44,7 +44,6 @@ import com.android.frameworks.coretests.R;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -57,7 +56,6 @@ public class EditorCursorDragTest {
|
||||
public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>(
|
||||
TextViewActivity.class);
|
||||
|
||||
private boolean mOriginalFlagValue;
|
||||
private Instrumentation mInstrumentation;
|
||||
private Activity mActivity;
|
||||
|
||||
@@ -65,13 +63,6 @@ public class EditorCursorDragTest {
|
||||
public void before() throws Throwable {
|
||||
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
mActivity = mActivityRule.getActivity();
|
||||
mOriginalFlagValue = Editor.FLAG_ENABLE_CURSOR_DRAG;
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = true;
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws Throwable {
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = mOriginalFlagValue;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -31,8 +31,8 @@ import static android.widget.espresso.TextViewActions.doubleTapAndDragHandle;
|
||||
import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText;
|
||||
import static android.widget.espresso.TextViewActions.doubleTapHandle;
|
||||
import static android.widget.espresso.TextViewActions.dragHandle;
|
||||
import static android.widget.espresso.TextViewActions.longPressAndDragOnText;
|
||||
import static android.widget.espresso.TextViewActions.longPressAndDragHandle;
|
||||
import static android.widget.espresso.TextViewActions.longPressAndDragOnText;
|
||||
import static android.widget.espresso.TextViewActions.longPressHandle;
|
||||
import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex;
|
||||
import static android.widget.espresso.TextViewAssertions.doesNotHaveStyledText;
|
||||
@@ -514,29 +514,26 @@ public class TextViewActivityTest {
|
||||
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
|
||||
}
|
||||
|
||||
private void enableFlagsForInsertionHandleGestures() {
|
||||
final TextView textView = mActivity.findViewById(R.id.textview);
|
||||
final Editor editor = textView.getEditorForTesting();
|
||||
editor.setFlagCursorDragFromAnywhereEnabled(true);
|
||||
editor.setFlagInsertionHandleGesturesEnabled(true);
|
||||
// Note: We don't need to reset these flags explicitly at the end of each test, because a
|
||||
// fresh TextView and Editor will be created for each test.
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertionHandle_touchThrough() {
|
||||
final TextView textView = mActivity.findViewById(R.id.textview);
|
||||
boolean cursorControlEnabled = textView.getEditorForTesting().getCursorControlEnabled();
|
||||
boolean cursorDragEnabled = Editor.FLAG_ENABLE_CURSOR_DRAG;
|
||||
textView.getEditorForTesting().setCursorControlEnabled(true);
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = true;
|
||||
|
||||
enableFlagsForInsertionHandleGestures();
|
||||
testInsertionHandle();
|
||||
testInsertionHandle_multiLine();
|
||||
|
||||
textView.getEditorForTesting().setCursorControlEnabled(cursorControlEnabled);
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = cursorDragEnabled;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertionHandle_longPressToSelect() {
|
||||
// This test only makes sense when Cursor Control flag is enabled.
|
||||
enableFlagsForInsertionHandleGestures();
|
||||
final TextView textView = mActivity.findViewById(R.id.textview);
|
||||
boolean cursorControlEnabled = textView.getEditorForTesting().getCursorControlEnabled();
|
||||
boolean cursorDragEnabled = Editor.FLAG_ENABLE_CURSOR_DRAG;
|
||||
textView.getEditorForTesting().setCursorControlEnabled(true);
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = true;
|
||||
|
||||
final String text = "hello the world";
|
||||
onView(withId(R.id.textview)).perform(replaceText(text));
|
||||
@@ -546,20 +543,12 @@ public class TextViewActivityTest {
|
||||
|
||||
onHandleView(com.android.internal.R.id.insertion_handle).perform(longPressHandle(textView));
|
||||
onView(withId(R.id.textview)).check(hasSelection("world"));
|
||||
|
||||
textView.getEditorForTesting().setCursorControlEnabled(cursorControlEnabled);
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = cursorDragEnabled;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertionHandle_longPressAndDragToSelect() {
|
||||
// This test only makes sense when Cursor Control flag is enabled.
|
||||
enableFlagsForInsertionHandleGestures();
|
||||
final TextView textView = mActivity.findViewById(R.id.textview);
|
||||
boolean cursorControlEnabled = textView.getEditorForTesting().getCursorControlEnabled();
|
||||
boolean cursorDragEnabled = Editor.FLAG_ENABLE_CURSOR_DRAG;
|
||||
textView.getEditorForTesting().setCursorControlEnabled(true);
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = true;
|
||||
|
||||
final String text = "hello the world";
|
||||
onView(withId(R.id.textview)).perform(replaceText(text));
|
||||
|
||||
@@ -569,19 +558,12 @@ public class TextViewActivityTest {
|
||||
onHandleView(com.android.internal.R.id.insertion_handle)
|
||||
.perform(longPressAndDragHandle(textView, Handle.INSERTION, text.indexOf('t')));
|
||||
onView(withId(R.id.textview)).check(hasSelection("the world"));
|
||||
|
||||
textView.getEditorForTesting().setCursorControlEnabled(cursorControlEnabled);
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = cursorDragEnabled;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertionHandle_doubleTapToSelect() {
|
||||
// This test only makes sense when Cursor Control flag is enabled.
|
||||
enableFlagsForInsertionHandleGestures();
|
||||
final TextView textView = mActivity.findViewById(R.id.textview);
|
||||
boolean cursorControlEnabled = textView.getEditorForTesting().getCursorControlEnabled();
|
||||
boolean cursorDragEnabled = Editor.FLAG_ENABLE_CURSOR_DRAG;
|
||||
textView.getEditorForTesting().setCursorControlEnabled(true);
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = true;
|
||||
|
||||
final String text = "hello the world";
|
||||
onView(withId(R.id.textview)).perform(replaceText(text));
|
||||
@@ -591,19 +573,12 @@ public class TextViewActivityTest {
|
||||
|
||||
onHandleView(com.android.internal.R.id.insertion_handle).perform(doubleTapHandle(textView));
|
||||
onView(withId(R.id.textview)).check(hasSelection("world"));
|
||||
|
||||
textView.getEditorForTesting().setCursorControlEnabled(cursorControlEnabled);
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = cursorDragEnabled;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertionHandle_doubleTapAndDragToSelect() {
|
||||
// This test only makes sense when Cursor Control flag is enabled.
|
||||
enableFlagsForInsertionHandleGestures();
|
||||
final TextView textView = mActivity.findViewById(R.id.textview);
|
||||
boolean cursorControlEnabled = textView.getEditorForTesting().getCursorControlEnabled();
|
||||
boolean cursorDragEnabled = Editor.FLAG_ENABLE_CURSOR_DRAG;
|
||||
textView.getEditorForTesting().setCursorControlEnabled(true);
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = true;
|
||||
|
||||
final String text = "hello the world";
|
||||
onView(withId(R.id.textview)).perform(replaceText(text));
|
||||
@@ -614,9 +589,6 @@ public class TextViewActivityTest {
|
||||
onHandleView(com.android.internal.R.id.insertion_handle)
|
||||
.perform(doubleTapAndDragHandle(textView, Handle.INSERTION, text.indexOf('t')));
|
||||
onView(withId(R.id.textview)).check(hasSelection("the world"));
|
||||
|
||||
textView.getEditorForTesting().setCursorControlEnabled(cursorControlEnabled);
|
||||
Editor.FLAG_ENABLE_CURSOR_DRAG = cursorDragEnabled;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -106,8 +106,11 @@ final class CoreSettingsObserver extends ContentObserver {
|
||||
// add other global settings here...
|
||||
|
||||
sDeviceConfigEntries.add(new DeviceConfigEntry(
|
||||
DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.ENABLE_CURSOR_CONTROL,
|
||||
WidgetFlags.KEY_ENABLE_CURSOR_CONTROL, boolean.class));
|
||||
DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.ENABLE_CURSOR_DRAG_FROM_ANYWHERE,
|
||||
WidgetFlags.KEY_ENABLE_CURSOR_DRAG_FROM_ANYWHERE, boolean.class));
|
||||
sDeviceConfigEntries.add(new DeviceConfigEntry(
|
||||
DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.ENABLE_INSERTION_HANDLE_GESTURES,
|
||||
WidgetFlags.KEY_ENABLE_INSERTION_HANDLE_GESTURES, boolean.class));
|
||||
sDeviceConfigEntries.add(new DeviceConfigEntry(
|
||||
DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.INSERTION_HANDLE_DELTA_HEIGHT,
|
||||
WidgetFlags.KEY_INSERTION_HANDLE_DELTA_HEIGHT, int.class));
|
||||
|
||||
Reference in New Issue
Block a user