summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityThread.java9
-rw-r--r--core/java/android/app/AppGlobals.java16
-rw-r--r--core/java/android/widget/Editor.java73
-rw-r--r--core/java/android/widget/WidgetFlags.java60
-rw-r--r--services/core/java/com/android/server/am/CoreSettingsObserver.java15
5 files changed, 158 insertions, 15 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b82a67556fc0..2ca5b1d5c76f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -7326,6 +7326,15 @@ public final class ActivityThread extends ClientTransactionHandler {
}
}
+ float getFloatCoreSetting(String key, float defaultValue) {
+ synchronized (mResourcesManager) {
+ if (mCoreSettings != null) {
+ return mCoreSettings.getFloat(key, defaultValue);
+ }
+ return defaultValue;
+ }
+ }
+
private static class AndroidOs extends ForwardingOs {
/**
* Install selective syscall interception. For example, this is used to
diff --git a/core/java/android/app/AppGlobals.java b/core/java/android/app/AppGlobals.java
index 81e1565ee86c..f66bf0d89c37 100644
--- a/core/java/android/app/AppGlobals.java
+++ b/core/java/android/app/AppGlobals.java
@@ -75,4 +75,20 @@ public class AppGlobals {
return defaultValue;
}
}
+
+ /**
+ * Gets the value of a float core setting.
+ *
+ * @param key The setting key.
+ * @param defaultValue The setting default value.
+ * @return The core settings.
+ */
+ public static float getFloatCoreSetting(String key, float defaultValue) {
+ ActivityThread currentActivityThread = ActivityThread.currentActivityThread();
+ if (currentActivityThread != null) {
+ return currentActivityThread.getFloatCoreSetting(key, defaultValue);
+ } else {
+ return defaultValue;
+ }
+ }
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index b10631b7ef2f..cdf8c686ef00 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -391,6 +391,9 @@ public class Editor {
// This can only be true if the text view is editable.
private boolean mCursorControlEnabled;
+ // Specifies whether the new magnifier (with fish-eye effect) is enabled.
+ private final boolean mNewMagnifierEnabled;
+
Editor(TextView textView) {
mTextView = textView;
// Synchronize the filter list, which places the undo input filter at the end.
@@ -401,9 +404,13 @@ public class Editor {
mCursorControlEnabled = AppGlobals.getIntCoreSetting(
WidgetFlags.KEY_ENABLE_CURSOR_CONTROL , 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", "New magnifier is %s.",
+ mNewMagnifierEnabled ? "enabled" : "disabled");
}
}
@@ -422,7 +429,7 @@ public class Editor {
if (FLAG_USE_MAGNIFIER && mMagnifierAnimator == null) {
// Lazy creates the magnifier instance because it requires the text height which cannot
// be measured at the time of Editor instance being created.
- final Magnifier.Builder builder = shouldUseNewMagnifier()
+ final Magnifier.Builder builder = mNewMagnifierEnabled
? createBuilderWithInlineMagnifierDefaults()
: Magnifier.createBuilderWithOldMagnifierDefaults(mTextView);
mMagnifierAnimator = new MagnifierMotionAnimator(builder.build());
@@ -430,24 +437,28 @@ public class Editor {
return mMagnifierAnimator;
}
- private boolean shouldUseNewMagnifier() {
- // TODO: use a separate flag to enable new magnifier.
- return mCursorControlEnabled;
- }
-
private Magnifier.Builder createBuilderWithInlineMagnifierDefaults() {
final Magnifier.Builder params = new Magnifier.Builder(mTextView);
// TODO: supports changing the height/width dynamically because the text height can be
// dynamically changed.
+ float zoom = AppGlobals.getFloatCoreSetting(
+ WidgetFlags.KEY_MAGNIFIER_ZOOM_FACTOR, 1.5f);
+ float aspectRatio = AppGlobals.getFloatCoreSetting(
+ WidgetFlags.KEY_MAGNIFIER_ASPECT_RATIO, 5.5f);
+ // Avoid invalid/unsupported values.
+ if (zoom < 1.2f || zoom > 1.8f) {
+ zoom = 1.5f;
+ }
+ if (aspectRatio < 3 || aspectRatio > 8) {
+ aspectRatio = 5.5f;
+ }
+
final Paint.FontMetrics fontMetrics = mTextView.getPaint().getFontMetrics();
final float sourceHeight = fontMetrics.descent - fontMetrics.ascent;
- final float zoom = 1.5f;
- final float widthHeightRatio = 5.5f;
// Slightly increase the height to avoid tooLargeTextForMagnifier() returns true.
int height = (int)(sourceHeight * zoom) + 2;
- int width = (int)(widthHeightRatio * height);
-
+ int width = (int)(aspectRatio * height);
params.setFishEyeStyle()
.setSize(width, height)
@@ -4680,11 +4691,11 @@ public class Editor {
}
};
- private int getPreferredWidth() {
+ protected final int getPreferredWidth() {
return Math.max(mDrawable.getIntrinsicWidth(), mMinSize);
}
- private int getPreferredHeight() {
+ protected final int getPreferredHeight() {
return Math.max(mDrawable.getIntrinsicHeight(), mMinSize);
}
@@ -5089,7 +5100,7 @@ public class Editor {
mTextView.invalidateCursorPath();
suspendBlink();
- if (shouldUseNewMagnifier()) {
+ if (mNewMagnifierEnabled) {
// Calculates the line bounds as the content source bounds to the magnifier.
Layout layout = mTextView.getLayout();
int line = layout.getLineForOffset(getCurrentCursorOffset());
@@ -5218,7 +5229,7 @@ public class Editor {
// Whether the popup window is in the invisible state and will be dismissed when finger up.
private boolean mPendingDismissOnUp = false;
// The alpha value of the drawable.
- private final int mDrawableOpacity = 255;
+ private final int mDrawableOpacity;
// Members for toggling the insertion menu in touch through mode.
@@ -5239,8 +5250,29 @@ public class Editor {
// of the touch through events.
private float mTextHeight;
- public InsertionHandleView(Drawable drawable) {
+ // The delta height applied to the insertion handle view.
+ private final int mDeltaHeight;
+
+ InsertionHandleView(Drawable drawable) {
super(drawable, drawable, com.android.internal.R.id.insertion_handle);
+
+ int deltaHeight = 0;
+ int opacity = 255;
+ if (mCursorControlEnabled) {
+ deltaHeight = AppGlobals.getIntCoreSetting(
+ WidgetFlags.KEY_INSERTION_HANDLE_DELTA_HEIGHT, 25);
+ opacity = AppGlobals.getIntCoreSetting(
+ WidgetFlags.KEY_INSERTION_HANDLE_OPACITY, 50);
+ // Avoid invalid/unsupported values.
+ if (deltaHeight < -25 || deltaHeight > 50) {
+ deltaHeight = 25;
+ }
+ if (opacity < 10 || opacity > 100) {
+ opacity = 50;
+ }
+ }
+ mDeltaHeight = deltaHeight;
+ mDrawableOpacity = opacity;
}
private void hideAfterDelay() {
@@ -5293,6 +5325,17 @@ public class Editor {
}
@Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (mCursorControlEnabled) {
+ final int height = Math.max(
+ getPreferredHeight() + mDeltaHeight, mDrawable.getIntrinsicHeight());
+ setMeasuredDimension(getPreferredWidth(), height);
+ return;
+ }
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ @Override
public boolean onTouchEvent(MotionEvent ev) {
if (mCursorControlEnabled && FLAG_ENABLE_CURSOR_DRAG) {
// Should only enable touch through when cursor drag is enabled.
diff --git a/core/java/android/widget/WidgetFlags.java b/core/java/android/widget/WidgetFlags.java
index fa1e498d55b6..1a8e7a713e7a 100644
--- a/core/java/android/widget/WidgetFlags.java
+++ b/core/java/android/widget/WidgetFlags.java
@@ -35,6 +35,66 @@ public final class WidgetFlags {
*/
public static final String KEY_ENABLE_CURSOR_CONTROL = "widget__enable_cursor_control";
+ /**
+ * The flag of delta height applies to the insertion handle when cursor control flag is enabled.
+ * The default value is 25.
+ */
+ public static final String INSERTION_HANDLE_DELTA_HEIGHT =
+ "CursorControlFeature__insertion_handle_delta_height";
+
+ /**
+ * The key name used in app core settings for {@link #INSERTION_HANDLE_DELTA_HEIGHT}.
+ */
+ public static final String KEY_INSERTION_HANDLE_DELTA_HEIGHT =
+ "widget__insertion_handle_delta_height";
+
+ /**
+ * The flag of opacity applies to the insertion handle when cursor control flag is enabled.
+ * The opacity value is in the range of {0..100}. The default value is 50.
+ */
+ public static final String INSERTION_HANDLE_OPACITY =
+ "CursorControlFeature__insertion_handle_opacity";
+
+ /**
+ * The key name used in app core settings for {@link #INSERTION_HANDLE_OPACITY}.
+ */
+ public static final String KEY_INSERTION_HANDLE_OPACITY =
+ "widget__insertion_handle_opacity";
+
+ /**
+ * The flag of enabling the new magnifier.
+ */
+ public static final String ENABLE_NEW_MAGNIFIER = "CursorControlFeature__enable_new_magnifier";
+
+ /**
+ * The key name used in app core settings for {@link #ENABLE_NEW_MAGNIFIER}.
+ */
+ public static final String KEY_ENABLE_NEW_MAGNIFIER = "widget__enable_new_magnifier";
+
+ /**
+ * The flag of zoom factor applies to the new magnifier.
+ * The default value is 1.5f.
+ */
+ public static final String MAGNIFIER_ZOOM_FACTOR =
+ "CursorControlFeature__magnifier_zoom_factor";
+
+ /**
+ * The key name used in app core settings for {@link #MAGNIFIER_ZOOM_FACTOR}.
+ */
+ public static final String KEY_MAGNIFIER_ZOOM_FACTOR = "widget__magnifier_zoom_factor";
+
+ /**
+ * The flag of aspect ratio (width/height) applies to the new magnifier.
+ * The default value is 5.5f.
+ */
+ public static final String MAGNIFIER_ASPECT_RATIO =
+ "CursorControlFeature__magnifier_aspect_ratio";
+
+ /**
+ * The key name used in app core settings for {@link #MAGNIFIER_ASPECT_RATIO}.
+ */
+ public static final String KEY_MAGNIFIER_ASPECT_RATIO = "widget__magnifier_aspect_ratio";
+
private WidgetFlags() {
}
}
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index fa55701cd882..a03f0bb4e399 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -108,6 +108,21 @@ final class CoreSettingsObserver extends ContentObserver {
sDeviceConfigEntries.add(new DeviceConfigEntry(
DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.ENABLE_CURSOR_CONTROL,
WidgetFlags.KEY_ENABLE_CURSOR_CONTROL, boolean.class));
+ sDeviceConfigEntries.add(new DeviceConfigEntry(
+ DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.INSERTION_HANDLE_DELTA_HEIGHT,
+ WidgetFlags.KEY_INSERTION_HANDLE_DELTA_HEIGHT, int.class));
+ sDeviceConfigEntries.add(new DeviceConfigEntry(
+ DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.INSERTION_HANDLE_OPACITY,
+ WidgetFlags.KEY_INSERTION_HANDLE_OPACITY, int.class));
+ sDeviceConfigEntries.add(new DeviceConfigEntry(
+ DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.ENABLE_NEW_MAGNIFIER,
+ WidgetFlags.KEY_ENABLE_NEW_MAGNIFIER, boolean.class));
+ sDeviceConfigEntries.add(new DeviceConfigEntry(
+ DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.MAGNIFIER_ZOOM_FACTOR,
+ WidgetFlags.KEY_MAGNIFIER_ZOOM_FACTOR, float.class));
+ sDeviceConfigEntries.add(new DeviceConfigEntry(
+ DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.MAGNIFIER_ASPECT_RATIO,
+ WidgetFlags.KEY_MAGNIFIER_ASPECT_RATIO, float.class));
// add other device configs here...
}