Moving trackpad device tracking to a separate class
This would eventually lead to breaking apart TIS into smaller classes,
which can be injected using dagger.
This is needed to migrate DisplayController to dagger
Bug: 361850561
Test: Presubmit
Flag: EXEMPT dagger refactor
Change-Id: Ic15386136bf1705e76c08536cc0790f51e19ab73
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index a04ff2e..620e2b7 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -217,7 +217,7 @@
@Override
protected boolean isLauncherInitialized() {
- return super.isLauncherInitialized() && TouchInteractionService.isInitialized();
+ return super.isLauncherInitialized() && SystemUiProxy.INSTANCE.get(mContext).isActive();
}
private void enableBlockingTimeout(
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index f5cc518..9870ecf 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -45,13 +45,11 @@
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Region;
-import android.hardware.input.InputManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.os.SystemClock;
import android.os.Trace;
-import android.util.ArraySet;
import android.util.Log;
import android.view.Choreographer;
import android.view.InputDevice;
@@ -59,7 +57,6 @@
import android.view.MotionEvent;
import androidx.annotation.BinderThread;
-import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -98,6 +95,7 @@
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActiveGestureLog.CompoundString;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
+import com.android.quickstep.util.ActiveTrackpadList;
import com.android.quickstep.util.ContextualSearchInvoker;
import com.android.quickstep.util.ContextualSearchStateManager;
import com.android.quickstep.views.RecentsViewContainer;
@@ -124,7 +122,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
-import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -188,7 +185,6 @@
tis.initInputMonitor("TISBinder#onInitialize()");
tis.preloadOverview(true /* fromInit */);
}));
- sIsInitialized = true;
}
@BinderThread
@@ -504,72 +500,8 @@
}
}
- private final InputManager.InputDeviceListener mInputDeviceListener =
- new InputManager.InputDeviceListener() {
- @Override
- public void onInputDeviceAdded(int deviceId) {
- if (isTrackpadDevice(deviceId)) {
- // This updates internal TIS state so it needs to also run on the main
- // thread.
- MAIN_EXECUTOR.execute(() -> {
- boolean wasEmpty = mTrackpadsConnected.isEmpty();
- mTrackpadsConnected.add(deviceId);
- if (wasEmpty) {
- update();
- }
- });
- }
- }
-
- @Override
- public void onInputDeviceChanged(int deviceId) {
- }
-
- @Override
- public void onInputDeviceRemoved(int deviceId) {
- // This updates internal TIS state so it needs to also run on the main
- // thread.
- MAIN_EXECUTOR.execute(() -> {
- mTrackpadsConnected.remove(deviceId);
- if (mTrackpadsConnected.isEmpty()) {
- update();
- }
- });
- }
-
- @MainThread
- private void update() {
- if (mInputMonitorCompat != null && !mTrackpadsConnected.isEmpty()) {
- // Don't destroy and reinitialize input monitor due to trackpad
- // connecting when it's already set up.
- return;
- }
- initInputMonitor("onTrackpadConnected()");
- }
-
- private boolean isTrackpadDevice(int deviceId) {
- // This is a blocking binder call that should run on a bg thread.
- InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
- if (inputDevice == null) {
- return false;
- }
- return inputDevice.getSources() == (InputDevice.SOURCE_MOUSE
- | InputDevice.SOURCE_TOUCHPAD);
- }
- };
-
- private static boolean sConnected = false;
- private static boolean sIsInitialized = false;
private RotationTouchHelper mRotationTouchHelper;
- public static boolean isConnected() {
- return sConnected;
- }
-
- public static boolean isInitialized() {
- return sIsInitialized;
- }
-
private final AbsSwipeUpHandler.Factory mLauncherSwipeHandlerFactory =
this::createLauncherSwipeHandler;
private final AbsSwipeUpHandler.Factory mFallbackSwipeHandlerFactory =
@@ -618,8 +550,7 @@
private TaskbarManager mTaskbarManager;
private Function<GestureState, AnimatedFloat> mSwipeUpProxyProvider = i -> null;
private AllAppsActionManager mAllAppsActionManager;
- private InputManager mInputManager;
- private final Set<Integer> mTrackpadsConnected = new ArraySet<>();
+ private ActiveTrackpadList mTrackpadsConnected;
private NavigationMode mGestureStartNavMode = null;
@@ -638,13 +569,15 @@
mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
mAllAppsActionManager = new AllAppsActionManager(
this, UI_HELPER_EXECUTOR, this::createAllAppsPendingIntent);
- mInputManager = getSystemService(InputManager.class);
- mInputManager.registerInputDeviceListener(mInputDeviceListener,
- UI_HELPER_EXECUTOR.getHandler());
- int [] inputDevices = mInputManager.getInputDeviceIds();
- for (int inputDeviceId : inputDevices) {
- mInputDeviceListener.onInputDeviceAdded(inputDeviceId);
- }
+ mTrackpadsConnected = new ActiveTrackpadList(this, () -> {
+ if (mInputMonitorCompat != null && !mTrackpadsConnected.isEmpty()) {
+ // Don't destroy and reinitialize input monitor due to trackpad
+ // connecting when it's already set up.
+ return;
+ }
+ initInputMonitor("onTrackpadConnected()");
+ });
+
mDesktopVisibilityController = new DesktopVisibilityController(this);
mTaskbarManager = new TaskbarManager(
this, mAllAppsActionManager, mNavCallbacks, mDesktopVisibilityController);
@@ -656,8 +589,6 @@
// Call runOnUserUnlocked() before any other callbacks to ensure everything is initialized.
LockedUserState.get(this).runOnUserUnlocked(mUserUnlockedRunnable);
mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
- sConnected = true;
-
ScreenOnTracker.INSTANCE.get(this).addListener(mScreenOnListener);
}
@@ -793,7 +724,6 @@
public void onDestroy() {
Log.d(TAG, "onDestroy: user=" + getUserId()
+ " instance=" + System.identityHashCode(this));
- sIsInitialized = false;
if (LockedUserState.get(this).isUserUnlocked()) {
mInputConsumer.unregisterInputConsumer();
mOverviewComponentObserver.setHomeDisabled(false);
@@ -805,16 +735,13 @@
mAllAppsActionManager.onDestroy();
- mInputManager.unregisterInputDeviceListener(mInputDeviceListener);
- mTrackpadsConnected.clear();
-
+ mTrackpadsConnected.destroy();
mTaskbarManager.destroy();
if (mDesktopAppLaunchTransitionManager != null) {
mDesktopAppLaunchTransitionManager.unregisterTransitions();
}
mDesktopAppLaunchTransitionManager = null;
mDesktopVisibilityController.onDestroy();
- sConnected = false;
LockedUserState.get(this).removeOnUserUnlockedRunnable(mUserUnlockedRunnable);
ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener);
diff --git a/quickstep/src/com/android/quickstep/util/ActiveTrackpadList.kt b/quickstep/src/com/android/quickstep/util/ActiveTrackpadList.kt
new file mode 100644
index 0000000..63bd03d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/ActiveTrackpadList.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 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.quickstep.util
+
+import android.content.Context
+import android.hardware.input.InputManager
+import android.view.InputDevice
+import com.android.launcher3.util.Executors
+import com.android.launcher3.util.IntSet
+
+/** Utility class to maintain a list of actively connected trackpad devices */
+class ActiveTrackpadList(ctx: Context, private val updateCallback: Runnable) :
+ IntSet(), InputManager.InputDeviceListener {
+
+ private val inputManager = ctx.getSystemService(InputManager::class.java)!!
+
+ init {
+ inputManager.registerInputDeviceListener(this, Executors.UI_HELPER_EXECUTOR.handler)
+ inputManager.inputDeviceIds.forEach { deviceId -> onInputDeviceAdded(deviceId) }
+ }
+
+ override fun onInputDeviceAdded(deviceId: Int) {
+ if (isTrackpadDevice(deviceId)) {
+ // This updates internal TIS state so it needs to also run on the main
+ // thread.
+ Executors.MAIN_EXECUTOR.execute {
+ val wasEmpty = isEmpty
+ add(deviceId)
+ if (wasEmpty) update()
+ }
+ }
+ }
+
+ override fun onInputDeviceChanged(deviceId: Int) {}
+
+ override fun onInputDeviceRemoved(deviceId: Int) {
+ // This updates internal TIS state so it needs to also run on the main thread.
+ Executors.MAIN_EXECUTOR.execute {
+ remove(deviceId)
+ if (isEmpty) update()
+ }
+ }
+
+ private fun update() {
+ updateCallback.run()
+ }
+
+ fun destroy() {
+ inputManager.unregisterInputDeviceListener(this)
+ clear()
+ }
+
+ /** This is a blocking binder call that should run on a bg thread. */
+ private fun isTrackpadDevice(deviceId: Int) =
+ inputManager.getInputDevice(deviceId)?.sources ==
+ (InputDevice.SOURCE_MOUSE or InputDevice.SOURCE_TOUCHPAD)
+}