Merge "Small refactor to displayDecor listeners" into main

This commit is contained in:
Randy Pfohl
2025-03-20 13:31:08 -07:00
committed by Android (Google) Code Review
5 changed files with 115 additions and 28 deletions
@@ -17,8 +17,8 @@ package com.android.launcher3.taskbar;
import static android.content.Context.RECEIVER_EXPORTED;
import static android.content.Context.RECEIVER_NOT_EXPORTED;
import static android.content.pm.PackageManager.FEATURE_PC;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
import static android.content.pm.PackageManager.FEATURE_PC;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
@@ -82,6 +82,8 @@ import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.quickstep.AllAppsActionManager;
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.SystemDecorationChangeObserver;
import com.android.quickstep.SystemDecorationChangeObserver.DisplayDecorationListener;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.fallback.window.RecentsDisplayModel;
import com.android.quickstep.fallback.window.RecentsWindowFlags;
@@ -107,7 +109,7 @@ import java.util.StringJoiner;
/**
* Class to manage taskbar lifecycle
*/
public class TaskbarManager {
public class TaskbarManager implements DisplayDecorationListener {
private static final String TAG = "TaskbarManager";
private static final boolean DEBUG = false;
private static final int TASKBAR_DESTROY_DURATION = 100;
@@ -454,6 +456,8 @@ public class TaskbarManager {
.register(USER_SETUP_COMPLETE_URI, mOnSettingsChangeListener);
SettingsCache.INSTANCE.get(mPrimaryWindowContext)
.register(NAV_BAR_KIDS_MODE, mOnSettingsChangeListener);
SystemDecorationChangeObserver.getINSTANCE().get(mPrimaryWindowContext)
.registerDisplayDecorationListener(this);
mShutdownReceiver =
new SimpleBroadcastReceiver(
mPrimaryWindowContext, UI_HELPER_EXECUTOR, i -> destroyAllTaskbars());
@@ -957,6 +961,7 @@ public class TaskbarManager {
* Signal from SysUI indicating that a non-mirroring display was just connected to the
* primary device or a previously mirroring display is switched to extended mode.
*/
@Override
public void onDisplayAddSystemDecorations(int displayId) {
debugTaskbarManager("onDisplayAddSystemDecorations: ", displayId);
Display display = getDisplay(displayId);
@@ -1020,6 +1025,7 @@ public class TaskbarManager {
* Signal from SysUI indicating that a previously connected non-mirroring display was just
* removed from the primary device.
*/
@Override
public void onDisplayRemoved(int displayId) {
debugTaskbarManager("onDisplayRemoved: ", displayId);
if (!DesktopExperienceFlags.ENABLE_TASKBAR_CONNECTED_DISPLAYS.isTrue() || isDefaultDisplay(
@@ -1059,6 +1065,7 @@ public class TaskbarManager {
/**
* Signal from SysUI indicating that system decorations should be removed from the display.
*/
@Override
public void onDisplayRemoveSystemDecorations(int displayId) {
// The display mirroring starts. The handling logic is the same as when removing a
// display.
@@ -1102,6 +1109,8 @@ public class TaskbarManager {
.unregister(USER_SETUP_COMPLETE_URI, mOnSettingsChangeListener);
SettingsCache.INSTANCE.get(mPrimaryWindowContext)
.unregister(NAV_BAR_KIDS_MODE, mOnSettingsChangeListener);
SystemDecorationChangeObserver.getINSTANCE().get(mPrimaryWindowContext)
.unregisterDisplayDecorationListener(this);
debugPrimaryTaskbar("destroy: unregistering component callbacks");
removeAndUnregisterComponentCallbacks(getDefaultDisplayId());
mShutdownReceiver.unregisterReceiverSafely();
@@ -23,10 +23,13 @@ import android.util.SparseArray
import android.view.Display
import androidx.core.util.valueIterator
import com.android.quickstep.DisplayModel.DisplayResource
import com.android.quickstep.SystemDecorationChangeObserver.Companion.INSTANCE
import com.android.quickstep.SystemDecorationChangeObserver.DisplayDecorationListener
import java.io.PrintWriter
/** data model for managing resources with lifecycles that match that of the connected display */
abstract class DisplayModel<RESOURCE_TYPE : DisplayResource>(val context: Context) {
abstract class DisplayModel<RESOURCE_TYPE : DisplayResource>(val context: Context) :
DisplayDecorationListener {
companion object {
private const val TAG = "DisplayModel"
@@ -34,19 +37,20 @@ abstract class DisplayModel<RESOURCE_TYPE : DisplayResource>(val context: Contex
}
private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
private var systemDecorationChangeObserver: SystemDecorationChangeObserver? = null
protected val displayResourceArray = SparseArray<RESOURCE_TYPE>()
fun onDisplayAddSystemDecorations(displayId: Int) {
override fun onDisplayAddSystemDecorations(displayId: Int) {
if (DEBUG) Log.d(TAG, "onDisplayAdded: displayId=$displayId")
storeDisplayResource(displayId)
}
fun onDisplayRemoved(displayId: Int) {
override fun onDisplayRemoved(displayId: Int) {
if (DEBUG) Log.d(TAG, "onDisplayRemoved: displayId=$displayId")
deleteDisplayResource(displayId)
}
fun onDisplayRemoveSystemDecorations(displayId: Int) {
override fun onDisplayRemoveSystemDecorations(displayId: Int) {
if (DEBUG) Log.d(TAG, "onDisplayRemoveSystemDecorations: displayId=$displayId")
deleteDisplayResource(displayId)
}
@@ -54,12 +58,16 @@ abstract class DisplayModel<RESOURCE_TYPE : DisplayResource>(val context: Contex
protected abstract fun createDisplayResource(display: Display): RESOURCE_TYPE
protected fun initializeDisplays() {
systemDecorationChangeObserver = INSTANCE[context]
systemDecorationChangeObserver?.registerDisplayDecorationListener(this)
displayManager.displays
.filter { getDisplayResource(it.displayId) == null }
.forEach { storeDisplayResource(it.displayId) }
}
fun destroy() {
systemDecorationChangeObserver?.unregisterDisplayDecorationListener(this)
systemDecorationChangeObserver = null
displayResourceArray.valueIterator().forEach { displayResource ->
displayResource.cleanup()
}
@@ -0,0 +1,81 @@
/*
* Copyright (C) 2025 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
import android.content.Context
import android.util.Log
import com.android.launcher3.dagger.ApplicationContext
import com.android.launcher3.dagger.LauncherAppSingleton
import com.android.launcher3.util.DaggerSingletonObject
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
import com.android.quickstep.dagger.QuickstepBaseAppComponent
import javax.inject.Inject
@LauncherAppSingleton
class SystemDecorationChangeObserver @Inject constructor(@ApplicationContext context: Context) {
companion object {
private const val TAG = "SystemDecorationChangeObserver"
private const val DEBUG = false
@JvmStatic
val INSTANCE: DaggerSingletonObject<SystemDecorationChangeObserver> =
DaggerSingletonObject<SystemDecorationChangeObserver>(
QuickstepBaseAppComponent::getSystemDecorationChangeObserver
)
}
interface DisplayDecorationListener {
fun onDisplayAddSystemDecorations(displayId: Int)
fun onDisplayRemoved(displayId: Int)
fun onDisplayRemoveSystemDecorations(displayId: Int)
}
fun notifyAddSystemDecorations(displayId: Int) {
if (DEBUG) Log.d(TAG, "SystemDecorationAdded: $displayId")
for (listener in mDisplayDecorationListeners) {
MAIN_EXECUTOR.execute { listener.onDisplayAddSystemDecorations(displayId) }
}
}
fun notifyOnDisplayRemoved(displayId: Int) {
if (DEBUG) Log.d(TAG, "displayRemoved: $displayId")
for (listener in mDisplayDecorationListeners) {
MAIN_EXECUTOR.execute { listener.onDisplayRemoved(displayId) }
}
}
fun notifyDisplayRemoveSystemDecorations(displayId: Int) {
if (DEBUG) Log.d(TAG, "SystemDecorationRemoved: $displayId")
for (listener in mDisplayDecorationListeners) {
MAIN_EXECUTOR.execute { listener.onDisplayRemoveSystemDecorations(displayId) }
}
}
private val mDisplayDecorationListeners = ArrayList<DisplayDecorationListener>()
fun registerDisplayDecorationListener(listener: DisplayDecorationListener) {
if (DEBUG) Log.d(TAG, "registerDisplayDecorationListener")
mDisplayDecorationListeners.add(listener)
}
fun unregisterDisplayDecorationListener(listener: DisplayDecorationListener) {
if (DEBUG) Log.d(TAG, "unregisterDisplayDecorationListener")
mDisplayDecorationListeners.remove(listener)
}
}
@@ -314,32 +314,25 @@ public class TouchInteractionService extends Service {
@BinderThread
@Override
public void onDisplayAddSystemDecorations(int displayId) {
executeForTaskbarManager(taskbarManager ->
taskbarManager.onDisplayAddSystemDecorations(displayId));
executeForRecentsDisplayModel(displayModel ->
displayModel.onDisplayAddSystemDecorations(displayId));
executeForTouchInteractionService(tis ->
tis.mSystemDecorationChangeObserver.notifyAddSystemDecorations(displayId));
}
@BinderThread
@Override
public void onDisplayRemoved(int displayId) {
executeForTaskbarManager(taskbarManager ->
taskbarManager.onDisplayRemoved(displayId));
executeForTouchInteractionService(tis -> {
tis.mSystemDecorationChangeObserver.notifyOnDisplayRemoved(displayId);
tis.mDeviceState.clearSysUIStateFlagsForDisplay(displayId);
});
executeForRecentsDisplayModel(displayModel ->
displayModel.onDisplayRemoved(displayId));
}
@BinderThread
@Override
public void onDisplayRemoveSystemDecorations(int displayId) {
executeForTaskbarManager(taskbarManager ->
taskbarManager.onDisplayRemoveSystemDecorations(displayId));
executeForRecentsDisplayModel(displayModel ->
displayModel.onDisplayRemoveSystemDecorations(displayId));
executeForTouchInteractionService(tis -> {
tis.mSystemDecorationChangeObserver.notifyDisplayRemoveSystemDecorations(displayId);
});
}
@BinderThread
@@ -451,15 +444,6 @@ public class TouchInteractionService extends Service {
}));
}
private void executeForRecentsDisplayModel(
@NonNull Consumer<RecentsDisplayModel> recentsDisplayModelConsumer) {
MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> {
RecentsDisplayModel recentsDisplayModel = tis.mRecentsDisplayModel;
if (recentsDisplayModel == null) return;
recentsDisplayModelConsumer.accept(recentsDisplayModel);
}));
}
/**
* Returns the {@link TaskbarManager}.
* <p>
@@ -596,6 +580,8 @@ public class TouchInteractionService extends Service {
private RecentsDisplayModel mRecentsDisplayModel;
private SystemDecorationChangeObserver mSystemDecorationChangeObserver;
@Override
public void onCreate() {
super.onCreate();
@@ -607,6 +593,7 @@ public class TouchInteractionService extends Service {
mDeviceState = RecentsAnimationDeviceState.INSTANCE.get(this);
mRotationTouchHelper = RotationTouchHelper.INSTANCE.get(this);
mRecentsDisplayModel = RecentsDisplayModel.getINSTANCE().get(this);
mSystemDecorationChangeObserver = SystemDecorationChangeObserver.getINSTANCE().get(this);
mAllAppsActionManager = new AllAppsActionManager(
this, UI_HELPER_EXECUTOR, this::createAllAppsPendingIntent);
mTrackpadsConnected = new ActiveTrackpadList(this, () -> {
@@ -25,6 +25,7 @@ import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.RotationTouchHelper;
import com.android.quickstep.SimpleOrientationTouchTransformer;
import com.android.quickstep.SystemDecorationChangeObserver;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TopTaskTracker;
import com.android.quickstep.fallback.window.RecentsDisplayModel;
@@ -71,4 +72,5 @@ public interface QuickstepBaseAppComponent extends LauncherBaseAppComponent {
SimpleOrientationTouchTransformer getSimpleOrientationTouchTransformer();
SystemDecorationChangeObserver getSystemDecorationChangeObserver();
}