Loading src/com/android/settings/inputmethod/TouchpadThreeFingerTapAppSelectionPreferenceController.java +63 −14 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.hardware.input.AppLaunchData.ComponentData; import android.hardware.input.InputGestureData; import android.hardware.input.InputManager; import android.hardware.input.InputSettings; import android.hardware.input.KeyGestureEvent; import android.net.Uri; import android.os.Handler; import android.os.Looper; Loading Loading @@ -80,24 +79,73 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceController extends Base @Nullable private PreferenceScreen mPreferenceScreen; private final LauncherApps.Callback mLauncherAppsCallback = new LauncherApps.Callback() { @Override public void onPackageRemoved(@Nullable String packageName, @Nullable UserHandle user) { if (packageName != null && isAppSelected(packageName)) { setGestureToDefault(); repopulateApps(); } } @Override public void onPackageAdded(@Nullable String packageName, @Nullable UserHandle user) {} @Override public void onPackageChanged(@Nullable String packageName, @Nullable UserHandle user) {} @Override public void onPackagesAvailable( @Nullable String[] packageNames, @Nullable UserHandle user, boolean replacing) {} @Override public void onPackagesUnavailable( @Nullable String[] packageNames, @Nullable UserHandle user, boolean replacing) { if (packageNames == null) { return; } for (String packageName : packageNames) { if (isAppSelected(packageName)) { setGestureToDefault(); repopulateApps(); } } } }; public TouchpadThreeFingerTapAppSelectionPreferenceController(@NonNull Context context, @NonNull String key) { super(context, key); mLauncherApps = context.getSystemService(LauncherApps.class); mInputManager = context.getSystemService(InputManager.class); mContentResolver = context.getContentResolver(); mLauncherApps.registerCallback(mLauncherAppsCallback); } @VisibleForTesting TouchpadThreeFingerTapAppSelectionPreferenceController(@NonNull Context context, @NonNull String key, LauncherApps launcherApps, InputManager inputManager, ContentObserver contentObserver) { @NonNull LauncherApps launcherApps, @NonNull InputManager inputManager, @NonNull ContentObserver contentObserver) { this(context, key); mLauncherApps = launcherApps; mInputManager = inputManager; mObserver = contentObserver; mLauncherApps.registerCallback(mLauncherAppsCallback); } private void setGestureToDefault() { mInputManager.removeAllCustomInputGestures(InputGestureData.Filter.TOUCHPAD); TouchpadThreeFingerTapUtils.setDefaultGestureType(mContentResolver); } private boolean isAppSelected(@NonNull String packageName) { if (TouchpadThreeFingerTapUtils.isGestureTypeLaunchApp(mContentResolver)) { ComponentName componentName = getSelectedAppComponent(); return componentName != null && packageName.equals(componentName.getPackageName()); } return false; } @Override Loading @@ -119,13 +167,15 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceController extends Base } private void updateAppListSelection() { int current = TouchpadThreeFingerTapUtils.getCurrentGestureType(mContentResolver); // When the current gesture state is not app launching, the key is set to null so that no // app Preference will be selected String matchingKey = current == KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION ? parsePreferenceKey() : null; String matchingKey = null; if (TouchpadThreeFingerTapUtils.isGestureTypeLaunchApp(mContentResolver)) { ComponentName componentName = getSelectedAppComponent(); if (componentName != null) { matchingKey = parsePreferenceKeyFromComponent(componentName); } } updateCheckStatus(matchingKey); } Loading @@ -145,15 +195,14 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceController extends Base } @Nullable private String parsePreferenceKey() { private ComponentName getSelectedAppComponent() { InputGestureData gestureData = mInputManager.getInputGesture(TouchpadThreeFingerTapUtils.TRIGGER); if (gestureData != null) { ComponentData componentData = (ComponentData) gestureData.getAction().appLaunchData(); if (componentData != null) { ComponentName component = new ComponentName( return new ComponentName( componentData.getPackageName(), componentData.getClassName()); return parsePreferenceKeyFromComponent(component); } } return null; Loading @@ -178,10 +227,10 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceController extends Base public void displayPreference(@NonNull PreferenceScreen screen) { super.displayPreference(screen); mPreferenceScreen = screen; populateApps(); repopulateApps(); } private void populateApps() { private void repopulateApps() { if (mPreferenceScreen == null) { return; } Loading src/com/android/settings/inputmethod/TouchpadThreeFingerTapUtils.java +23 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,10 @@ public final class TouchpadThreeFingerTapUtils { static final InputGestureData.Trigger TRIGGER = createTouchpadTrigger(TOUCHPAD_GESTURE_TYPE_THREE_FINGER_TAP); // Note that KEY_GESTURE_TYPE_UNSPECIFIED is the "mouse mid click" action static final Integer DEFAULT_GESTURE_TYPE = KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED; private static final Map<String, Integer> PREF_KEY_TO_GESTURE_TYPE = Map.ofEntries( Map.entry("launch_gemini", KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT), Map.entry("go_home", KeyGestureEvent.KEY_GESTURE_TYPE_HOME), Loading @@ -60,6 +64,15 @@ public final class TouchpadThreeFingerTapUtils { ActivityManager.getCurrentUser()); } /** * Return if KEY_GESTURE_TYPE_LAUNCH_APPLICATION is the cuurent the gesture type * @param resolver ContentResolver */ public static boolean isGestureTypeLaunchApp(@NonNull ContentResolver resolver) { return getCurrentGestureType(resolver) == KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION; } /** * @param prefKey Preference key for input_touchpad_three_finger_tap_action * @return the corresponding KeyGestureEvent of the given key, or KEY_GESTURE_TYPE_UNSPECIFIED Loading @@ -80,7 +93,16 @@ public final class TouchpadThreeFingerTapUtils { } /** * Set KEY_GESTURE_TYPE_LAUNCH_APPLICATION as the gesture type * Set KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED as the gesture type * @param resolver ContentResolver */ public static void setDefaultGestureType(@NonNull ContentResolver resolver) { Settings.System.putIntForUser( resolver, TARGET_ACTION, DEFAULT_GESTURE_TYPE, ActivityManager.getCurrentUser()); } /** * Set KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION as the gesture type * @param resolver ContentResolver */ public static void setLaunchAppAsGestureType(@NonNull ContentResolver resolver) { Loading tests/robotests/src/com/android/settings/inputmethod/TouchpadThreeFingerTapAppSelectionPreferenceControllerTest.java +41 −5 Original line number Diff line number Diff line Loading @@ -104,7 +104,8 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceControllerTest { private final Context mContext = RuntimeEnvironment.application; private ContentResolver mContentResolver; private TouchpadThreeFingerTapAppSelectionPreferenceController mController; private InputGestureData mCustomInputGesture = null; private InputGestureData mCustomInputGesture; private LauncherApps.Callback mLauncherAppsCallback; @Before public void setup() { Loading Loading @@ -185,7 +186,7 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceControllerTest { public void updateState_whenActionIsLaunchApp_correspondingAppChecked() { ArgumentCaptor<SelectorWithWidgetPreference> captor = capturePrefs(); setupLaunchingApp(/* matchingIndex = */ 1); setupAppSelection(/* matchingIndex = */ 1); mController.updateState(mMockPreferenceScreen); List<SelectorWithWidgetPreference> prefs = captor.getAllValues(); Loading @@ -212,8 +213,7 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceControllerTest { mController.onRadioButtonClicked(captor.getAllValues().get(clickingIndex)); // Settings key is updated int gesture = TouchpadThreeFingerTapUtils.getCurrentGestureType(mContentResolver); assertThat(gesture).isEqualTo(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION); assertTrue(TouchpadThreeFingerTapUtils.isGestureTypeLaunchApp(mContentResolver)); // InputManager gesture is updated assertThat(mCustomInputGesture).isNotNull(); Loading @@ -229,6 +229,42 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceControllerTest { assertThat(prefs.get(1).isChecked()).isFalse(); } @Test public void onPackageRemoved_isNotSelectedApp_doNothing() { ArgumentCaptor<LauncherApps.Callback> captor = ArgumentCaptor.forClass(LauncherApps.Callback.class); verify(mMockLauncherApps).registerCallback(captor.capture()); mLauncherAppsCallback = captor.getValue(); int selectedAppIndex = 0; setupAppSelection(/* matchingIndex = */ selectedAppIndex); mController.updateState(mMockPreferenceScreen); mLauncherAppsCallback.onPackageRemoved( TEST_PACKAGE_PREFIX + 1, UserHandle.CURRENT); assertTrue(TouchpadThreeFingerTapUtils.isGestureTypeLaunchApp(mContentResolver)); } @Test public void onPackageRemoved_isSelectedApp_setToDefaultGesture() { ArgumentCaptor<LauncherApps.Callback> captor = ArgumentCaptor.forClass(LauncherApps.Callback.class); verify(mMockLauncherApps).registerCallback(captor.capture()); mLauncherAppsCallback = captor.getValue(); int selectedAppIndex = 0; setupAppSelection(/* matchingIndex = */ selectedAppIndex); mController.updateState(mMockPreferenceScreen); mLauncherAppsCallback.onPackageRemoved( TEST_PACKAGE_PREFIX + selectedAppIndex, UserHandle.CURRENT); // Settings key is updated int gesture = TouchpadThreeFingerTapUtils.getCurrentGestureType(mContentResolver); assertThat(gesture).isEqualTo(TouchpadThreeFingerTapUtils.DEFAULT_GESTURE_TYPE); } private ArgumentCaptor<SelectorWithWidgetPreference> capturePrefs() { ArgumentCaptor<SelectorWithWidgetPreference> captor = ArgumentCaptor.forClass(SelectorWithWidgetPreference.class); Loading @@ -242,7 +278,7 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceControllerTest { return captor; } private void setupLaunchingApp(int matchingIndex) { private void setupAppSelection(int matchingIndex) { AppLaunchData appLaunchData = createLaunchDataForComponent( TEST_PACKAGE_PREFIX + matchingIndex, TEST_CLASS_PREFIX + matchingIndex); Loading Loading
src/com/android/settings/inputmethod/TouchpadThreeFingerTapAppSelectionPreferenceController.java +63 −14 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.hardware.input.AppLaunchData.ComponentData; import android.hardware.input.InputGestureData; import android.hardware.input.InputManager; import android.hardware.input.InputSettings; import android.hardware.input.KeyGestureEvent; import android.net.Uri; import android.os.Handler; import android.os.Looper; Loading Loading @@ -80,24 +79,73 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceController extends Base @Nullable private PreferenceScreen mPreferenceScreen; private final LauncherApps.Callback mLauncherAppsCallback = new LauncherApps.Callback() { @Override public void onPackageRemoved(@Nullable String packageName, @Nullable UserHandle user) { if (packageName != null && isAppSelected(packageName)) { setGestureToDefault(); repopulateApps(); } } @Override public void onPackageAdded(@Nullable String packageName, @Nullable UserHandle user) {} @Override public void onPackageChanged(@Nullable String packageName, @Nullable UserHandle user) {} @Override public void onPackagesAvailable( @Nullable String[] packageNames, @Nullable UserHandle user, boolean replacing) {} @Override public void onPackagesUnavailable( @Nullable String[] packageNames, @Nullable UserHandle user, boolean replacing) { if (packageNames == null) { return; } for (String packageName : packageNames) { if (isAppSelected(packageName)) { setGestureToDefault(); repopulateApps(); } } } }; public TouchpadThreeFingerTapAppSelectionPreferenceController(@NonNull Context context, @NonNull String key) { super(context, key); mLauncherApps = context.getSystemService(LauncherApps.class); mInputManager = context.getSystemService(InputManager.class); mContentResolver = context.getContentResolver(); mLauncherApps.registerCallback(mLauncherAppsCallback); } @VisibleForTesting TouchpadThreeFingerTapAppSelectionPreferenceController(@NonNull Context context, @NonNull String key, LauncherApps launcherApps, InputManager inputManager, ContentObserver contentObserver) { @NonNull LauncherApps launcherApps, @NonNull InputManager inputManager, @NonNull ContentObserver contentObserver) { this(context, key); mLauncherApps = launcherApps; mInputManager = inputManager; mObserver = contentObserver; mLauncherApps.registerCallback(mLauncherAppsCallback); } private void setGestureToDefault() { mInputManager.removeAllCustomInputGestures(InputGestureData.Filter.TOUCHPAD); TouchpadThreeFingerTapUtils.setDefaultGestureType(mContentResolver); } private boolean isAppSelected(@NonNull String packageName) { if (TouchpadThreeFingerTapUtils.isGestureTypeLaunchApp(mContentResolver)) { ComponentName componentName = getSelectedAppComponent(); return componentName != null && packageName.equals(componentName.getPackageName()); } return false; } @Override Loading @@ -119,13 +167,15 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceController extends Base } private void updateAppListSelection() { int current = TouchpadThreeFingerTapUtils.getCurrentGestureType(mContentResolver); // When the current gesture state is not app launching, the key is set to null so that no // app Preference will be selected String matchingKey = current == KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION ? parsePreferenceKey() : null; String matchingKey = null; if (TouchpadThreeFingerTapUtils.isGestureTypeLaunchApp(mContentResolver)) { ComponentName componentName = getSelectedAppComponent(); if (componentName != null) { matchingKey = parsePreferenceKeyFromComponent(componentName); } } updateCheckStatus(matchingKey); } Loading @@ -145,15 +195,14 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceController extends Base } @Nullable private String parsePreferenceKey() { private ComponentName getSelectedAppComponent() { InputGestureData gestureData = mInputManager.getInputGesture(TouchpadThreeFingerTapUtils.TRIGGER); if (gestureData != null) { ComponentData componentData = (ComponentData) gestureData.getAction().appLaunchData(); if (componentData != null) { ComponentName component = new ComponentName( return new ComponentName( componentData.getPackageName(), componentData.getClassName()); return parsePreferenceKeyFromComponent(component); } } return null; Loading @@ -178,10 +227,10 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceController extends Base public void displayPreference(@NonNull PreferenceScreen screen) { super.displayPreference(screen); mPreferenceScreen = screen; populateApps(); repopulateApps(); } private void populateApps() { private void repopulateApps() { if (mPreferenceScreen == null) { return; } Loading
src/com/android/settings/inputmethod/TouchpadThreeFingerTapUtils.java +23 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,10 @@ public final class TouchpadThreeFingerTapUtils { static final InputGestureData.Trigger TRIGGER = createTouchpadTrigger(TOUCHPAD_GESTURE_TYPE_THREE_FINGER_TAP); // Note that KEY_GESTURE_TYPE_UNSPECIFIED is the "mouse mid click" action static final Integer DEFAULT_GESTURE_TYPE = KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED; private static final Map<String, Integer> PREF_KEY_TO_GESTURE_TYPE = Map.ofEntries( Map.entry("launch_gemini", KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT), Map.entry("go_home", KeyGestureEvent.KEY_GESTURE_TYPE_HOME), Loading @@ -60,6 +64,15 @@ public final class TouchpadThreeFingerTapUtils { ActivityManager.getCurrentUser()); } /** * Return if KEY_GESTURE_TYPE_LAUNCH_APPLICATION is the cuurent the gesture type * @param resolver ContentResolver */ public static boolean isGestureTypeLaunchApp(@NonNull ContentResolver resolver) { return getCurrentGestureType(resolver) == KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION; } /** * @param prefKey Preference key for input_touchpad_three_finger_tap_action * @return the corresponding KeyGestureEvent of the given key, or KEY_GESTURE_TYPE_UNSPECIFIED Loading @@ -80,7 +93,16 @@ public final class TouchpadThreeFingerTapUtils { } /** * Set KEY_GESTURE_TYPE_LAUNCH_APPLICATION as the gesture type * Set KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED as the gesture type * @param resolver ContentResolver */ public static void setDefaultGestureType(@NonNull ContentResolver resolver) { Settings.System.putIntForUser( resolver, TARGET_ACTION, DEFAULT_GESTURE_TYPE, ActivityManager.getCurrentUser()); } /** * Set KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION as the gesture type * @param resolver ContentResolver */ public static void setLaunchAppAsGestureType(@NonNull ContentResolver resolver) { Loading
tests/robotests/src/com/android/settings/inputmethod/TouchpadThreeFingerTapAppSelectionPreferenceControllerTest.java +41 −5 Original line number Diff line number Diff line Loading @@ -104,7 +104,8 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceControllerTest { private final Context mContext = RuntimeEnvironment.application; private ContentResolver mContentResolver; private TouchpadThreeFingerTapAppSelectionPreferenceController mController; private InputGestureData mCustomInputGesture = null; private InputGestureData mCustomInputGesture; private LauncherApps.Callback mLauncherAppsCallback; @Before public void setup() { Loading Loading @@ -185,7 +186,7 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceControllerTest { public void updateState_whenActionIsLaunchApp_correspondingAppChecked() { ArgumentCaptor<SelectorWithWidgetPreference> captor = capturePrefs(); setupLaunchingApp(/* matchingIndex = */ 1); setupAppSelection(/* matchingIndex = */ 1); mController.updateState(mMockPreferenceScreen); List<SelectorWithWidgetPreference> prefs = captor.getAllValues(); Loading @@ -212,8 +213,7 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceControllerTest { mController.onRadioButtonClicked(captor.getAllValues().get(clickingIndex)); // Settings key is updated int gesture = TouchpadThreeFingerTapUtils.getCurrentGestureType(mContentResolver); assertThat(gesture).isEqualTo(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION); assertTrue(TouchpadThreeFingerTapUtils.isGestureTypeLaunchApp(mContentResolver)); // InputManager gesture is updated assertThat(mCustomInputGesture).isNotNull(); Loading @@ -229,6 +229,42 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceControllerTest { assertThat(prefs.get(1).isChecked()).isFalse(); } @Test public void onPackageRemoved_isNotSelectedApp_doNothing() { ArgumentCaptor<LauncherApps.Callback> captor = ArgumentCaptor.forClass(LauncherApps.Callback.class); verify(mMockLauncherApps).registerCallback(captor.capture()); mLauncherAppsCallback = captor.getValue(); int selectedAppIndex = 0; setupAppSelection(/* matchingIndex = */ selectedAppIndex); mController.updateState(mMockPreferenceScreen); mLauncherAppsCallback.onPackageRemoved( TEST_PACKAGE_PREFIX + 1, UserHandle.CURRENT); assertTrue(TouchpadThreeFingerTapUtils.isGestureTypeLaunchApp(mContentResolver)); } @Test public void onPackageRemoved_isSelectedApp_setToDefaultGesture() { ArgumentCaptor<LauncherApps.Callback> captor = ArgumentCaptor.forClass(LauncherApps.Callback.class); verify(mMockLauncherApps).registerCallback(captor.capture()); mLauncherAppsCallback = captor.getValue(); int selectedAppIndex = 0; setupAppSelection(/* matchingIndex = */ selectedAppIndex); mController.updateState(mMockPreferenceScreen); mLauncherAppsCallback.onPackageRemoved( TEST_PACKAGE_PREFIX + selectedAppIndex, UserHandle.CURRENT); // Settings key is updated int gesture = TouchpadThreeFingerTapUtils.getCurrentGestureType(mContentResolver); assertThat(gesture).isEqualTo(TouchpadThreeFingerTapUtils.DEFAULT_GESTURE_TYPE); } private ArgumentCaptor<SelectorWithWidgetPreference> capturePrefs() { ArgumentCaptor<SelectorWithWidgetPreference> captor = ArgumentCaptor.forClass(SelectorWithWidgetPreference.class); Loading @@ -242,7 +278,7 @@ public class TouchpadThreeFingerTapAppSelectionPreferenceControllerTest { return captor; } private void setupLaunchingApp(int matchingIndex) { private void setupAppSelection(int matchingIndex) { AppLaunchData appLaunchData = createLaunchDataForComponent( TEST_PACKAGE_PREFIX + matchingIndex, TEST_CLASS_PREFIX + matchingIndex); Loading