Merge "[CD Taskbar] Refactor TaskbarManager - Add Debugging Support for Stability." into main

This commit is contained in:
Treehugger Robot
2025-02-25 08:14:09 -08:00
committed by Android (Google) Code Review
4 changed files with 237 additions and 103 deletions
@@ -28,7 +28,6 @@ import static com.android.launcher3.util.DisplayController.CHANGE_DESKTOP_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_SHOW_LOCKED_TASKBAR;
import static com.android.launcher3.util.DisplayController.CHANGE_TASKBAR_PINNING;
import static com.android.launcher3.util.DisplayController.TASKBAR_NOT_DESTROYED_TAG;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
import static com.android.quickstep.util.SystemActionConstants.ACTION_SHOW_TASKBAR;
@@ -103,9 +102,6 @@ import java.util.StringJoiner;
public class TaskbarManager {
private static final String TAG = "TaskbarManager";
private static final boolean DEBUG = false;
// TODO(b/382378283) remove all logs with this tag
public static final String NULL_TASKBAR_ROOT_LAYOUT_TAG = "b/382378283";
public static final String ILLEGAL_ARGUMENT_WM_ADD_VIEW = "b/391653300";
private static final int TASKBAR_DESTROY_DURATION = 100;
/**
@@ -131,10 +127,10 @@ public class TaskbarManager {
Settings.Secure.NAV_BAR_KIDS_MODE);
private final Context mBaseContext;
private TaskbarNavButtonCallbacks mNavCallbacks;
private final TaskbarNavButtonCallbacks mNavCallbacks;
// TODO: Remove this during the connected displays lifecycle refactor.
private final Context mPrimaryWindowContext;
private WindowManager mPrimaryWindowManager;
private final WindowManager mPrimaryWindowManager;
private TaskbarNavButtonController mPrimaryNavButtonController;
private ComponentCallbacks mPrimaryComponentCallbacks;
@@ -180,48 +176,47 @@ public class TaskbarManager {
@Override
public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
if ((flags & CHANGE_DENSITY) != 0) {
debugTaskbarManager("onDisplayInfoChanged - Display density changed",
debugTaskbarManager("onDisplayInfoChanged: Display density changed",
context.getDisplayId());
}
if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
debugTaskbarManager("onDisplayInfoChanged - Navigation mode changed",
debugTaskbarManager("onDisplayInfoChanged: Navigation mode changed",
context.getDisplayId());
}
if ((flags & CHANGE_DESKTOP_MODE) != 0) {
debugTaskbarManager("onDisplayInfoChanged - Desktop mode changed",
debugTaskbarManager("onDisplayInfoChanged: Desktop mode changed",
context.getDisplayId());
}
if ((flags & CHANGE_TASKBAR_PINNING) != 0) {
debugTaskbarManager("onDisplayInfoChanged - Taskbar pinning changed",
debugTaskbarManager("onDisplayInfoChanged: Taskbar pinning changed",
context.getDisplayId());
}
if ((flags & (CHANGE_DENSITY | CHANGE_NAVIGATION_MODE | CHANGE_DESKTOP_MODE
| CHANGE_TASKBAR_PINNING | CHANGE_SHOW_LOCKED_TASKBAR)) != 0) {
debugTaskbarManager("onDisplayInfoChanged - Recreating Taskbar!",
debugTaskbarManager("onDisplayInfoChanged: Recreating Taskbar!",
context.getDisplayId());
TaskbarActivityContext taskbarActivityContext = getCurrentActivityContext();
if ((flags & CHANGE_SHOW_LOCKED_TASKBAR) != 0) {
recreateTaskbar();
recreateTaskbars();
} else if ((flags & CHANGE_DESKTOP_MODE) != 0) {
// Only Handles Special Exit Cases for Desktop Mode Taskbar Recreation.
if (taskbarActivityContext != null
&& !DesktopVisibilityController.INSTANCE.get(taskbarActivityContext)
.isInDesktopMode()
&& !DisplayController.showLockedTaskbarOnHome(context)) {
recreateTaskbar();
recreateTaskbars();
}
} else {
recreateTaskbar();
recreateTaskbars();
}
}
}
}
private final SettingsCache.OnChangeListener mOnSettingsChangeListener = c -> {
debugTaskbarManager("Settings changed! Recreating Taskbar!");
recreateTaskbar();
debugPrimaryTaskbar("Settings changed! Recreating Taskbar!");
recreateTaskbars();
};
private final PerceptibleTaskListener mTaskStackListener;
@@ -283,8 +278,6 @@ public class TaskbarManager {
}
}
;
private final DesktopVisibilityController.TaskbarDesktopModeListener
mTaskbarDesktopModeListener =
new DesktopVisibilityController.TaskbarDesktopModeListener() {
@@ -339,14 +332,12 @@ public class TaskbarManager {
@Override
public void run() {
int displayId = getDefaultDisplayId();
debugTaskbarManager("mActivityOnDestroyCallback running!", displayId);
debugTaskbarManager("onActivityDestroyed:", displayId);
if (mActivity != null) {
displayId = mActivity.getDisplayId();
mActivity.removeOnDeviceProfileChangeListener(
mDebugActivityDeviceProfileChanged);
Log.d(TASKBAR_NOT_DESTROYED_TAG,
"unregistering activity lifecycle callbacks from "
+ "onActivityDestroyed.");
debugTaskbarManager("onActivityDestroyed: unregistering callbacks", displayId);
mActivity.removeEventCallback(EVENT_DESTROYED, this);
}
if (mActivity == mRecentsViewContainer) {
@@ -355,7 +346,10 @@ public class TaskbarManager {
mActivity = null;
TaskbarActivityContext taskbar = getTaskbarForDisplay(displayId);
if (taskbar != null) {
debugTaskbarManager("onActivityDestroyed: setting taskbarUIController", displayId);
taskbar.setUIController(TaskbarUIController.DEFAULT);
} else {
debugTaskbarManager("onActivityDestroyed: taskbar is null!", displayId);
}
mUnfoldProgressProvider.setSourceProvider(null);
}
@@ -365,26 +359,26 @@ public class TaskbarManager {
new UnfoldTransitionProgressProvider.TransitionProgressListener() {
@Override
public void onTransitionStarted() {
debugTaskbarManager("fold/unfold transition started getting called.");
debugPrimaryTaskbar("fold/unfold transition started getting called.");
}
@Override
public void onTransitionProgress(float progress) {
debugTaskbarManager(
debugPrimaryTaskbar(
"fold/unfold transition progress getting called. | progress="
+ progress);
}
@Override
public void onTransitionFinishing() {
debugTaskbarManager(
debugPrimaryTaskbar(
"fold/unfold transition finishing getting called.");
}
@Override
public void onTransitionFinished() {
debugTaskbarManager(
debugPrimaryTaskbar(
"fold/unfold transition finished getting called.");
}
};
@@ -402,7 +396,7 @@ public class TaskbarManager {
// Set up primary display.
int primaryDisplayId = getDefaultDisplayId();
debugTaskbarManager("TaskbarManager constructor", primaryDisplayId);
debugPrimaryTaskbar("TaskbarManager constructor");
mPrimaryWindowContext = createWindowContext(primaryDisplayId);
mPrimaryWindowManager = mPrimaryWindowContext.getSystemService(WindowManager.class);
DesktopVisibilityController.INSTANCE.get(
@@ -439,26 +433,32 @@ public class TaskbarManager {
} else {
mTaskStackListener = null;
}
debugTaskbarManager("TaskbarManager created");
recreateTaskbar();
recreateTaskbars();
debugPrimaryTaskbar("TaskbarManager created");
}
private void destroyAllTaskbars() {
debugPrimaryTaskbar("destroyAllTaskbars");
for (int i = 0; i < mTaskbars.size(); i++) {
int displayId = mTaskbars.keyAt(i);
debugTaskbarManager("destroyAllTaskbars: call destroyTaskbarForDisplay", displayId);
destroyTaskbarForDisplay(displayId);
debugTaskbarManager("destroyAllTaskbars: call removeTaskbarRootViewFromWindow",
displayId);
removeTaskbarRootViewFromWindow(displayId);
}
}
private void destroyTaskbarForDisplay(int displayId) {
Log.d(ILLEGAL_ARGUMENT_WM_ADD_VIEW, "destroyTaskbarForDisplay: " + displayId);
debugTaskbarManager("destroyTaskbarForDisplay", displayId);
TaskbarActivityContext taskbar = getTaskbarForDisplay(displayId);
debugTaskbarManager("destroyTaskbarForDisplay: " + taskbar, displayId);
if (taskbar != null) {
taskbar.onDestroy();
// remove all defaults that we store
removeTaskbarFromMap(displayId);
} else {
debugTaskbarManager("destroyTaskbarForDisplay: taskbar is NULL!", displayId);
}
DeviceProfile dp = getDeviceProfile(displayId);
@@ -471,6 +471,7 @@ public class TaskbarManager {
* Show Taskbar upon receiving broadcast
*/
private void showTaskbarFromBroadcast(Intent intent) {
debugPrimaryTaskbar("destroyTaskbarForDisplay");
// TODO: make this code displayId specific
TaskbarActivityContext taskbar = getTaskbarForDisplay(getDefaultDisplayId());
if (ACTION_SHOW_TASKBAR.equals(intent.getAction()) && taskbar != null) {
@@ -507,12 +508,15 @@ public class TaskbarManager {
* Called when the user is unlocked
*/
public void onUserUnlocked() {
debugPrimaryTaskbar("onUserUnlocked");
mUserUnlocked = true;
DisplayController.INSTANCE.get(mPrimaryWindowContext).addChangeListener(
mRecreationListener);
recreateTaskbar();
debugPrimaryTaskbar("onUserUnlocked: recreating all taskbars!");
recreateTaskbars();
for (int i = 0; i < mTaskbars.size(); i++) {
int displayId = mTaskbars.keyAt(i);
debugTaskbarManager("onUserUnlocked: addTaskbarRootViewToWindow()", displayId);
addTaskbarRootViewToWindow(displayId);
}
}
@@ -521,15 +525,15 @@ public class TaskbarManager {
* Sets a {@link StatefulActivity} to act as taskbar callback
*/
public void setActivity(@NonNull StatefulActivity activity) {
debugPrimaryTaskbar("setActivity: mActivity=" + mActivity);
if (mActivity == activity) {
debugPrimaryTaskbar("setActivity: No need to set activity!");
return;
}
removeActivityCallbacksAndListeners();
mActivity = activity;
debugTaskbarManager("Set mActivity=" + mActivity);
mActivity.addOnDeviceProfileChangeListener(mDebugActivityDeviceProfileChanged);
Log.d(TASKBAR_NOT_DESTROYED_TAG,
"registering activity lifecycle callbacks from setActivity().");
debugPrimaryTaskbar("setActivity: registering activity lifecycle callbacks.");
mActivity.addEventCallback(EVENT_DESTROYED, mActivityOnDestroyCallback);
UnfoldTransitionProgressProvider unfoldTransitionProgressProvider =
getUnfoldTransitionProgressProviderForActivity(activity);
@@ -547,6 +551,7 @@ public class TaskbarManager {
* Sets the current RecentsViewContainer, from which we create a TaskbarUIController.
*/
public void setRecentsViewContainer(@NonNull RecentsViewContainer recentsViewContainer) {
debugPrimaryTaskbar("setRecentsViewContainer");
if (mRecentsViewContainer == recentsViewContainer) {
return;
}
@@ -570,6 +575,7 @@ public class TaskbarManager {
*/
private UnfoldTransitionProgressProvider getUnfoldTransitionProgressProviderForActivity(
StatefulActivity activity) {
debugPrimaryTaskbar("getUnfoldTransitionProgressProviderForActivity");
if (!enableUnfoldStateAnimation()) {
if (activity instanceof QuickstepLauncher ql) {
return ql.getUnfoldTransitionProgressProvider();
@@ -582,6 +588,7 @@ public class TaskbarManager {
/** Creates a {@link TaskbarUIController} to use with non default displays. */
private TaskbarUIController createTaskbarUIControllerForNonDefaultDisplay(int displayId) {
debugPrimaryTaskbar("createTaskbarUIControllerForNonDefaultDisplay");
if (RecentsDisplayModel.enableOverviewInWindow()) {
RecentsViewContainer rvc = mRecentsDisplayModel.getRecentsWindowManager(displayId);
if (rvc != null) {
@@ -597,6 +604,7 @@ public class TaskbarManager {
*/
private TaskbarUIController createTaskbarUIControllerForRecentsViewContainer(
RecentsViewContainer container) {
debugPrimaryTaskbar("createTaskbarUIControllerForRecentsViewContainer");
if (container instanceof QuickstepLauncher quickstepLauncher) {
return new LauncherTaskbarUIController(quickstepLauncher);
}
@@ -617,15 +625,18 @@ public class TaskbarManager {
* In other case (folding/unfolding) we don't need to remove and add window.
*/
@VisibleForTesting
public synchronized void recreateTaskbar() {
public synchronized void recreateTaskbars() {
debugPrimaryTaskbar("recreateTaskbars");
// Handles initial creation case.
if (mTaskbars.size() == 0) {
debugTaskbarManager("recreateTaskbars: create primary taskbar", getDefaultDisplayId());
recreateTaskbarForDisplay(getDefaultDisplayId(), 0);
return;
}
for (int i = 0; i < mTaskbars.size(); i++) {
int displayId = mTaskbars.keyAt(i);
debugTaskbarManager("recreateTaskbars: create external taskbar", displayId);
recreateTaskbarForDisplay(displayId, 0);
}
}
@@ -636,16 +647,17 @@ public class TaskbarManager {
* In other case (folding/unfolding) we don't need to remove and add window.
*/
private void recreateTaskbarForDisplay(int displayId, int duration) {
debugTaskbarManager("recreateTaskbarForDisplay: ", displayId);
Trace.beginSection("recreateTaskbarForDisplay");
try {
Log.d(ILLEGAL_ARGUMENT_WM_ADD_VIEW, "recreateTaskbarForDisplay: " + displayId);
debugTaskbarManager("recreateTaskbarForDisplay: getting device profile", displayId);
// TODO (b/381113004): make this display-specific via getWindowContext()
DeviceProfile dp = getDeviceProfile(displayId);
// All Apps action is unrelated to navbar unification, so we only need to check DP.
final boolean isLargeScreenTaskbar = dp != null && dp.isTaskbarPresent;
mAllAppsActionManager.setTaskbarPresent(isLargeScreenTaskbar);
debugTaskbarManager("recreateTaskbarForDisplay: destroying taskbar", displayId);
destroyTaskbarForDisplay(displayId);
boolean displayExists = getDisplay(displayId) != null;
@@ -654,17 +666,22 @@ public class TaskbarManager {
+ " [dp != null (i.e. mUserUnlocked)]=" + (dp != null)
+ " FLAG_HIDE_NAVBAR_WINDOW=" + ENABLE_TASKBAR_NAVBAR_UNIFICATION
+ " dp.isTaskbarPresent=" + (dp == null ? "null" : dp.isTaskbarPresent)
+ " displayExists=" + displayExists);
+ " displayExists=" + displayExists, displayId);
if (!isTaskbarEnabled || !isLargeScreenTaskbar || !displayExists) {
SystemUiProxy.INSTANCE.get(mBaseContext)
.notifyTaskbarStatus(/* visible */ false, /* stashed */ false);
if (!isTaskbarEnabled || !displayExists) {
debugTaskbarManager(
"recreateTaskbarForDisplay: exiting bc (!isTaskbarEnabled || "
+ "!displayExists)",
displayId);
return;
}
}
TaskbarActivityContext taskbar = getTaskbarForDisplay(displayId);
if (enableTaskbarNoRecreate() || taskbar == null) {
debugTaskbarManager("recreateTaskbarForDisplay: creating taskbar", displayId);
taskbar = createTaskbarActivityContext(dp, displayId);
if (taskbar == null) {
debugTaskbarManager(
@@ -672,6 +689,8 @@ public class TaskbarManager {
return;
}
} else {
debugTaskbarManager("recreateTaskbarForDisplay: updating taskbar device profile",
displayId);
taskbar.updateDeviceProfile(dp);
}
mSharedState.startTaskbarVariantIsTransient =
@@ -690,15 +709,17 @@ public class TaskbarManager {
}
if (enableTaskbarNoRecreate()) {
debugTaskbarManager("recreateTaskbarForDisplay: adding rootView", displayId);
addTaskbarRootViewToWindow(displayId);
FrameLayout taskbarRootLayout = getTaskbarRootLayoutForDisplay(displayId);
if (taskbarRootLayout != null) {
debugTaskbarManager("recreateTaskbarForDisplay: adding root layout", displayId);
taskbarRootLayout.removeAllViews();
taskbarRootLayout.addView(taskbar.getDragLayer());
taskbar.notifyUpdateLayoutParams();
} else {
Log.e(NULL_TASKBAR_ROOT_LAYOUT_TAG,
"taskbarRootLayout is null for displayId=" + displayId);
debugTaskbarManager("recreateTaskbarForDisplay: taskbarRootLayout is null!",
displayId);
}
}
} finally {
@@ -843,27 +864,62 @@ public class TaskbarManager {
* primary device or a previously mirroring display is switched to extended mode.
*/
public void onDisplayAddSystemDecorations(int displayId) {
debugTaskbarManager("onDisplayAddSystemDecorations: ", displayId);
Display display = getDisplay(displayId);
if (!DesktopExperienceFlags.ENABLE_TASKBAR_CONNECTED_DISPLAYS.isTrue() || isDefaultDisplay(
displayId) || display == null) {
debugTaskbarManager("onDisplayAddSystemDecorations: not adding display");
if (display == null) {
debugTaskbarManager("onDisplayAddSystemDecorations: can't find display!", displayId);
return;
}
if (!DesktopExperienceFlags.ENABLE_TASKBAR_CONNECTED_DISPLAYS.isTrue() || isDefaultDisplay(
displayId)) {
debugTaskbarManager(
"onDisplayAddSystemDecorations: not an external display! | "
+ "ENABLE_TASKBAR_CONNECTED_DISPLAYS="
+ DesktopExperienceFlags.ENABLE_TASKBAR_CONNECTED_DISPLAYS.isTrue()
+ " isDefaultDisplay=" + isDefaultDisplay(displayId), displayId);
return;
}
debugTaskbarManager("onDisplayAddSystemDecorations: creating new windowContext!",
displayId);
Context newWindowContext = createWindowContext(displayId);
if (newWindowContext != null) {
debugTaskbarManager("onDisplayAddSystemDecorations: add new windowContext to map!",
displayId);
addWindowContextToMap(displayId, newWindowContext);
// TODO (b/391965805): remove once onDisplayAddSystemDecorations is working.
WindowManager wm = getWindowManager(displayId);
if (wm == null || !wm.shouldShowSystemDecors(displayId)) {
String wmStatus = wm == null ? "WindowManager is null!" : "WindowManager exists";
boolean showDecor = wm != null && wm.shouldShowSystemDecors(displayId);
debugTaskbarManager(
"onDisplayAddSystemDecorations:\n\t" + wmStatus + "\n\tshowSystemDecors="
+ showDecor, displayId);
return;
}
debugTaskbarManager("onDisplayAddSystemDecorations: creating RootLayout!", displayId);
createExternalDeviceProfile(displayId);
debugTaskbarManager("onDisplayAddSystemDecorations: creating RootLayout!", displayId);
createTaskbarRootLayout(displayId);
debugTaskbarManager("onDisplayAddSystemDecorations: creating NavButtonController!",
displayId);
createNavButtonController(displayId);
debugTaskbarManager(
"onDisplayAddSystemDecorations: createAndRegisterComponentCallbacks!",
displayId);
createAndRegisterComponentCallbacks(displayId);
debugTaskbarManager("onDisplayAddSystemDecorations: recreateTaskbarForDisplay!",
displayId);
recreateTaskbarForDisplay(displayId, 0);
} else {
debugTaskbarManager("onDisplayAddSystemDecorations: newWindowContext is NULL!",
displayId);
}
debugTaskbarManager("onDisplayAddSystemDecorations: finished!", displayId);
}
/**
@@ -871,18 +927,38 @@ public class TaskbarManager {
* removed from the primary device.
*/
public void onDisplayRemoved(int displayId) {
debugTaskbarManager("onDisplayRemoved: ", displayId);
if (!DesktopExperienceFlags.ENABLE_TASKBAR_CONNECTED_DISPLAYS.isTrue() || isDefaultDisplay(
displayId)) {
debugTaskbarManager(
"onDisplayRemoved: not an external display! | "
+ "ENABLE_TASKBAR_CONNECTED_DISPLAYS="
+ DesktopExperienceFlags.ENABLE_TASKBAR_CONNECTED_DISPLAYS.isTrue()
+ " isDefaultDisplay=" + isDefaultDisplay(displayId), displayId);
return;
}
Context windowContext = getWindowContext(displayId);
if (windowContext != null) {
debugTaskbarManager("onDisplayRemoved: removing NavButtonController!", displayId);
removeNavButtonController(displayId);
debugTaskbarManager("onDisplayRemoved: removeAndUnregisterComponentCallbacks!",
displayId);
removeAndUnregisterComponentCallbacks(displayId);
debugTaskbarManager("onDisplayRemoved: destroying Taskbar!", displayId);
destroyTaskbarForDisplay(displayId);
debugTaskbarManager("onDisplayRemoved: removing DeviceProfile from map!", displayId);
removeDeviceProfileFromMap(displayId);
debugTaskbarManager("onDisplayRemoved: removing WindowContext from map!", displayId);
removeWindowContextFromMap(displayId);
debugTaskbarManager("onDisplayRemoved: finished!", displayId);
} else {
debugTaskbarManager("onDisplayRemoved: removing NavButtonController!", displayId);
}
}
@@ -898,9 +974,7 @@ public class TaskbarManager {
private void removeActivityCallbacksAndListeners() {
if (mActivity != null) {
mActivity.removeOnDeviceProfileChangeListener(mDebugActivityDeviceProfileChanged);
Log.d(TASKBAR_NOT_DESTROYED_TAG,
"unregistering activity lifecycle callbacks from "
+ "removeActivityCallbackAndListeners().");
debugPrimaryTaskbar("unregistering activity lifecycle callbacks");
mActivity.removeEventCallback(EVENT_DESTROYED, mActivityOnDestroyCallback);
UnfoldTransitionProgressProvider unfoldTransitionProgressProvider =
getUnfoldTransitionProgressProviderForActivity(mActivity);
@@ -914,8 +988,9 @@ public class TaskbarManager {
* Called when the manager is no longer needed
*/
public void destroy() {
debugPrimaryTaskbar("TaskbarManager#destroy()");
mRecentsViewContainer = null;
debugTaskbarManager("TaskbarManager#destroy()");
debugPrimaryTaskbar("destroy: removing activity callbacks");
DesktopVisibilityController.INSTANCE.get(
mPrimaryWindowContext).unregisterTaskbarDesktopModeListener(
mTaskbarDesktopModeListener);
@@ -930,7 +1005,7 @@ public class TaskbarManager {
.unregister(USER_SETUP_COMPLETE_URI, mOnSettingsChangeListener);
SettingsCache.INSTANCE.get(mPrimaryWindowContext)
.unregister(NAV_BAR_KIDS_MODE, mOnSettingsChangeListener);
Log.d(TASKBAR_NOT_DESTROYED_TAG, "unregistering component callbacks from destroy().");
debugPrimaryTaskbar("destroy: unregistering component callbacks");
removeAndUnregisterComponentCallbacks(getDefaultDisplayId());
mShutdownReceiver.unregisterReceiverSafely();
if (ActivityManagerWrapper.usePerceptibleTasks(getPrimaryWindowContext())) {
@@ -939,7 +1014,9 @@ public class TaskbarManager {
}
}
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
debugPrimaryTaskbar("destroy: destroying all taskbars!");
destroyAllTaskbars();
debugPrimaryTaskbar("destroy: finished!");
}
public @Nullable TaskbarActivityContext getCurrentActivityContext() {
@@ -962,14 +1039,15 @@ public class TaskbarManager {
}
private void addTaskbarRootViewToWindow(int displayId) {
debugTaskbarManager("addTaskbarRootViewToWindow:", displayId);
TaskbarActivityContext taskbar = getTaskbarForDisplay(displayId);
if (!enableTaskbarNoRecreate() || taskbar == null) {
debugTaskbarManager("addTaskbarRootViewToWindow - taskbar null", displayId);
debugTaskbarManager("addTaskbarRootViewToWindow: taskbar null", displayId);
return;
}
if (getDisplay(displayId) == null) {
debugTaskbarManager("addTaskbarRootViewToWindow - display null", displayId);
debugTaskbarManager("addTaskbarRootViewToWindow: display null", displayId);
return;
}
@@ -980,18 +1058,21 @@ public class TaskbarManager {
windowManager.addView(rootLayout, taskbar.getWindowLayoutParams());
mAddedRootLayouts.put(displayId, true);
} else {
Log.d(ILLEGAL_ARGUMENT_WM_ADD_VIEW,
"addTaskbarRootViewToWindow - root layout null | displayId=" + displayId);
String rootLayoutStatus =
(rootLayout == null) ? "rootLayout is NULL!" : "rootLayout exists!";
String wmStatus = (windowManager == null) ? "windowManager is NULL!"
: "windowManager exists!";
debugTaskbarManager(
"addTaskbarRootViewToWindow: \n\t" + rootLayoutStatus + "\n\t" + wmStatus,
displayId);
}
} else {
Log.d(NULL_TASKBAR_ROOT_LAYOUT_TAG,
"addTaskbarRootViewToWindow - root layout already added | displayId="
+ displayId);
debugTaskbarManager("addTaskbarRootViewToWindow: rootLayout already added!", displayId);
}
}
private void removeTaskbarRootViewFromWindow(int displayId) {
Log.d(ILLEGAL_ARGUMENT_WM_ADD_VIEW, "removeTaskbarRootViewFromWindow: " + displayId);
debugTaskbarManager("removeTaskbarRootViewFromWindow", displayId);
FrameLayout rootLayout = getTaskbarRootLayoutForDisplay(displayId);
if (!enableTaskbarNoRecreate() || rootLayout == null) {
return;
@@ -1003,7 +1084,7 @@ public class TaskbarManager {
mAddedRootLayouts.put(displayId, false);
removeTaskbarRootLayoutFromMap(displayId);
} else {
debugTaskbarManager("removeTaskbarRootViewFromWindow - WindowManager is null",
debugTaskbarManager("removeTaskbarRootViewFromWindow: WindowManager is null",
displayId);
}
}
@@ -1142,6 +1223,7 @@ public class TaskbarManager {
* @param displayId The ID of the display.
*/
private void createAndRegisterComponentCallbacks(int displayId) {
debugTaskbarManager("createAndRegisterComponentCallbacks", displayId);
ComponentCallbacks callbacks = new ComponentCallbacks() {
private Configuration mOldConfig =
getWindowContext(displayId).getResources().getConfiguration();
@@ -1150,14 +1232,13 @@ public class TaskbarManager {
public void onConfigurationChanged(Configuration newConfig) {
Trace.instantForTrack(Trace.TRACE_TAG_APP, "TaskbarManager",
"onConfigurationChanged: " + newConfig);
debugTaskbarManager(
"TaskbarManager#mComponentCallbacks.onConfigurationChanged: " + newConfig);
debugTaskbarManager("onConfigurationChanged: " + newConfig, displayId);
DeviceProfile dp = getDeviceProfile(displayId);
int configDiff = mOldConfig.diff(newConfig) & ~SKIP_RECREATE_CONFIG_CHANGES;
if ((configDiff & ActivityInfo.CONFIG_UI_MODE) != 0) {
Log.d(ILLEGAL_ARGUMENT_WM_ADD_VIEW, "onConfigurationChanged: theme changed");
debugTaskbarManager("onConfigurationChanged: theme changed", displayId);
// Only recreate for theme changes, not other UI mode changes such as docking.
int oldUiNightMode = (mOldConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK);
int newUiNightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK);
@@ -1166,27 +1247,36 @@ public class TaskbarManager {
}
}
debugTaskbarManager("ComponentCallbacks#onConfigurationChanged() "
+ "configDiff=" + Configuration.configurationDiffToString(configDiff));
debugTaskbarManager("onConfigurationChanged: | configDiff="
+ Configuration.configurationDiffToString(configDiff), displayId);
if (configDiff != 0 || getCurrentActivityContext() == null) {
recreateTaskbar();
} else {
debugTaskbarManager("onConfigurationChanged: call recreateTaskbars", displayId);
recreateTaskbars();
} else if (dp != null) {
// Config change might be handled without re-creating the taskbar
if (dp != null && !isTaskbarEnabled(dp)) {
if (!isTaskbarEnabled(dp)) {
debugPrimaryTaskbar(
"onConfigurationChanged: isTaskbarEnabled(dp)=False | "
+ "destroyTaskbarForDisplay");
destroyTaskbarForDisplay(getDefaultDisplayId());
} else {
if (dp != null && isTaskbarEnabled(dp)) {
if (ENABLE_TASKBAR_NAVBAR_UNIFICATION) {
// Re-initialize for screen size change? Should this be done
// by looking at screen-size change flag in configDiff in the
// block above?
recreateTaskbar();
} else {
getCurrentActivityContext().updateDeviceProfile(dp);
}
debugPrimaryTaskbar("onConfigurationChanged: isTaskbarEnabled(dp)=True");
if (ENABLE_TASKBAR_NAVBAR_UNIFICATION) {
// Re-initialize for screen size change? Should this be done
// by looking at screen-size change flag in configDiff in the
// block above?
debugPrimaryTaskbar("onConfigurationChanged: call recreateTaskbars");
recreateTaskbars();
} else {
debugPrimaryTaskbar(
"onConfigurationChanged: updateDeviceProfile for current "
+ "taskbar.");
getCurrentActivityContext().updateDeviceProfile(dp);
}
getCurrentActivityContext().onConfigurationChanged(configDiff);
}
} else {
getCurrentActivityContext().onConfigurationChanged(configDiff);
}
mOldConfig = new Configuration(newConfig);
// reset taskbar was pinned value, so we don't automatically unstash taskbar upon
@@ -1294,7 +1384,7 @@ public class TaskbarManager {
* @param displayId The ID of the display for which to create the taskbar root layout.
*/
private void createTaskbarRootLayout(int displayId) {
Log.d(ILLEGAL_ARGUMENT_WM_ADD_VIEW, "createTaskbarRootLayout: " + displayId);
debugTaskbarManager("createTaskbarRootLayout: ", displayId);
if (!enableTaskbarNoRecreate()) {
return;
}
@@ -1302,6 +1392,7 @@ public class TaskbarManager {
FrameLayout newTaskbarRootLayout = new FrameLayout(getWindowContext(displayId)) {
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
debugTaskbarManager("dispatchTouchEvent: ", displayId);
// The motion events can be outside the view bounds of task bar, and hence
// manually dispatching them to the drag layer here.
TaskbarActivityContext taskbar = getTaskbarForDisplay(displayId);
@@ -1311,8 +1402,9 @@ public class TaskbarManager {
return super.dispatchTouchEvent(ev);
}
};
debugTaskbarManager("createTaskbarRootLayout: adding to map", displayId);
addTaskbarRootLayoutToMap(displayId, newTaskbarRootLayout);
Log.d(NULL_TASKBAR_ROOT_LAYOUT_TAG, "created new root layout - displayId=" + displayId);
}
private boolean isDefaultDisplay(int displayId) {
@@ -1326,13 +1418,12 @@ public class TaskbarManager {
* @return The taskbar root layout {@link FrameLayout} for a given display or {@code null}.
*/
private FrameLayout getTaskbarRootLayoutForDisplay(int displayId) {
Log.d(ILLEGAL_ARGUMENT_WM_ADD_VIEW, "getTaskbarRootLayoutForDisplay: " + displayId);
debugTaskbarManager("getTaskbarRootLayoutForDisplay:", displayId);
FrameLayout frameLayout = mRootLayouts.get(displayId);
if (frameLayout != null) {
return frameLayout;
} else {
Log.d(NULL_TASKBAR_ROOT_LAYOUT_TAG,
"getTaskbarRootLayoutForDisplay == null | displayId=" + displayId);
debugTaskbarManager("getTaskbarRootLayoutForDisplay: rootLayout is null!", displayId);
return null;
}
}
@@ -1344,11 +1435,14 @@ public class TaskbarManager {
* @param rootLayout The taskbar root layout {@link FrameLayout} to add to the map.
*/
private void addTaskbarRootLayoutToMap(int displayId, FrameLayout rootLayout) {
debugTaskbarManager("addTaskbarRootLayoutToMap: ", displayId);
if (!mRootLayouts.contains(displayId) && rootLayout != null) {
mRootLayouts.put(displayId, rootLayout);
}
Log.d(NULL_TASKBAR_ROOT_LAYOUT_TAG, "mRootLayouts.size()=" + mRootLayouts.size());
debugTaskbarManager(
"addTaskbarRootLayoutToMap: finished! mRootLayouts.size()=" + mRootLayouts.size(),
displayId);
}
/**
@@ -1357,12 +1451,14 @@ public class TaskbarManager {
* @param displayId The ID of the display for which to remove the taskbar root layout.
*/
private void removeTaskbarRootLayoutFromMap(int displayId) {
debugTaskbarManager("removeTaskbarRootLayoutFromMap:", displayId);
if (mRootLayouts.contains(displayId)) {
mAddedRootLayouts.delete(displayId);
mRootLayouts.delete(displayId);
}
Log.d(NULL_TASKBAR_ROOT_LAYOUT_TAG, "mRootLayouts.size()=" + mRootLayouts.size());
debugTaskbarManager("removeTaskbarRootLayoutFromMap: finished! mRootLayouts.size="
+ mRootLayouts.size(), displayId);
}
/**
@@ -1371,10 +1467,10 @@ public class TaskbarManager {
* @param displayId The ID of the display for which to create the window context.
*/
private @Nullable Context createWindowContext(int displayId) {
debugTaskbarManager("createWindowContext: " + displayId);
debugTaskbarManager("createWindowContext: ", displayId);
Display display = getDisplay(displayId);
if (display == null) {
debugTaskbarManager("createWindowContext: display null", displayId);
debugTaskbarManager("createWindowContext: display null!", displayId);
return null;
}
@@ -1471,23 +1567,62 @@ public class TaskbarManager {
return mBaseContext.getDisplayId();
}
/** Temp logs for b/254119092. */
public void debugTaskbarManager(String debugReason) {
debugTaskbarManager(debugReason, getDefaultDisplayId());
}
/** Temp logs for b/254119092. */
/**
* Logs debug information about the TaskbarManager for primary display.
* @param debugReason A string describing the reason for the debug log.
* @param displayId The ID of the display for which to log debug information.
*/
public void debugTaskbarManager(String debugReason, int displayId) {
StringJoiner log = new StringJoiner("\n");
log.add(debugReason + " displayId=" + displayId + " isDefaultDisplay=" + isDefaultDisplay(
displayId));
Log.d(TAG, log.toString());
}
/**
* Logs verbose debug information about the TaskbarManager for primary display.
* @param debugReason A string describing the reason for the debug log.
* @param displayId The ID of the display for which to log debug information.
* @param verbose Indicates whether or not to debug with detail.
*/
public void debugTaskbarManager(String debugReason, int displayId, boolean verbose) {
StringJoiner log = new StringJoiner("\n");
log.add(debugReason + " displayId=" + displayId + " isDefaultDisplay=" + isDefaultDisplay(
displayId));
if (verbose) {
generateVerboseLogs(log, displayId);
}
Log.d(TAG, log.toString());
}
/**
* Logs debug information about the TaskbarManager for primary display.
* @param debugReason A string describing the reason for the debug log.
*
*/
public void debugPrimaryTaskbar(String debugReason) {
debugTaskbarManager(debugReason, getDefaultDisplayId(), false);
}
/**
* Logs debug information about the TaskbarManager for primary display.
* @param debugReason A string describing the reason for the debug log.
*
*/
public void debugPrimaryTaskbar(String debugReason, boolean verbose) {
debugTaskbarManager(debugReason, getDefaultDisplayId(), verbose);
}
/**
* Logs verbose debug information about the TaskbarManager for a specific display.
*/
private void generateVerboseLogs(StringJoiner log, int displayId) {
boolean activityTaskbarPresent = mActivity != null
&& mActivity.getDeviceProfile().isTaskbarPresent;
// TODO (b/381113004): make this display-specific via getWindowContext()
Context windowContext = mPrimaryWindowContext;
if (windowContext == null) {
log.add("window context for displayId" + displayId);
log.add("windowContext is null!");
return;
}
@@ -1498,7 +1633,7 @@ public class TaskbarManager {
}
if (activityTaskbarPresent == contextTaskbarPresent) {
log.add("mActivity and mWindowContext agree taskbarIsPresent=" + contextTaskbarPresent);
Log.d(TASKBAR_NOT_DESTROYED_TAG, log.toString());
Log.d(TAG, log.toString());
return;
}
@@ -1522,11 +1657,9 @@ public class TaskbarManager {
} else {
log.add("\t\tCouldn't get DeviceProfile because !mUserUnlocked");
}
Log.d(TASKBAR_NOT_DESTROYED_TAG, log.toString());
}
private final DeviceProfile.OnDeviceProfileChangeListener mDebugActivityDeviceProfileChanged =
dp -> debugTaskbarManager("mActivity onDeviceProfileChanged");
dp -> debugPrimaryTaskbar("mActivity onDeviceProfileChanged", true);
}
@@ -1380,7 +1380,8 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
SystemUiProxy.INSTANCE.get(this).setLauncherAppIconSize(mDeviceProfile.iconSizePx);
TaskbarManager taskbarManager = mTISBindHelper.getTaskbarManager();
if (taskbarManager != null) {
taskbarManager.debugTaskbarManager("QuickstepLauncher#onDeviceProfileChanged");
taskbarManager.debugPrimaryTaskbar("QuickstepLauncher#onDeviceProfileChanged",
true);
}
}
@@ -177,7 +177,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
case TestProtocol.REQUEST_RECREATE_TASKBAR:
// Allow null-pointer to catch illegal states.
runOnTISBinder(tisBinder -> tisBinder.getTaskbarManager().recreateTaskbar());
runOnTISBinder(tisBinder -> tisBinder.getTaskbarManager().recreateTaskbars());
return response;
case TestProtocol.REQUEST_TASKBAR_IME_DOCKED:
return getTISBinderUIProperty(Bundle::putBoolean, tisBinder ->
@@ -113,8 +113,8 @@ class TaskbarUnitTestRule(
object : TaskbarNavButtonCallbacks {},
RecentsDisplayModel.INSTANCE.get(context),
) {
override fun recreateTaskbar() {
super.recreateTaskbar()
override fun recreateTaskbars() {
super.recreateTaskbars()
if (currentActivityContext != null) {
injectControllers()
controllerInjectionCallback.invoke()
@@ -146,7 +146,7 @@ class TaskbarUnitTestRule(
}
/** Simulates Taskbar recreation lifecycle. */
fun recreateTaskbar() = instrumentation.runOnMainSync { taskbarManager.recreateTaskbar() }
fun recreateTaskbar() = instrumentation.runOnMainSync { taskbarManager.recreateTaskbars() }
private fun injectControllers() {
val bubbleControllerTypes =