Merge "Reads "enable_cursor_control" device config flag in Editor."
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index b891af5..513e72f 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -21,6 +21,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.AppGlobals;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.app.RemoteAction;
@@ -384,6 +385,10 @@
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 final boolean mCursorControlEnabled;
+
Editor(TextView textView) {
mTextView = textView;
// Synchronize the filter list, which places the undo input filter at the end.
@@ -397,6 +402,13 @@
Magnifier.createBuilderWithOldMagnifierDefaults(mTextView).build();
mMagnifierAnimator = new MagnifierMotionAnimator(magnifier);
}
+
+ mCursorControlEnabled = AppGlobals.getIntCoreSetting(
+ WidgetFlags.KEY_ENABLE_CURSOR_CONTROL , 0) != 0;
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("Editor", "Cursor control is %s.",
+ mCursorControlEnabled ? "enabled" : "disabled");
+ }
}
ParcelableParcel saveInstanceState() {
diff --git a/core/java/android/widget/WidgetFlags.java b/core/java/android/widget/WidgetFlags.java
new file mode 100644
index 0000000..fa1e498d
--- /dev/null
+++ b/core/java/android/widget/WidgetFlags.java
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+package android.widget;
+
+/**
+ * Keeps the flags related to the Widget namespace in {@link DeviceConfig}.
+ *
+ * @hide
+ */
+public final class WidgetFlags {
+
+ /**
+ * Whether the cursor control feature set is enabled.
+ * TODO: Makes this flag key visible to webview/chrome.
+ */
+ public static final String ENABLE_CURSOR_CONTROL =
+ "CursorControlFeature__enable_cursor_control";
+
+ /**
+ * The key name used in app core settings for enable cursor control.
+ */
+ public static final String KEY_ENABLE_CURSOR_CONTROL = "widget__enable_cursor_control";
+
+ 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 aa8bc04..fa55701 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -16,15 +16,21 @@
package com.android.server.am;
+import android.app.ActivityThread;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
+import android.provider.DeviceConfig;
import android.provider.Settings;
+import android.widget.WidgetFlags;
import com.android.internal.annotations.VisibleForTesting;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
/**
@@ -36,6 +42,19 @@
final class CoreSettingsObserver extends ContentObserver {
private static final String LOG_TAG = CoreSettingsObserver.class.getSimpleName();
+ private static class DeviceConfigEntry {
+ String namespace;
+ String flag;
+ String coreSettingKey;
+ Class<?> type;
+ DeviceConfigEntry(String namespace, String flag, String coreSettingKey, Class<?> type) {
+ this.namespace = namespace;
+ this.flag = flag;
+ this.coreSettingKey = coreSettingKey;
+ this.type = type;
+ }
+ }
+
// mapping form property name to its type
@VisibleForTesting
static final Map<String, Class<?>> sSecureSettingToTypeMap = new HashMap<
@@ -46,6 +65,7 @@
@VisibleForTesting
static final Map<String, Class<?>> sGlobalSettingToTypeMap = new HashMap<
String, Class<?>>();
+ static final List<DeviceConfigEntry> sDeviceConfigEntries = new ArrayList<DeviceConfigEntry>();
static {
sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
sSecureSettingToTypeMap.put(Settings.Secure.MULTI_PRESS_TIMEOUT, int.class);
@@ -84,6 +104,11 @@
sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_BLACKLISTS, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, String.class);
// add other global settings here...
+
+ sDeviceConfigEntries.add(new DeviceConfigEntry(
+ DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.ENABLE_CURSOR_CONTROL,
+ WidgetFlags.KEY_ENABLE_CURSOR_CONTROL, boolean.class));
+ // add other device configs here...
}
private final Bundle mCoreSettings = new Bundle();
@@ -112,6 +137,7 @@
populateSettings(mCoreSettings, sSecureSettingToTypeMap);
populateSettings(mCoreSettings, sSystemSettingToTypeMap);
populateSettings(mCoreSettings, sGlobalSettingToTypeMap);
+ populateSettingsFromDeviceConfig();
mActivityManagerService.onCoreSettingsChange(mCoreSettings);
}
@@ -133,6 +159,16 @@
mActivityManagerService.mContext.getContentResolver().registerContentObserver(
uri, false, this);
}
+
+ HashSet<String> deviceConfigNamespaces = new HashSet<>();
+ for (DeviceConfigEntry entry : sDeviceConfigEntries) {
+ if (!deviceConfigNamespaces.contains(entry.namespace)) {
+ DeviceConfig.addOnPropertiesChangedListener(
+ entry.namespace, ActivityThread.currentApplication().getMainExecutor(),
+ (DeviceConfig.Properties prop) -> onChange(false));
+ deviceConfigNamespaces.add(entry.namespace);
+ }
+ }
}
@VisibleForTesting
@@ -164,4 +200,25 @@
}
}
}
+
+ private void populateSettingsFromDeviceConfig() {
+ for (DeviceConfigEntry entry : sDeviceConfigEntries) {
+ if (entry.type == String.class) {
+ mCoreSettings.putString(entry.coreSettingKey,
+ DeviceConfig.getString(entry.namespace, entry.flag, ""));
+ } else if (entry.type == int.class) {
+ mCoreSettings.putInt(entry.coreSettingKey,
+ DeviceConfig.getInt(entry.namespace, entry.flag, 0));
+ } else if (entry.type == float.class) {
+ mCoreSettings.putFloat(entry.coreSettingKey,
+ DeviceConfig.getFloat(entry.namespace, entry.flag, 0));
+ } else if (entry.type == long.class) {
+ mCoreSettings.putLong(entry.coreSettingKey,
+ DeviceConfig.getLong(entry.namespace, entry.flag, 0));
+ } else if (entry.type == boolean.class) {
+ mCoreSettings.putInt(entry.coreSettingKey,
+ DeviceConfig.getBoolean(entry.namespace, entry.flag, false) ? 1 : 0);
+ }
+ }
+ }
}