Merge "Moving trackpad device tracking to a separate class" into main

This commit is contained in:
Treehugger Robot
2024-12-30 09:52:58 -08:00
committed by Android (Google) Code Review
3 changed files with 84 additions and 86 deletions
@@ -217,7 +217,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
@Override
protected boolean isLauncherInitialized() {
return super.isLauncherInitialized() && TouchInteractionService.isInitialized();
return super.isLauncherInitialized() && SystemUiProxy.INSTANCE.get(mContext).isActive();
}
private void enableBlockingTimeout(
@@ -45,13 +45,11 @@ import android.content.IIntentSender;
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.InputEvent;
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.inputconsumers.ResetGestureInputConsumer;
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 com.android.wm.shell.startingsurface.IStartingWindow;
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 @@ public class TouchInteractionService extends Service {
tis.initInputMonitor("TISBinder#onInitialize()");
tis.preloadOverview(true /* fromInit */);
}));
sIsInitialized = true;
}
@BinderThread
@@ -504,72 +500,8 @@ public class TouchInteractionService extends Service {
}
}
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 @@ public class TouchInteractionService extends Service {
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 @@ public class TouchInteractionService extends Service {
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 @@ public class TouchInteractionService extends Service {
// 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 class TouchInteractionService extends Service {
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 @@ public class TouchInteractionService extends Service {
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);
@@ -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)
}