Separate "Keyboard" from "Language & input"
1. Separate "Keyboard" from "Language & input".
2. Use FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI to control the
different UI until Settings launches the new UI design.
Bug: 242680328
Test: local test
Change-Id: Id1ea6d3e3c2e6b83bc4b4d835c6b27e31311c530
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index f1c1191..7ed95bc 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -111,6 +111,8 @@
public static class SpellCheckersSettingsActivity extends SettingsActivity { /* empty */ }
public static class LocalePickerActivity extends SettingsActivity { /* empty */ }
public static class LanguageAndInputSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class LanguageSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class KeyboardSettingsActivity extends SettingsActivity { /* empty */ }
public static class UserDictionarySettingsActivity extends SettingsActivity { /* empty */ }
public static class DarkThemeSettingsActivity extends SettingsActivity { /* empty */ }
public static class DisplaySettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 5e17e0b..c6f64d6 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -115,11 +115,13 @@
import com.android.settings.gestures.SystemNavigationGestureSettings;
import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
+import com.android.settings.inputmethod.KeyboardSettings;
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
import com.android.settings.inputmethod.SpellCheckersSettings;
import com.android.settings.inputmethod.UserDictionaryList;
import com.android.settings.inputmethod.UserDictionarySettings;
import com.android.settings.language.LanguageAndInputSettings;
+import com.android.settings.language.LanguageSettings;
import com.android.settings.localepicker.LocaleListEditor;
import com.android.settings.location.LocationServices;
import com.android.settings.location.LocationSettings;
@@ -205,6 +207,8 @@
LocaleListEditor.class.getName(),
AvailableVirtualKeyboardFragment.class.getName(),
LanguageAndInputSettings.class.getName(),
+ LanguageSettings.class.getName(),
+ KeyboardSettings.class.getName(),
SpellCheckersSettings.class.getName(),
UserDictionaryList.class.getName(),
UserDictionarySettings.class.getName(),
@@ -383,6 +387,8 @@
Settings.LocationSettingsActivity.class.getName(),
// Home page > System
Settings.LanguageAndInputSettingsActivity.class.getName(),
+ Settings.LanguageSettingsActivity.class.getName(),
+ Settings.KeyboardSettingsActivity.class.getName(),
Settings.DateTimeSettingsActivity.class.getName(),
Settings.EnterprisePrivacySettingsActivity.class.getName(),
Settings.MyDeviceInfoActivity.class.getName(),
diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
index c2b5198..a2b1454 100644
--- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
+++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
@@ -101,6 +101,7 @@
SystemDashboardFragment.class.getName(), CategoryKey.CATEGORY_SYSTEM);
PARENT_TO_CATEGORY_KEY_MAP.put(LanguageAndInputSettings.class.getName(),
CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
+ // TODO(b/242680328) Tie new category key to LanguageSettings and KeyboardSettings page
PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettingsDashboardFragment.class.getName(),
CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
PARENT_TO_CATEGORY_KEY_MAP.put(ConfigureNotificationSettings.class.getName(),
diff --git a/src/com/android/settings/inputmethod/KeyboardPreferenceController.java b/src/com/android/settings/inputmethod/KeyboardPreferenceController.java
new file mode 100644
index 0000000..75351b1
--- /dev/null
+++ b/src/com/android/settings/inputmethod/KeyboardPreferenceController.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 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 com.android.settings.inputmethod;
+
+import android.content.Context;
+import android.hardware.input.InputManager;
+import android.util.FeatureFlagUtils;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.inputmethod.PhysicalKeyboardFragment.HardKeyboardDeviceInfo;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+
+import java.util.List;
+
+public class KeyboardPreferenceController extends BasePreferenceController
+ implements PreferenceControllerMixin, LifecycleObserver, OnResume, OnPause,
+ InputManager.InputDeviceListener {
+
+ private final InputManager mIm;
+
+ private Preference mPreference;
+
+ public KeyboardPreferenceController(Context context, String key) {
+ super(context, key);
+ mIm = context.getSystemService(InputManager.class);
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ updateSummary();
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ updateSummary();
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ updateSummary();
+ }
+
+ @Override
+ public void onPause() {
+ mIm.unregisterInputDeviceListener(this);
+ }
+
+ @Override
+ public void onResume() {
+ mIm.registerInputDeviceListener(this, null);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ mPreference = preference;
+ updateSummary();
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ boolean isFeatureOn = FeatureFlagUtils
+ .isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ return isFeatureOn ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+ }
+
+ private void updateSummary() {
+ final List<HardKeyboardDeviceInfo> keyboards =
+ PhysicalKeyboardFragment.getHardKeyboards(mContext);
+ if (keyboards.isEmpty()) {
+ mPreference.setSummary(R.string.keyboard_settings_summary);
+ } else {
+ mPreference.setSummary(R.string.keyboard_settings_with_physical_keyboard_summary);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/inputmethod/KeyboardSettings.java b/src/com/android/settings/inputmethod/KeyboardSettings.java
new file mode 100644
index 0000000..2d6ac88
--- /dev/null
+++ b/src/com/android/settings/inputmethod/KeyboardSettings.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2022 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 com.android.settings.inputmethod;
+
+import static android.app.admin.DevicePolicyResources.Strings.Settings.PERSONAL_DICTIONARY_FOR_WORK;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SPELL_CHECKER_FOR_WORK;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_KEYBOARDS_AND_TOOLS;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.FeatureFlagUtils;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.language.DefaultVoiceInputPreferenceController;
+import com.android.settings.language.PointerSpeedController;
+import com.android.settings.language.TtsPreferenceController;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.widget.PreferenceCategoryController;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@SearchIndexable
+public class KeyboardSettings extends DashboardFragment {
+
+ private static final String TAG = "KeyboardSettings";
+
+ private static final String KEY_KEYBOARDS_CATEGORY = "keyboards_category";
+ private static final String KEY_SPEECH_CATEGORY = "speech_category";
+ private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
+ private static final String KEY_POINTER_CATEGORY = "pointer_category";
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.SETTINGS_KEYBOARDS_CATEGORY;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ replaceEnterpriseStringTitle("language_and_input_for_work_category",
+ WORK_PROFILE_KEYBOARDS_AND_TOOLS,
+ R.string.language_and_input_for_work_category_title);
+ replaceEnterpriseStringTitle("spellcheckers_settings_for_work_pref",
+ SPELL_CHECKER_FOR_WORK,
+ R.string.spellcheckers_settings_for_work_title);
+ replaceEnterpriseStringTitle("user_dictionary_settings_for_work_pref",
+ PERSONAL_DICTIONARY_FOR_WORK,
+ R.string.user_dict_settings_for_work_title);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.keyboard_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getSettingsLifecycle());
+ }
+
+ private static List<AbstractPreferenceController> buildPreferenceControllers(
+ @NonNull Context context, @Nullable Lifecycle lifecycle) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ // Input
+ final VirtualKeyboardPreferenceController virtualKeyboardPreferenceController =
+ new VirtualKeyboardPreferenceController(context);
+ final PhysicalKeyboardPreferenceController physicalKeyboardPreferenceController =
+ new PhysicalKeyboardPreferenceController(context, lifecycle);
+ controllers.add(virtualKeyboardPreferenceController);
+ controllers.add(physicalKeyboardPreferenceController);
+ controllers.add(new PreferenceCategoryController(context,
+ KEY_KEYBOARDS_CATEGORY).setChildren(
+ Arrays.asList(virtualKeyboardPreferenceController,
+ physicalKeyboardPreferenceController)));
+
+ // Speech
+ final DefaultVoiceInputPreferenceController defaultVoiceInputPreferenceController =
+ new DefaultVoiceInputPreferenceController(context, lifecycle);
+ final TtsPreferenceController ttsPreferenceController =
+ new TtsPreferenceController(context, KEY_TEXT_TO_SPEECH);
+ controllers.add(defaultVoiceInputPreferenceController);
+ controllers.add(ttsPreferenceController);
+ controllers.add(new PreferenceCategoryController(context,
+ KEY_SPEECH_CATEGORY).setChildren(
+ Arrays.asList(defaultVoiceInputPreferenceController, ttsPreferenceController)));
+
+ // Pointer
+ final PointerSpeedController pointerController = new PointerSpeedController(context);
+ controllers.add(pointerController);
+ controllers.add(new PreferenceCategoryController(context,
+ KEY_POINTER_CATEGORY).setChildren(Arrays.asList(pointerController)));
+
+ // Input Assistance
+ controllers.add(new SpellCheckerPreferenceController(context));
+
+ return controllers;
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.keyboard_settings) {
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return FeatureFlagUtils
+ .isEnabled(context, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/com/android/settings/language/LanguageAndInputPreferenceController.java b/src/com/android/settings/language/LanguageAndInputPreferenceController.java
index 04bf622..691d907 100644
--- a/src/com/android/settings/language/LanguageAndInputPreferenceController.java
+++ b/src/com/android/settings/language/LanguageAndInputPreferenceController.java
@@ -21,6 +21,7 @@
import android.content.pm.PackageManager;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
@@ -41,7 +42,9 @@
@Override
public int getAvailabilityStatus() {
- return AVAILABLE;
+ boolean isFeatureOn = FeatureFlagUtils
+ .isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ return isFeatureOn ? CONDITIONALLY_UNAVAILABLE : AVAILABLE;
}
@Override
diff --git a/src/com/android/settings/language/LanguageAndInputSettings.java b/src/com/android/settings/language/LanguageAndInputSettings.java
index 2d80da5..f40473c 100644
--- a/src/com/android/settings/language/LanguageAndInputSettings.java
+++ b/src/com/android/settings/language/LanguageAndInputSettings.java
@@ -24,6 +24,7 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
+import android.util.FeatureFlagUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -104,8 +105,6 @@
private static List<AbstractPreferenceController> buildPreferenceControllers(
@NonNull Context context, @Nullable Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
- // Language
- controllers.add(new PhoneLanguagePreferenceController(context));
// Input
final VirtualKeyboardPreferenceController virtualKeyboardPreferenceController =
@@ -154,11 +153,16 @@
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.language_and_input) {
-
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
+
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return !FeatureFlagUtils
+ .isEnabled(context, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ }
};
}
diff --git a/src/com/android/settings/language/LanguagePreferenceController.java b/src/com/android/settings/language/LanguagePreferenceController.java
new file mode 100644
index 0000000..08033cd
--- /dev/null
+++ b/src/com/android/settings/language/LanguagePreferenceController.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 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 com.android.settings.language;
+
+import android.content.Context;
+import android.util.FeatureFlagUtils;
+
+import com.android.settings.core.BasePreferenceController;
+
+public class LanguagePreferenceController extends BasePreferenceController {
+
+ public LanguagePreferenceController(Context context, String key) {
+ super(context, key);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ boolean isFeatureOn = FeatureFlagUtils
+ .isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ return isFeatureOn ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/language/LanguageSettings.java b/src/com/android/settings/language/LanguageSettings.java
new file mode 100644
index 0000000..f814e36
--- /dev/null
+++ b/src/com/android/settings/language/LanguageSettings.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 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 com.android.settings.language;
+
+import android.app.Activity;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.util.FeatureFlagUtils;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+@SearchIndexable
+public class LanguageSettings extends DashboardFragment {
+
+ private static final String TAG = "LanguageSettings";
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.SETTINGS_LANGUAGES_CATEGORY;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // Hack to update action bar title. It's necessary to refresh title because this page user
+ // can change locale from here and fragment won't relaunch. Once language changes, title
+ // must display in the new language.
+ final Activity activity = getActivity();
+ if (activity == null) {
+ return;
+ }
+ activity.setTitle(R.string.languages_settings);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.language_settings;
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.language_settings) {
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return FeatureFlagUtils
+ .isEnabled(context, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/com/android/settings/language/PhoneLanguagePreferenceController.java b/src/com/android/settings/language/PhoneLanguagePreferenceController.java
index 4f67a8f..0d5aa37 100644
--- a/src/com/android/settings/language/PhoneLanguagePreferenceController.java
+++ b/src/com/android/settings/language/PhoneLanguagePreferenceController.java
@@ -16,33 +16,32 @@
package com.android.settings.language;
-import android.app.settings.SettingsEnums;
import android.content.Context;
import androidx.preference.Preference;
import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.localepicker.LocaleListEditor;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.AbstractPreferenceController;
import java.util.List;
-public class PhoneLanguagePreferenceController extends AbstractPreferenceController
+public class PhoneLanguagePreferenceController extends BasePreferenceController
implements PreferenceControllerMixin {
- private static final String KEY_PHONE_LANGUAGE = "phone_language";
-
- public PhoneLanguagePreferenceController(Context context) {
- super(context);
+ public PhoneLanguagePreferenceController(Context context, String key) {
+ super(context, key);
}
@Override
- public boolean isAvailable() {
- return mContext.getResources().getBoolean(R.bool.config_show_phone_language)
- && mContext.getAssets().getLocales().length > 1;
+ public int getAvailabilityStatus() {
+ if (mContext.getResources().getBoolean(R.bool.config_show_phone_language)
+ && mContext.getAssets().getLocales().length > 1) {
+ return AVAILABLE;
+ } else {
+ return CONDITIONALLY_UNAVAILABLE;
+ }
}
@Override
@@ -61,23 +60,4 @@
// make search page look like there are duplicate result, creating confusion.
keys.add(getPreferenceKey());
}
-
- @Override
- public String getPreferenceKey() {
- return KEY_PHONE_LANGUAGE;
- }
-
- @Override
- public boolean handlePreferenceTreeClick(Preference preference) {
- if (!KEY_PHONE_LANGUAGE.equals(preference.getKey())) {
- return false;
- }
- new SubSettingLauncher(mContext)
- .setDestination(LocaleListEditor.class.getName())
- .setSourceMetricsCategory(SettingsEnums.SETTINGS_LANGUAGE_CATEGORY)
- .setTitleRes(R.string.language_picker_title)
- .launch();
- return true;
- }
-
}