diff options
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 9 | ||||
| -rw-r--r-- | core/java/android/app/AppGlobals.java | 16 | ||||
| -rw-r--r-- | core/java/android/widget/Editor.java | 73 | ||||
| -rw-r--r-- | core/java/android/widget/WidgetFlags.java | 60 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/CoreSettingsObserver.java | 15 |
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... } |