Loading core/java/android/app/ActivityThread.java +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading core/java/android/app/AppGlobals.java +16 −0 Original line number Diff line number Diff line Loading @@ -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; } } } core/java/android/widget/Editor.java +58 −15 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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"); } } Loading @@ -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()); Loading @@ -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) Loading Loading @@ -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); } Loading Loading @@ -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()); Loading Loading @@ -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. Loading @@ -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() { Loading Loading @@ -5292,6 +5324,17 @@ public class Editor { return super.getCursorHorizontalPosition(layout, offset); } @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) { Loading core/java/android/widget/WidgetFlags.java +60 −0 Original line number Diff line number Diff line Loading @@ -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() { } } services/core/java/com/android/server/am/CoreSettingsObserver.java +15 −0 Original line number Diff line number Diff line Loading @@ -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... } Loading Loading
core/java/android/app/ActivityThread.java +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/android/app/AppGlobals.java +16 −0 Original line number Diff line number Diff line Loading @@ -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; } } }
core/java/android/widget/Editor.java +58 −15 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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"); } } Loading @@ -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()); Loading @@ -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) Loading Loading @@ -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); } Loading Loading @@ -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()); Loading Loading @@ -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. Loading @@ -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() { Loading Loading @@ -5292,6 +5324,17 @@ public class Editor { return super.getCursorHorizontalPosition(layout, offset); } @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) { Loading
core/java/android/widget/WidgetFlags.java +60 −0 Original line number Diff line number Diff line Loading @@ -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() { } }
services/core/java/com/android/server/am/CoreSettingsObserver.java +15 −0 Original line number Diff line number Diff line Loading @@ -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... } Loading