summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-05-31 08:57:07 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-05-31 08:57:07 +0000
commitbbbb2d8ff62fc6e0d573613d64a2ef8806961bf5 (patch)
tree46d8a822443cc77bbe94fada84a550a6f508d128
parentc4a2125180170bd11ea812cdcb464d77f0053e44 (diff)
parenta379689f66bcc431645ec7c87bbd35eb2f42732f (diff)
Merge "Separate thread for back panel" into main
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/util/Assert.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java130
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/concurrency/UiThreadContext.kt51
5 files changed, 179 insertions, 75 deletions
diff --git a/packages/SystemUI/customization/src/com/android/systemui/util/Assert.java b/packages/SystemUI/customization/src/com/android/systemui/util/Assert.java
index 165e9728b9d7..de9baa59b2b7 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/util/Assert.java
+++ b/packages/SystemUI/customization/src/com/android/systemui/util/Assert.java
@@ -79,6 +79,21 @@ public class Assert {
}
}
+ /**
+ * Asserts that the current thread is the same as the given thread, or that the current thread
+ * is the test thread.
+ * @param expected The looper we expected to be running on
+ */
+ public static void isCurrentThread(Looper expected) {
+ if (!expected.isCurrentThread()
+ && (sTestThread == null || sTestThread != Thread.currentThread())) {
+ throw new IllegalStateException("Called on wrong thread thread."
+ + " wanted " + expected.getThread().getName()
+ + " but instead got Thread.currentThread()="
+ + Thread.currentThread().getName());
+ }
+ }
+
public static void isNotMainThread() {
if (sMainLooper.isCurrentThread()
&& (sTestThread == null || sTestThread == Thread.currentThread())) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index b208434c3218..18358a79cbca 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -36,11 +36,12 @@ import androidx.dynamicanimation.animation.DynamicAnimation
import com.android.internal.jank.Cuj
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.util.LatencyTracker
-import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.NavigationEdgeBackPlugin
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.ViewController
+import com.android.systemui.util.concurrency.BackPanelUiThread
+import com.android.systemui.util.concurrency.UiThreadContext
import com.android.systemui.util.time.SystemClock
import java.io.PrintWriter
import javax.inject.Inject
@@ -84,11 +85,11 @@ internal constructor(
context: Context,
private val windowManager: WindowManager,
private val viewConfiguration: ViewConfiguration,
- @Main private val mainHandler: Handler,
+ private val mainHandler: Handler,
private val systemClock: SystemClock,
private val vibratorHelper: VibratorHelper,
private val configurationController: ConfigurationController,
- private val latencyTracker: LatencyTracker,
+ latencyTracker: LatencyTracker,
private val interactionJankMonitor: InteractionJankMonitor,
) : ViewController<BackPanel>(BackPanel(context, latencyTracker)), NavigationEdgeBackPlugin {
@@ -103,7 +104,7 @@ internal constructor(
constructor(
private val windowManager: WindowManager,
private val viewConfiguration: ViewConfiguration,
- @Main private val mainHandler: Handler,
+ @BackPanelUiThread private val uiThreadContext: UiThreadContext,
private val systemClock: SystemClock,
private val vibratorHelper: VibratorHelper,
private val configurationController: ConfigurationController,
@@ -112,20 +113,19 @@ internal constructor(
) {
/** Construct a [BackPanelController]. */
fun create(context: Context): BackPanelController {
- val backPanelController =
- BackPanelController(
+ uiThreadContext.isCurrentThread()
+ return BackPanelController(
context,
windowManager,
viewConfiguration,
- mainHandler,
+ uiThreadContext.handler,
systemClock,
vibratorHelper,
configurationController,
latencyTracker,
interactionJankMonitor
)
- backPanelController.init()
- return backPanelController
+ .also { it.init() }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index d0f8412c85b2..2dc09e5ab478 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -44,8 +44,6 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.input.InputManager;
import android.icu.text.SimpleDateFormat;
-import android.os.Handler;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -55,7 +53,6 @@ import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
-import android.view.Choreographer;
import android.view.ISystemGestureExclusionListener;
import android.view.IWindowManager;
import android.view.InputDevice;
@@ -75,7 +72,6 @@ import androidx.annotation.DimenRes;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.policy.GestureNavigationSettingsObserver;
import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.FalsingManager;
@@ -94,7 +90,8 @@ import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.phone.LightBarController;
-import com.android.systemui.util.Assert;
+import com.android.systemui.util.concurrency.BackPanelUiThread;
+import com.android.systemui.util.concurrency.UiThreadContext;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.desktopmode.DesktopMode;
import com.android.wm.shell.pip.Pip;
@@ -136,7 +133,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
public void onSystemGestureExclusionChanged(int displayId,
Region systemGestureExclusion, Region unrestrictedOrNull) {
if (displayId == mDisplayId) {
- mMainExecutor.execute(() -> {
+ mUiThreadContext.getExecutor().execute(() -> {
mExcludeRegion.set(systemGestureExclusion);
mUnrestrictedExcludeRegion.set(unrestrictedOrNull != null
? unrestrictedOrNull : systemGestureExclusion);
@@ -215,8 +212,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
private final Point mDisplaySize = new Point();
private final int mDisplayId;
- private final Executor mMainExecutor;
- private final Handler mMainHandler;
+ private final UiThreadContext mUiThreadContext;
private final Executor mBackgroundExecutor;
private final Rect mPipExcludedBounds = new Rect();
@@ -411,8 +407,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
OverviewProxyService overviewProxyService,
SysUiState sysUiState,
PluginManager pluginManager,
- @Main Executor executor,
- @Main Handler handler,
+ @BackPanelUiThread UiThreadContext uiThreadContext,
@Background Executor backgroundExecutor,
UserTracker userTracker,
NavigationModeController navigationModeController,
@@ -428,8 +423,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
Provider<LightBarController> lightBarControllerProvider) {
mContext = context;
mDisplayId = context.getDisplayId();
- mMainExecutor = executor;
- mMainHandler = handler;
+ mUiThreadContext = uiThreadContext;
mBackgroundExecutor = backgroundExecutor;
mUserTracker = userTracker;
mOverviewProxyService = overviewProxyService;
@@ -478,7 +472,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
ViewConfiguration.getLongPressTimeout());
mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver(
- mMainHandler, mContext, this::onNavigationSettingsChanged);
+ mUiThreadContext.getHandler(), mContext, this::onNavigationSettingsChanged);
updateCurrentUserResources();
}
@@ -564,13 +558,15 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mIsAttached = true;
mOverviewProxyService.addCallback(mQuickSwitchListener);
mSysUiState.addCallback(mSysUiStateCallback);
- mInputManager.registerInputDeviceListener(mInputDeviceListener, mMainHandler);
- int [] inputDevices = mInputManager.getInputDeviceIds();
+ mInputManager.registerInputDeviceListener(
+ mInputDeviceListener,
+ mUiThreadContext.getHandler());
+ int[] inputDevices = mInputManager.getInputDeviceIds();
for (int inputDeviceId : inputDevices) {
mInputDeviceListener.onInputDeviceAdded(inputDeviceId);
}
updateIsEnabled();
- mUserTracker.addCallback(mUserChangedCallback, mMainExecutor);
+ mUserTracker.addCallback(mUserChangedCallback, mUiThreadContext.getExecutor());
}
/**
@@ -617,6 +613,10 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
}
private void updateIsEnabled() {
+ mUiThreadContext.runWithScissors(this::updateIsEnabledInner);
+ }
+
+ private void updateIsEnabledInner() {
try {
Trace.beginSection("EdgeBackGestureHandler#updateIsEnabled");
@@ -661,12 +661,12 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
TaskStackChangeListeners.getInstance().registerTaskStackListener(
mTaskStackListener);
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
- mMainExecutor::execute, mOnPropertiesChangedListener);
+ mUiThreadContext.getExecutor()::execute, mOnPropertiesChangedListener);
mPipOptional.ifPresent(pip -> pip.setOnIsInPipStateChangedListener(
mOnIsInPipStateChangedListener));
mDesktopModeOptional.ifPresent(
dm -> dm.addDesktopGestureExclusionRegionListener(
- mDesktopCornersChangedListener, mMainExecutor));
+ mDesktopCornersChangedListener, mUiThreadContext.getExecutor()));
try {
mWindowManagerService.registerSystemGestureExclusionListener(
@@ -677,8 +677,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
// Register input event receiver
mInputMonitor = new InputMonitorCompat("edge-swipe", mDisplayId);
- mInputEventReceiver = mInputMonitor.getInputReceiver(Looper.getMainLooper(),
- Choreographer.getInstance(), this::onInputEvent);
+ mInputEventReceiver = mInputMonitor.getInputReceiver(mUiThreadContext.getLooper(),
+ mUiThreadContext.getChoreographer(), this::onInputEvent);
// Add a nav bar panel window
resetEdgeBackPlugin();
@@ -773,7 +773,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mUseMLModel = newState;
if (mUseMLModel) {
- Assert.isMainThread();
+ mUiThreadContext.isCurrentThread();
if (mMLModelIsLoading) {
Log.d(TAG, "Model tried to load while already loading.");
return;
@@ -804,12 +804,13 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
}
BackGestureTfClassifierProvider finalProvider = provider;
Map<String, Integer> finalVocab = vocab;
- mMainExecutor.execute(() -> onMLModelLoadFinished(finalProvider, finalVocab, threshold));
+ mUiThreadContext.getExecutor().execute(
+ () -> onMLModelLoadFinished(finalProvider, finalVocab, threshold));
}
private void onMLModelLoadFinished(BackGestureTfClassifierProvider provider,
Map<String, Integer> vocab, float threshold) {
- Assert.isMainThread();
+ mUiThreadContext.isCurrentThread();
mMLModelIsLoading = false;
if (!mUseMLModel) {
// This can happen if the user disables Gesture Nav while the model is loading.
@@ -1291,7 +1292,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
updateBackAnimationThresholds();
if (mLightBarControllerProvider.get() != null) {
mBackAnimation.setStatusBarCustomizer((appearance) -> {
- mMainExecutor.execute(() ->
+ mUiThreadContext.getExecutor().execute(() ->
mLightBarControllerProvider.get()
.customizeStatusBarAppearance(appearance));
});
@@ -1308,8 +1309,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
private final OverviewProxyService mOverviewProxyService;
private final SysUiState mSysUiState;
private final PluginManager mPluginManager;
- private final Executor mExecutor;
- private final Handler mHandler;
+ private final UiThreadContext mUiThreadContext;
private final Executor mBackgroundExecutor;
private final UserTracker mUserTracker;
private final NavigationModeController mNavigationModeController;
@@ -1327,29 +1327,27 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
@Inject
public Factory(OverviewProxyService overviewProxyService,
- SysUiState sysUiState,
- PluginManager pluginManager,
- @Main Executor executor,
- @Main Handler handler,
- @Background Executor backgroundExecutor,
- UserTracker userTracker,
- NavigationModeController navigationModeController,
- BackPanelController.Factory backPanelControllerFactory,
- ViewConfiguration viewConfiguration,
- WindowManager windowManager,
- IWindowManager windowManagerService,
- InputManager inputManager,
- Optional<Pip> pipOptional,
- Optional<DesktopMode> desktopModeOptional,
- FalsingManager falsingManager,
- Provider<BackGestureTfClassifierProvider>
- backGestureTfClassifierProviderProvider,
- Provider<LightBarController> lightBarControllerProvider) {
+ SysUiState sysUiState,
+ PluginManager pluginManager,
+ @BackPanelUiThread UiThreadContext uiThreadContext,
+ @Background Executor backgroundExecutor,
+ UserTracker userTracker,
+ NavigationModeController navigationModeController,
+ BackPanelController.Factory backPanelControllerFactory,
+ ViewConfiguration viewConfiguration,
+ WindowManager windowManager,
+ IWindowManager windowManagerService,
+ InputManager inputManager,
+ Optional<Pip> pipOptional,
+ Optional<DesktopMode> desktopModeOptional,
+ FalsingManager falsingManager,
+ Provider<BackGestureTfClassifierProvider>
+ backGestureTfClassifierProviderProvider,
+ Provider<LightBarController> lightBarControllerProvider) {
mOverviewProxyService = overviewProxyService;
mSysUiState = sysUiState;
mPluginManager = pluginManager;
- mExecutor = executor;
- mHandler = handler;
+ mUiThreadContext = uiThreadContext;
mBackgroundExecutor = backgroundExecutor;
mUserTracker = userTracker;
mNavigationModeController = navigationModeController;
@@ -1367,26 +1365,26 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
/** Construct a {@link EdgeBackGestureHandler}. */
public EdgeBackGestureHandler create(Context context) {
- return new EdgeBackGestureHandler(
- context,
- mOverviewProxyService,
- mSysUiState,
- mPluginManager,
- mExecutor,
- mHandler,
- mBackgroundExecutor,
- mUserTracker,
- mNavigationModeController,
- mBackPanelControllerFactory,
- mViewConfiguration,
- mWindowManager,
- mWindowManagerService,
- mInputManager,
- mPipOptional,
- mDesktopModeOptional,
- mFalsingManager,
- mBackGestureTfClassifierProviderProvider,
- mLightBarControllerProvider);
+ return mUiThreadContext.runWithScissors(
+ () -> new EdgeBackGestureHandler(
+ context,
+ mOverviewProxyService,
+ mSysUiState,
+ mPluginManager,
+ mUiThreadContext,
+ mBackgroundExecutor,
+ mUserTracker,
+ mNavigationModeController,
+ mBackPanelControllerFactory,
+ mViewConfiguration,
+ mWindowManager,
+ mWindowManagerService,
+ mInputManager,
+ mPipOptional,
+ mDesktopModeOptional,
+ mFalsingManager,
+ mBackGestureTfClassifierProviderProvider,
+ mLightBarControllerProvider));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.kt b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.kt
index 83e3428bb95f..a7abb6b5f1d3 100644
--- a/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.kt
@@ -19,6 +19,7 @@ import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.os.Process
+import android.view.Choreographer
import com.android.systemui.Dependency
import com.android.systemui.Flags
import com.android.systemui.dagger.SysUISingleton
@@ -31,6 +32,12 @@ import dagger.Module
import dagger.Provides
import java.util.concurrent.Executor
import javax.inject.Named
+import javax.inject.Qualifier
+
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class BackPanelUiThread
/** Dagger Module for classes found within the concurrent package. */
@Module
@@ -106,6 +113,39 @@ object SysUIConcurrencyModule {
return looper
}
+ @Provides
+ @SysUISingleton
+ @BackPanelUiThread
+ fun provideBackPanelUiThreadContext(
+ @Main mainLooper: Looper,
+ @Main mainHandler: Handler,
+ @Main mainExecutor: Executor
+ ): UiThreadContext {
+ return if (Flags.edgeBackGestureHandlerThread()) {
+ val thread =
+ HandlerThread("BackPanelUiThread", Process.THREAD_PRIORITY_DISPLAY).apply {
+ start()
+ looper.setSlowLogThresholdMs(
+ LONG_SLOW_DISPATCH_THRESHOLD,
+ LONG_SLOW_DELIVERY_THRESHOLD
+ )
+ }
+ UiThreadContext(
+ thread.looper,
+ thread.threadHandler,
+ thread.threadExecutor,
+ thread.threadHandler.runWithScissors { Choreographer.getInstance() }
+ )
+ } else {
+ UiThreadContext(
+ mainLooper,
+ mainHandler,
+ mainExecutor,
+ mainHandler.runWithScissors { Choreographer.getInstance() }
+ )
+ }
+ }
+
/**
* Background Handler.
*
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/UiThreadContext.kt b/packages/SystemUI/src/com/android/systemui/util/concurrency/UiThreadContext.kt
new file mode 100644
index 000000000000..8c8c686dddcc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/UiThreadContext.kt
@@ -0,0 +1,51 @@
+/*
+ * 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.systemui.util.concurrency
+
+import android.os.Handler
+import android.os.Looper
+import android.view.Choreographer
+import com.android.systemui.util.Assert
+import java.util.concurrent.Executor
+import java.util.concurrent.atomic.AtomicReference
+
+private const val DEFAULT_TIMEOUT = 150L
+
+class UiThreadContext(
+ val looper: Looper,
+ val handler: Handler,
+ val executor: Executor,
+ val choreographer: Choreographer
+) {
+ fun isCurrentThread() {
+ Assert.isCurrentThread(looper)
+ }
+
+ fun <T> runWithScissors(block: () -> T): T {
+ return handler.runWithScissors(block)
+ }
+
+ fun runWithScissors(block: Runnable) {
+ handler.runWithScissors(block, DEFAULT_TIMEOUT)
+ }
+}
+
+fun <T> Handler.runWithScissors(block: () -> T): T {
+ val returnedValue = AtomicReference<T>()
+ runWithScissors({ returnedValue.set(block()) }, DEFAULT_TIMEOUT)
+ return returnedValue.get()!!
+}