diff --git a/res/drawable-night/mouse_keys_click.xml b/res/drawable-night/mouse_keys_click.xml
new file mode 100644
index 00000000000..e5e8d5a486e
--- /dev/null
+++ b/res/drawable-night/mouse_keys_click.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable-night/mouse_keys_directional.xml b/res/drawable-night/mouse_keys_directional.xml
new file mode 100644
index 00000000000..fd49f1e33e8
--- /dev/null
+++ b/res/drawable-night/mouse_keys_directional.xml
@@ -0,0 +1,248 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable-night/mouse_keys_press_hold.xml b/res/drawable-night/mouse_keys_press_hold.xml
new file mode 100644
index 00000000000..eb8560255ff
--- /dev/null
+++ b/res/drawable-night/mouse_keys_press_hold.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable-night/mouse_keys_release.xml b/res/drawable-night/mouse_keys_release.xml
new file mode 100644
index 00000000000..4fb7c4ad26f
--- /dev/null
+++ b/res/drawable-night/mouse_keys_release.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable-night/mouse_keys_release2.xml b/res/drawable-night/mouse_keys_release2.xml
new file mode 100644
index 00000000000..e844bc9790c
--- /dev/null
+++ b/res/drawable-night/mouse_keys_release2.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable-night/mouse_keys_toggle_scroll.xml b/res/drawable-night/mouse_keys_toggle_scroll.xml
new file mode 100644
index 00000000000..3d6cbf3409a
--- /dev/null
+++ b/res/drawable-night/mouse_keys_toggle_scroll.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/mouse_keys_click.xml b/res/drawable/mouse_keys_click.xml
new file mode 100644
index 00000000000..2dd62389d41
--- /dev/null
+++ b/res/drawable/mouse_keys_click.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/mouse_keys_directional.xml b/res/drawable/mouse_keys_directional.xml
new file mode 100644
index 00000000000..ae79563447e
--- /dev/null
+++ b/res/drawable/mouse_keys_directional.xml
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/mouse_keys_press_hold.xml b/res/drawable/mouse_keys_press_hold.xml
new file mode 100644
index 00000000000..af20290c053
--- /dev/null
+++ b/res/drawable/mouse_keys_press_hold.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/mouse_keys_release.xml b/res/drawable/mouse_keys_release.xml
new file mode 100644
index 00000000000..232d5e721e8
--- /dev/null
+++ b/res/drawable/mouse_keys_release.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/mouse_keys_release2.xml b/res/drawable/mouse_keys_release2.xml
new file mode 100644
index 00000000000..88422cbd80e
--- /dev/null
+++ b/res/drawable/mouse_keys_release2.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/mouse_keys_toggle_scroll.xml b/res/drawable/mouse_keys_toggle_scroll.xml
new file mode 100644
index 00000000000..1a1a55084ac
--- /dev/null
+++ b/res/drawable/mouse_keys_toggle_scroll.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/mouse_keys_image_item.xml b/res/layout/mouse_keys_image_item.xml
new file mode 100644
index 00000000000..36b999201f3
--- /dev/null
+++ b/res/layout/mouse_keys_image_item.xml
@@ -0,0 +1,26 @@
+
+
+
+
diff --git a/res/layout/mouse_keys_image_list.xml b/res/layout/mouse_keys_image_list.xml
new file mode 100644
index 00000000000..f111736f085
--- /dev/null
+++ b/res/layout/mouse_keys_image_list.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b62df6081ee..65ce6eb5f11 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4546,6 +4546,8 @@
Press one key at a time for shortcuts instead of holding keys down together
Mouse keys
+
+ Use mouse keys
Use your keyboard to control the pointer
@@ -4556,6 +4558,21 @@
Swap left and right buttons
Use the left mouse button as your right
+
+ Mouse keys for %s
+
+ Use the \“%s\” keys to move the mouse pointer
+
+ Use the \“%s\” key to click the primary mouse button
+
+ Use the \“%s\” key to press & hold the primary mouse button
+
+ Use the \“%s\” key to release the primary mouse button
+
+ Use the \“%1$s\” key to toggle scroll mode. This will make the \“%2$s\” keys scroll the view top, down, left or right
+
+ Use the \“%s\” key to click the secondary mouse button
+
Keyboard shortcuts
diff --git a/res/xml/mouse_keys_main_page.xml b/res/xml/mouse_keys_main_page.xml
new file mode 100644
index 00000000000..d781b519e79
--- /dev/null
+++ b/res/xml/mouse_keys_main_page.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/xml/physical_keyboard_a11y_settings.xml b/res/xml/physical_keyboard_a11y_settings.xml
index 3bfe1993d5b..9d634c00195 100644
--- a/res/xml/physical_keyboard_a11y_settings.xml
+++ b/res/xml/physical_keyboard_a11y_settings.xml
@@ -44,14 +44,15 @@
android:title="@string/slow_keys"
android:defaultValue="false"
android:summary="@string/slow_keys_summary"
- settings:controller="com.android.settings.inputmethod.KeyboardAccessibilitySlowKeysController" />
+ settings:controller="com.android.settings.inputmethod.KeyboardAccessibilitySlowKeysController"/>
-
+ android:fragment="com.android.settings.inputmethod.MouseKeysMainPageFragment"
+ settings:controller="com.android.settings.inputmethod.KeyboardAccessibilityMouseKeysController"/>
diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java
index 57ae88a85f5..34f53c47dce 100644
--- a/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java
+++ b/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java
@@ -22,15 +22,23 @@ import android.net.Uri;
import android.provider.Settings;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleObserver;
import androidx.preference.PreferenceScreen;
-import androidx.preference.TwoStatePreference;
+
+import com.android.settingslib.PrimarySwitchPreference;
+import com.android.settingslib.widget.MainSwitchPreference;
public class KeyboardAccessibilityMouseKeysController extends
InputSettingPreferenceController implements
LifecycleObserver {
+ private static final String KEY_MOUSE_KEY = "accessibility_mouse_keys";
+ private static final String KEY_MOUSE_KEY_MAIN_PAGE = "mouse_keys_main_switch";
- private TwoStatePreference mTwoStatePreference;
+ @Nullable
+ private PrimarySwitchPreference mPrimaryPreference;
+ @Nullable
+ private MainSwitchPreference mMainSwitchPreference;
public KeyboardAccessibilityMouseKeysController(@NonNull Context context, @NonNull String key) {
super(context, key);
@@ -39,7 +47,11 @@ public class KeyboardAccessibilityMouseKeysController extends
@Override
public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen);
- mTwoStatePreference = screen.findPreference(getPreferenceKey());
+ if (KEY_MOUSE_KEY.equals(getPreferenceKey())) {
+ mPrimaryPreference = screen.findPreference(getPreferenceKey());
+ } else if (KEY_MOUSE_KEY_MAIN_PAGE.equals(getPreferenceKey())) {
+ mMainSwitchPreference = screen.findPreference(getPreferenceKey());
+ }
}
@Override
@@ -63,8 +75,11 @@ public class KeyboardAccessibilityMouseKeysController extends
@Override
protected void onInputSettingUpdated() {
- if (mTwoStatePreference != null) {
- mTwoStatePreference.setChecked(
+ if (mPrimaryPreference != null) {
+ mPrimaryPreference.setChecked(
+ InputSettings.isAccessibilityMouseKeysEnabled(mContext));
+ } else if (mMainSwitchPreference != null) {
+ mMainSwitchPreference.setChecked(
InputSettings.isAccessibilityMouseKeysEnabled(mContext));
}
}
diff --git a/src/com/android/settings/inputmethod/MouseKeysImageListAdapter.java b/src/com/android/settings/inputmethod/MouseKeysImageListAdapter.java
new file mode 100644
index 00000000000..65024b1b2cf
--- /dev/null
+++ b/src/com/android/settings/inputmethod/MouseKeysImageListAdapter.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2024 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.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settings.R;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+public class MouseKeysImageListAdapter extends
+ RecyclerView.Adapter {
+ private static final ImmutableList DRAWABLE_LIST = ImmutableList.of(
+ R.drawable.mouse_keys_directional, R.drawable.mouse_keys_click,
+ R.drawable.mouse_keys_press_hold, R.drawable.mouse_keys_release,
+ R.drawable.mouse_keys_toggle_scroll, R.drawable.mouse_keys_release2);
+ private static final ImmutableList DIRECTIONAL_CHAR_KEYCODE_LIST = ImmutableList.of(
+ KeyEvent.KEYCODE_7, KeyEvent.KEYCODE_8, KeyEvent.KEYCODE_9, KeyEvent.KEYCODE_U,
+ KeyEvent.KEYCODE_O, KeyEvent.KEYCODE_J, KeyEvent.KEYCODE_K, KeyEvent.KEYCODE_L
+ );
+ private static final int LEFT_CLICK_CHAR_KEYCODE =
+ KeyEvent.KEYCODE_I;
+ private static final int PRESS_HOLD_CHAR_KEYCODE =
+ KeyEvent.KEYCODE_M;
+ private static final int RELEASE_CHAR_KEYCODE =
+ KeyEvent.KEYCODE_COMMA;
+ private static final ImmutableList TOGGLE_SCROLL_CHAR_KEYCODE_LIST = ImmutableList.of(
+ KeyEvent.KEYCODE_PERIOD, KeyEvent.KEYCODE_8, KeyEvent.KEYCODE_K, KeyEvent.KEYCODE_O,
+ KeyEvent.KEYCODE_U
+ );
+ private static final int RIGHT_CLICK_CHAR_KEYCODE =
+ KeyEvent.KEYCODE_SLASH;
+ private final List mComposedSummaryList = new ArrayList<>();
+
+ public MouseKeysImageListAdapter(@NonNull Context context,
+ @Nullable InputDevice currentInputDevice) {
+ composeSummaryForImages(context, currentInputDevice);
+ }
+
+ @NonNull
+ @Override
+ public MouseKeyImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.mouse_keys_image_item, parent, false);
+ return new MouseKeyImageViewHolder(view, parent.getContext());
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull MouseKeyImageViewHolder holder, int position) {
+ ((MouseKeyImageViewHolder) holder).bindView(DRAWABLE_LIST.get(position),
+ mComposedSummaryList.get(position));
+ }
+
+ @Override
+ public int getItemCount() {
+ return DRAWABLE_LIST.size();
+ }
+
+ private void composeSummaryForImages(Context context,
+ @Nullable InputDevice currentInputDevice) {
+ if (currentInputDevice == null) {
+ return;
+ }
+ mComposedSummaryList.clear();
+ List directionalLabelList = DIRECTIONAL_CHAR_KEYCODE_LIST.stream().map(
+ (key) -> getDisplayLabel(currentInputDevice, key)).toList();
+ mComposedSummaryList.add(context.getString(R.string.mouse_keys_directional_summary,
+ String.join(",", directionalLabelList)));
+ String leftClickLabel = getDisplayLabel(currentInputDevice, LEFT_CLICK_CHAR_KEYCODE);
+ mComposedSummaryList.add(
+ context.getString(R.string.mouse_keys_click_summary, leftClickLabel));
+ String pressHoldLabel = getDisplayLabel(currentInputDevice, PRESS_HOLD_CHAR_KEYCODE);
+ mComposedSummaryList.add(
+ context.getString(R.string.mouse_keys_press_hold_summary, pressHoldLabel));
+ String releaseLabel = getDisplayLabel(currentInputDevice, RELEASE_CHAR_KEYCODE);
+ mComposedSummaryList.add(
+ context.getString(R.string.mouse_keys_release_summary, releaseLabel));
+ List toggleScrollLabelList = TOGGLE_SCROLL_CHAR_KEYCODE_LIST.stream().map(
+ (key) -> getDisplayLabel(currentInputDevice, key)).toList();
+ mComposedSummaryList.add(context.getString(R.string.mouse_keys_toggle_scroll_summary,
+ toggleScrollLabelList.getFirst(),
+ String.join(",", toggleScrollLabelList.subList(1, toggleScrollLabelList.size()))
+ ));
+ String rightClickLabel = getDisplayLabel(currentInputDevice, RIGHT_CLICK_CHAR_KEYCODE);
+ mComposedSummaryList.add(
+ context.getString(R.string.mouse_keys_release2_summary, rightClickLabel));
+ }
+
+ private String getDisplayLabel(InputDevice currentInputDevice, int keycode) {
+ return String.valueOf(currentInputDevice.getKeyCharacterMap().getDisplayLabel(
+ currentInputDevice.getKeyCodeForKeyLocation(keycode))).toLowerCase(Locale.ROOT);
+ }
+
+ public static class MouseKeyImageViewHolder extends RecyclerView.ViewHolder {
+ private final TextView mTextView;
+ private final Context mContext;
+
+ public MouseKeyImageViewHolder(View itemView, Context context) {
+ super(itemView);
+ mTextView = (TextView) itemView;
+ mContext = context;
+ }
+
+ void bindView(int drawableRes, String summary) {
+ mTextView.setText(summary);
+ mTextView.setCompoundDrawablesWithIntrinsicBounds(null,
+ mContext.getDrawable(drawableRes), null, null);
+ }
+ }
+}
diff --git a/src/com/android/settings/inputmethod/MouseKeysMainPageFragment.java b/src/com/android/settings/inputmethod/MouseKeysMainPageFragment.java
new file mode 100644
index 00000000000..dd9c1ddf62f
--- /dev/null
+++ b/src/com/android/settings/inputmethod/MouseKeysMainPageFragment.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2024 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 com.android.settings.inputmethod.PhysicalKeyboardFragment.getHardKeyboards;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.hardware.input.InputManager;
+import android.os.Bundle;
+import android.view.InputDevice;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.PreferenceScreen;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.internal.util.Preconditions;
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.keyboard.Flags;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.utils.ThreadUtils;
+import com.android.settingslib.widget.LayoutPreference;
+
+import java.util.List;
+
+@SearchIndexable
+public class MouseKeysMainPageFragment extends DashboardFragment
+ implements InputManager.InputDeviceListener {
+
+ private static final String TAG = "MouseKeysMainPageFragment";
+ private static final String KEY_MOUSE_KEY_LIST = "mouse_keys_list";
+
+ private InputManager mInputManager;
+ private LayoutPreference mMouseKeyImagesPreference;
+ @Nullable
+ private InputDevice mCurrentInputDevice;
+
+ @Override
+ public void onCreate(@NonNull Bundle bundle) {
+ super.onCreate(bundle);
+ mCurrentInputDevice = getInputDevice();
+ final PreferenceScreen screen = getPreferenceScreen();
+ mMouseKeyImagesPreference = screen.findPreference(KEY_MOUSE_KEY_LIST);
+ mInputManager = Preconditions.checkNotNull(getActivity()
+ .getSystemService(InputManager.class));
+ String title = mCurrentInputDevice == null ? getActivity().getString(R.string.mouse_keys)
+ : getActivity().getString(R.string.mouse_key_main_page_title,
+ mCurrentInputDevice.getName());
+ getActivity().setTitle(title);
+ configureImagesPreference();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ finishEarlyIfNeeded();
+ mInputManager.registerInputDeviceListener(this, null);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mInputManager.unregisterInputDeviceListener(this);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.PHYSICAL_KEYBOARD_A11Y;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.mouse_keys_main_page;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ finishEarlyIfNeeded();
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ finishEarlyIfNeeded();
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ finishEarlyIfNeeded();
+ }
+
+ private void finishEarlyIfNeeded() {
+ final Context context = getContext();
+ ThreadUtils.postOnBackgroundThread(() -> {
+ final List newHardKeyboards =
+ getHardKeyboards(context);
+ if (newHardKeyboards.isEmpty()) {
+ getActivity().finish();
+ }
+ });
+ }
+
+ private void configureImagesPreference() {
+ final RecyclerView recyclerView = mMouseKeyImagesPreference.findViewById(
+ R.id.mouse_keys_image_recycler_list);
+ recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
+ recyclerView.setAdapter(new MouseKeysImageListAdapter(getActivity(), mCurrentInputDevice));
+ }
+
+ /**
+ * Priority of picking input device:
+ * 1. internal keyboard(built-in keyboard)
+ * 2. first keyboard in the list
+ */
+ @Nullable
+ private InputDevice getInputDevice() {
+ InputDevice inputDevice = null;
+ for (int deviceId : InputDevice.getDeviceIds()) {
+ final InputDevice device = InputDevice.getDevice(deviceId);
+ if (device == null || device.isVirtual() || !device.isFullKeyboard()) {
+ continue;
+ }
+ if (inputDevice == null) {
+ inputDevice = device;
+ } else if (!device.isExternal()) {
+ inputDevice = device;
+ break;
+ }
+ }
+ return inputDevice;
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.mouse_keys_main_page) {
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return Flags.keyboardAndTouchpadA11yNewPageEnabled()
+ && !getHardKeyboards(context).isEmpty();
+ }
+ };
+}