Recreate DP for CD when displayInfo changes
- Only IDP is updated when displayInfo changes but DPs of CD don't. As a result taskbars on CD end up reusing the old config DPs. For example, when user changes display size, displayInfo updates but taskbars on CD continue using old DP resources. - So, update DP for CD when DisplayInfo changes. - Also added using supplied context with dpToPx for calculating radius for taskbar roundedness at the ends. Fix: 414933860 Test: m Flag: com.android.window.flags.enable_taskbar_connected_displays Change-Id: I7d8ed3c5ba69b755a58d3462a5da9ed7fd404198
This commit is contained in:
@@ -121,6 +121,7 @@ import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
/**
|
||||
* Class to manage taskbar lifecycle
|
||||
@@ -215,7 +216,7 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
// Mode upon getting transition callback from shell side. So, we make sure that if taskbar is
|
||||
// already in recreate process due to transition callback, don't recreate for
|
||||
// DisplayInfoChangeListener.
|
||||
private boolean mShouldIgnoreNextDesktopModeChangeFromDisplayController = false;
|
||||
private boolean mShouldIgnoreNextDesktopModeChangeFromDisplayControllerForPrimary = false;
|
||||
|
||||
private class RecreationListener implements DisplayController.DisplayInfoChangeListener {
|
||||
@Override
|
||||
@@ -235,27 +236,35 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
debugTaskbarManager("onDisplayInfoChanged: Taskbar pinning changed", displayId);
|
||||
}
|
||||
|
||||
// Use a helper to update DP (only for secondary displays) and then recreate taskbar.
|
||||
IntConsumer updateExternalDpAndRecreateTaskbar = displayIdToUpdate -> {
|
||||
// Don't update DP for primary display as IDP already takes care of this.
|
||||
createExternalDeviceProfile(displayIdToUpdate);
|
||||
recreateTaskbarForDisplay(displayIdToUpdate, /* duration= */ 0);
|
||||
};
|
||||
|
||||
if ((flags & (CHANGE_DENSITY | CHANGE_NAVIGATION_MODE | CHANGE_DESKTOP_MODE
|
||||
| CHANGE_TASKBAR_PINNING | CHANGE_SHOW_LOCKED_TASKBAR)) != 0) {
|
||||
|
||||
TaskbarActivityContext taskbarActivityContext = getCurrentActivityContext();
|
||||
TaskbarActivityContext taskbarActivityContext = getTaskbarForDisplay(displayId);
|
||||
if ((flags & CHANGE_SHOW_LOCKED_TASKBAR) != 0) {
|
||||
debugTaskbarManager("onDisplayInfoChanged: show locked taskbar changed!",
|
||||
displayId);
|
||||
recreateTaskbars();
|
||||
updateExternalDpAndRecreateTaskbar.accept(displayId);
|
||||
} else if ((flags & CHANGE_DESKTOP_MODE) != 0) {
|
||||
if (mShouldIgnoreNextDesktopModeChangeFromDisplayController) {
|
||||
mShouldIgnoreNextDesktopModeChangeFromDisplayController = false;
|
||||
if (displayId == mPrimaryDisplayId
|
||||
&& mShouldIgnoreNextDesktopModeChangeFromDisplayControllerForPrimary) {
|
||||
mShouldIgnoreNextDesktopModeChangeFromDisplayControllerForPrimary = false;
|
||||
return;
|
||||
}
|
||||
// Only Handles Special Exit Cases for Desktop Mode Taskbar Recreation.
|
||||
if (((flags & CHANGE_TASKBAR_PINNING) != 0) || (taskbarActivityContext != null
|
||||
&& !taskbarActivityContext.showLockedTaskbarOnHome()
|
||||
&& !taskbarActivityContext.showDesktopTaskbarForFreeformDisplay())) {
|
||||
recreateTaskbars();
|
||||
updateExternalDpAndRecreateTaskbar.accept(displayId);
|
||||
}
|
||||
} else {
|
||||
recreateTaskbars();
|
||||
updateExternalDpAndRecreateTaskbar.accept(displayId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,44 +348,31 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
LatencyTracker.getInstance(mBaseContext).onActionStart(
|
||||
LatencyTracker.ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE);
|
||||
}
|
||||
for (Entry<Integer, TaskbarActivityContext> entry : mTaskbars.entrySet()) {
|
||||
int displayId = entry.getKey();
|
||||
if (isExternalDisplay(displayId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TaskbarActivityContext taskbarActivityContext = entry.getValue();
|
||||
if (taskbarActivityContext != null
|
||||
&& !taskbarActivityContext.isInOverview()
|
||||
&& !taskbarActivityContext.showDesktopTaskbarForFreeformDisplay()) {
|
||||
mShouldIgnoreNextDesktopModeChangeFromDisplayController = true;
|
||||
AnimatorSet animatorSet = taskbarActivityContext.onDestroyAnimation(
|
||||
TASKBAR_DESTROY_DURATION);
|
||||
animatorSet.addListener(AnimatorListeners.forEndCallback(
|
||||
() -> recreateTaskbarForDisplay(mPrimaryDisplayId, duration)));
|
||||
animatorSet.start();
|
||||
}
|
||||
TaskbarActivityContext taskbarActivityContext = getCurrentActivityContext();
|
||||
if (taskbarActivityContext != null
|
||||
&& !taskbarActivityContext.isInOverview()
|
||||
&& !taskbarActivityContext.showDesktopTaskbarForFreeformDisplay()) {
|
||||
mShouldIgnoreNextDesktopModeChangeFromDisplayControllerForPrimary = true;
|
||||
AnimatorSet animatorSet = taskbarActivityContext.onDestroyAnimation(
|
||||
TASKBAR_DESTROY_DURATION);
|
||||
animatorSet.addListener(AnimatorListeners.forEndCallback(
|
||||
() -> recreateTaskbarForDisplay(mPrimaryDisplayId, duration)));
|
||||
animatorSet.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterDesktopMode(int duration) {
|
||||
for (Entry<Integer, TaskbarActivityContext> entry : mTaskbars.entrySet()) {
|
||||
int displayId = entry.getKey();
|
||||
if (isExternalDisplay(displayId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TaskbarActivityContext taskbarActivityContext = entry.getValue();
|
||||
if (taskbarActivityContext != null
|
||||
&& !taskbarActivityContext.showDesktopTaskbarForFreeformDisplay()) {
|
||||
mShouldIgnoreNextDesktopModeChangeFromDisplayController = true;
|
||||
AnimatorSet animatorSet = taskbarActivityContext.onDestroyAnimation(
|
||||
TASKBAR_DESTROY_DURATION);
|
||||
animatorSet.addListener(AnimatorListeners.forEndCallback(
|
||||
() -> recreateTaskbarForDisplay(mPrimaryDisplayId, duration)));
|
||||
animatorSet.start();
|
||||
}
|
||||
TaskbarActivityContext taskbarActivityContext = getCurrentActivityContext();
|
||||
if (taskbarActivityContext != null
|
||||
&& !taskbarActivityContext.showDesktopTaskbarForFreeformDisplay()) {
|
||||
mShouldIgnoreNextDesktopModeChangeFromDisplayControllerForPrimary = true;
|
||||
AnimatorSet animatorSet = taskbarActivityContext.onDestroyAnimation(
|
||||
TASKBAR_DESTROY_DURATION);
|
||||
animatorSet.addListener(AnimatorListeners.forEndCallback(
|
||||
() -> recreateTaskbarForDisplay(mPrimaryDisplayId, duration)));
|
||||
animatorSet.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,14 +636,14 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
public void onUserUnlocked() {
|
||||
debugPrimaryTaskbar("onUserUnlocked");
|
||||
mUserUnlocked = true;
|
||||
DisplayController.INSTANCE.get(mPrimaryWindowContext).addChangeListener(
|
||||
mRecreationListener);
|
||||
addRecreationListener(mPrimaryDisplayId);
|
||||
debugPrimaryTaskbar("onUserUnlocked: recreating all taskbars!");
|
||||
// Create DPs for all connected displays if required.
|
||||
for (int i = 0; i < mWindowContexts.size(); i++) {
|
||||
int displayId = mWindowContexts.keyAt(i);
|
||||
if (displayId != mPrimaryDisplayId && !mExternalDeviceProfiles.contains(displayId)) {
|
||||
createExternalDeviceProfile(displayId);
|
||||
addRecreationListener(displayId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -783,7 +779,8 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
* we fully want to destroy an existing taskbar for a specified display and create a new one.
|
||||
* In other case (folding/unfolding) we don't need to remove and add window.
|
||||
*/
|
||||
private void recreateTaskbarForDisplay(int displayId, int duration) {
|
||||
@VisibleForTesting
|
||||
protected void recreateTaskbarForDisplay(int displayId, int duration) {
|
||||
debugTaskbarManager("recreateTaskbarForDisplay: ", displayId);
|
||||
Trace.beginSection("recreateTaskbarForDisplay");
|
||||
try {
|
||||
@@ -1061,6 +1058,11 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
"onDisplayAddSystemDecorations: createAndRegisterComponentCallbacks!",
|
||||
displayId);
|
||||
createAndRegisterComponentCallbacks(displayId);
|
||||
|
||||
debugTaskbarManager(
|
||||
"onDisplayAddSystemDecorations: addRecreationListener!", displayId);
|
||||
addRecreationListener(displayId);
|
||||
|
||||
debugTaskbarManager("onDisplayAddSystemDecorations: recreateTaskbarForDisplay!",
|
||||
displayId);
|
||||
recreateTaskbarForDisplay(displayId, 0);
|
||||
@@ -1095,6 +1097,9 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
displayId);
|
||||
removeAndUnregisterComponentCallbacks(displayId);
|
||||
|
||||
debugTaskbarManager("onDisplayRemoved: removeRecreationListener!", displayId);
|
||||
removeRecreationListener(displayId);
|
||||
|
||||
debugTaskbarManager("onDisplayRemoved: removing DeviceProfile from map!", displayId);
|
||||
removeDeviceProfileFromMap(displayId);
|
||||
|
||||
@@ -1152,10 +1157,7 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
mGrowthBroadcastReceiver.unregisterReceiverSafely();
|
||||
}
|
||||
|
||||
if (mUserUnlocked) {
|
||||
DisplayController.INSTANCE.get(mPrimaryWindowContext).removeChangeListener(
|
||||
mRecreationListener);
|
||||
}
|
||||
removeRecreationListener(mPrimaryDisplayId);
|
||||
SettingsCache.INSTANCE.get(mPrimaryWindowContext)
|
||||
.unregister(USER_SETUP_COMPLETE_URI, mOnSettingsChangeListener);
|
||||
SettingsCache.INSTANCE.get(mPrimaryWindowContext)
|
||||
@@ -1384,7 +1386,7 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
* @param displayId The ID of the display.
|
||||
*/
|
||||
private void createExternalDeviceProfile(int displayId) {
|
||||
if (!mUserUnlocked) {
|
||||
if (!mUserUnlocked || displayId == mPrimaryDisplayId) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1434,6 +1436,24 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
mExternalDeviceProfiles.delete(displayId);
|
||||
}
|
||||
|
||||
private void addRecreationListener(int displayId) {
|
||||
if (!mUserUnlocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayController.INSTANCE.get(mPrimaryWindowContext).addChangeListenerForDisplay(
|
||||
mRecreationListener, displayId);
|
||||
}
|
||||
|
||||
private void removeRecreationListener(int displayId) {
|
||||
if (!mUserUnlocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayController.INSTANCE.get(mPrimaryWindowContext).removeChangeListenerForDisplay(
|
||||
mRecreationListener, displayId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@link ComponentCallbacks} for the given display and register it to the relevant
|
||||
* WindowContext. For external displays, populate maps.
|
||||
@@ -1467,16 +1487,17 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
|
||||
debugTaskbarManager("onConfigurationChanged: | configDiff="
|
||||
+ Configuration.configurationDiffToString(configDiff), displayId);
|
||||
if (configDiff != 0 || getCurrentActivityContext() == null) {
|
||||
TaskbarActivityContext taskbar = getTaskbarForDisplay(displayId);
|
||||
if (configDiff != 0 || taskbar == null) {
|
||||
debugTaskbarManager("onConfigurationChanged: call recreateTaskbars", displayId);
|
||||
recreateTaskbars();
|
||||
recreateTaskbarForDisplay(displayId, /* duration= */ 0);
|
||||
} else if (dp != null) {
|
||||
// Config change might be handled without re-creating the taskbar
|
||||
if (!isTaskbarEnabled(dp)) {
|
||||
debugPrimaryTaskbar(
|
||||
"onConfigurationChanged: isTaskbarEnabled(dp)=False | "
|
||||
+ "destroyTaskbarForDisplay");
|
||||
destroyTaskbarForDisplay(mPrimaryDisplayId);
|
||||
destroyTaskbarForDisplay(displayId);
|
||||
} else {
|
||||
debugPrimaryTaskbar("onConfigurationChanged: isTaskbarEnabled(dp)=True");
|
||||
if (ENABLE_TASKBAR_NAVBAR_UNIFICATION) {
|
||||
@@ -1484,16 +1505,16 @@ public class TaskbarManagerImpl implements DisplayDecorationListener {
|
||||
// by looking at screen-size change flag in configDiff in the
|
||||
// block above?
|
||||
debugPrimaryTaskbar("onConfigurationChanged: call recreateTaskbars");
|
||||
recreateTaskbars();
|
||||
recreateTaskbarForDisplay(displayId, /* duration= */ 0);
|
||||
} else {
|
||||
debugPrimaryTaskbar(
|
||||
"onConfigurationChanged: updateDeviceProfile for current "
|
||||
+ "taskbar.");
|
||||
getCurrentActivityContext().updateDeviceProfile(dp);
|
||||
taskbar.updateDeviceProfile(dp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
getCurrentActivityContext().onConfigurationChanged(configDiff);
|
||||
taskbar.onConfigurationChanged(configDiff);
|
||||
}
|
||||
mOldConfig = new Configuration(newConfig);
|
||||
// reset taskbar was pinned value, so we don't automatically unstash taskbar upon
|
||||
|
||||
@@ -57,6 +57,7 @@ public final class Utilities {
|
||||
ThemeManager.INSTANCE.get(activityContext).getIconState().getShapeRadius();
|
||||
float iconSizeRatio = taskbarIconSize / maxIconSize;
|
||||
return dpToPx((iconShapeRadius * iconSizeRatio)
|
||||
+ TaskbarIconSpecs.INSTANCE.getDefaultTransientIconMargin().getSize());
|
||||
+ TaskbarIconSpecs.INSTANCE.getDefaultTransientIconMargin().getSize(),
|
||||
activityContext);
|
||||
}
|
||||
}
|
||||
|
||||
+26
-1
@@ -17,9 +17,11 @@
|
||||
package com.android.launcher3.taskbar
|
||||
|
||||
import android.animation.AnimatorTestRule
|
||||
import android.platform.test.annotations.DisableFlags
|
||||
import android.platform.test.annotations.EnableFlags
|
||||
import android.platform.test.flag.junit.SetFlagsRule
|
||||
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
||||
import com.android.launcher3.Flags
|
||||
import com.android.launcher3.LauncherPrefs
|
||||
import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING
|
||||
import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING_IN_DESKTOP_MODE
|
||||
@@ -53,6 +55,7 @@ import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule
|
||||
import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.InjectController
|
||||
import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.UserSetupMode
|
||||
import com.android.launcher3.taskbar.rules.TaskbarWindowSandboxContext
|
||||
import com.android.launcher3.taskbar.rules.displayControllerSpy
|
||||
import com.android.launcher3.util.LauncherMultivalentJUnit
|
||||
import com.android.launcher3.util.LauncherMultivalentJUnit.EmulatedDevices
|
||||
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED
|
||||
@@ -64,6 +67,8 @@ import org.junit.After
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
@RunWith(LauncherMultivalentJUnit::class)
|
||||
@@ -125,7 +130,27 @@ class TaskbarStashControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRecreateAsTransient_timeoutStarted() {
|
||||
@DisableFlags(Flags.FLAG_ENABLE_OVERVIEW_ON_CONNECTED_DISPLAYS)
|
||||
fun testRecreateAsTransient_withoutOverviewOnConnectedDisplays_timeoutStarted() {
|
||||
context.displayControllerSpy?.setupTaskbarPinningPrefListener(context.displayId)
|
||||
|
||||
testRecreateAsTransient_timeoutStarted()
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_OVERVIEW_ON_CONNECTED_DISPLAYS)
|
||||
fun testRecreateAsTransient_withOverviewOnConnectedDisplay_timeoutStarted() {
|
||||
context.displayControllerSpy?.let { controller ->
|
||||
controller.setupTaskbarPinningPrefListener(context.displayId)
|
||||
controller.infoModifierForDisplay = {
|
||||
spy(it) { on { it?.isTransientTaskbar } doReturn true }
|
||||
}
|
||||
}
|
||||
|
||||
testRecreateAsTransient_timeoutStarted()
|
||||
}
|
||||
|
||||
private fun testRecreateAsTransient_timeoutStarted() {
|
||||
var isPinned by TASKBAR_PINNING.asProperty(context)
|
||||
isPinned = true
|
||||
activityContext.controllers.sharedState?.taskbarWasPinned = true
|
||||
|
||||
+43
-1
@@ -18,7 +18,10 @@ package com.android.launcher3.taskbar.rules
|
||||
|
||||
import android.content.Context
|
||||
import com.android.app.displaylib.PerDisplayRepository
|
||||
import com.android.launcher3.Flags
|
||||
import com.android.launcher3.LauncherPrefChangeListener
|
||||
import com.android.launcher3.LauncherPrefs
|
||||
import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING
|
||||
import com.android.launcher3.concurrent.ExecutorsModule
|
||||
import com.android.launcher3.dagger.ApiWrapperModule
|
||||
import com.android.launcher3.dagger.AppModule
|
||||
@@ -99,15 +102,54 @@ class DisplayControllerSpy
|
||||
constructor(
|
||||
@ApplicationContext context: Context,
|
||||
wmProxy: WindowManagerProxy,
|
||||
prefs: LauncherPrefs,
|
||||
private val prefs: LauncherPrefs,
|
||||
lifecycle: DaggerSingletonTracker,
|
||||
) : DisplayController(context, wmProxy, prefs, lifecycle) {
|
||||
|
||||
var infoModifier: ((Info) -> Info)? = null
|
||||
var infoModifierForDisplay: ((Info?) -> Info?)? = null
|
||||
|
||||
private var prefListener: LauncherPrefChangeListener? = null
|
||||
|
||||
init {
|
||||
// When overview on CD is disabled, DisplayController only adds the info associated with
|
||||
// the DEFAULT_DISPLAY. So, instead of changing the production code of DisplayController to
|
||||
// use display from context we manually add the info associated with the virtual display.
|
||||
if (!Flags.enableOverviewOnConnectedDisplays()) {
|
||||
getOrCreatePerDisplayInfo(context.display)
|
||||
lifecycle.addCloseable { removePerDisplayInfo(context.displayId) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getInfo(): Info = infoModifier?.invoke(super.getInfo()) ?: super.getInfo()
|
||||
|
||||
override fun getInfoForDisplay(displayId: Int): Info? =
|
||||
infoModifierForDisplay?.invoke(super.getInfoForDisplay(displayId))
|
||||
?: super.getInfoForDisplay(displayId)
|
||||
|
||||
/**
|
||||
* Sets up [TASKBAR_PINNING] pref listener for the given display.
|
||||
*
|
||||
* <p>DisplayController sets up LauncherPrefChangeListener only for the DEFAULT_DISPLAY, this is
|
||||
* correct but tests rely on treating the created virtual display as default. So, instead of
|
||||
* changing the production code of DisplayController to be more testable, we add a custom
|
||||
* listener for our virtual display.
|
||||
*/
|
||||
fun setupTaskbarPinningPrefListener(displayId: Int) {
|
||||
prefListener =
|
||||
LauncherPrefChangeListener { notifyConfigChangeForDisplay(displayId) }
|
||||
.also { prefs.addListener(it, TASKBAR_PINNING) }
|
||||
}
|
||||
|
||||
fun removeTaskbarPinningPrefListener() {
|
||||
prefListener?.let { prefs.removeListener(it, TASKBAR_PINNING) }
|
||||
}
|
||||
}
|
||||
|
||||
/** Convenient extension to access [DisplayControllerSpy] from [TaskbarWindowSandboxContext]. */
|
||||
val TaskbarWindowSandboxContext.displayControllerSpy: DisplayControllerSpy?
|
||||
get() = DisplayController.INSTANCE[this] as? DisplayControllerSpy
|
||||
|
||||
@Module
|
||||
object DesktopVisibilityControllerModule {
|
||||
@JvmStatic
|
||||
|
||||
+6
-3
@@ -119,9 +119,11 @@ class TaskbarUnitTestRule(
|
||||
object : TaskbarNavButtonCallbacks {},
|
||||
RecentsWindowManager.REPOSITORY_INSTANCE.get(context),
|
||||
) {
|
||||
override fun recreateTaskbars() {
|
||||
super.recreateTaskbars()
|
||||
if (currentActivityContext != null) {
|
||||
override fun recreateTaskbarForDisplay(displayId: Int, duration: Int) {
|
||||
super.recreateTaskbarForDisplay(displayId, duration)
|
||||
if (
|
||||
displayId == context.displayId && currentActivityContext != null
|
||||
) {
|
||||
injectControllers()
|
||||
// TODO(b/346394875): we should test a non-default uiController.
|
||||
activityContext.setUIController(TaskbarUIController.DEFAULT)
|
||||
@@ -148,6 +150,7 @@ class TaskbarUnitTestRule(
|
||||
base.evaluate()
|
||||
} finally {
|
||||
instrumentation.runOnMainSync { taskbarManager.destroy() }
|
||||
context.displayControllerSpy?.removeTaskbarPinningPrefListener()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +454,8 @@ public class DisplayController implements DesktopVisibilityListener {
|
||||
}
|
||||
}
|
||||
|
||||
private PerDisplayInfo getOrCreatePerDisplayInfo(Display display) {
|
||||
@VisibleForTesting
|
||||
protected PerDisplayInfo getOrCreatePerDisplayInfo(Display display) {
|
||||
int displayId = display.getDisplayId();
|
||||
PerDisplayInfo perDisplayInfo = mPerDisplayInfo.get(displayId);
|
||||
if (perDisplayInfo != null) {
|
||||
@@ -477,7 +478,8 @@ public class DisplayController implements DesktopVisibilityListener {
|
||||
* Clean up resources for the given display id.
|
||||
* @param displayId The display id
|
||||
*/
|
||||
void removePerDisplayInfo(int displayId) {
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
||||
protected void removePerDisplayInfo(int displayId) {
|
||||
PerDisplayInfo info = mPerDisplayInfo.get(displayId);
|
||||
if (info == null) return;
|
||||
info.cleanup();
|
||||
@@ -769,7 +771,8 @@ public class DisplayController implements DesktopVisibilityListener {
|
||||
}
|
||||
}
|
||||
|
||||
private class PerDisplayInfo implements ComponentCallbacks {
|
||||
@VisibleForTesting
|
||||
protected class PerDisplayInfo implements ComponentCallbacks {
|
||||
final int mDisplayId;
|
||||
final CopyOnWriteArrayList<DisplayInfoChangeListener> mListeners =
|
||||
new CopyOnWriteArrayList<>();
|
||||
|
||||
Reference in New Issue
Block a user