diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 0b83a88bcc..241796af79 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -27,6 +27,7 @@ import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_OVERLAY_PROXY; import static com.android.launcher3.Utilities.isRunningInTestHarness; +import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NO_RECREATION; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_FULLSCREEN; @@ -323,11 +324,11 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mIsDestroyed = false; } - if (!mAddedWindow) { + if (!ENABLE_TASKBAR_NO_RECREATION.get() && !mAddedWindow) { mWindowManager.addView(mDragLayer, mWindowLayoutParams); mAddedWindow = true; } else { - mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams); + notifyUpdateLayoutParams(); } } @@ -674,7 +675,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mIsDestroyed = true; setUIController(TaskbarUIController.DEFAULT); mControllers.onDestroy(); - if (!FLAG_HIDE_NAVBAR_WINDOW) { + if (!ENABLE_TASKBAR_NO_RECREATION.get() && !FLAG_HIDE_NAVBAR_WINDOW) { mWindowManager.removeViewImmediate(mDragLayer); mAddedWindow = false; } @@ -806,7 +807,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { } mWindowLayoutParams.height = height; mControllers.taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged(); - mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams); + notifyUpdateLayoutParams(); } /** @@ -849,7 +850,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { } else { mWindowLayoutParams.flags |= FLAG_NOT_FOCUSABLE; } - mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams); + notifyUpdateLayoutParams(); } /** @@ -1229,12 +1230,16 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mWindowLayoutParams.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION; } - mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams); + notifyUpdateLayoutParams(); } void notifyUpdateLayoutParams() { if (mDragLayer.isAttachedToWindow()) { - mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams); + if (ENABLE_TASKBAR_NO_RECREATION.get()) { + mWindowManager.updateViewLayout(mDragLayer.getRootView(), mWindowLayoutParams); + } else { + mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams); + } } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt index c51a7ec825..12fa17c3e0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt @@ -15,9 +15,9 @@ */ package com.android.launcher3.taskbar -import android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR import android.graphics.Insets import android.graphics.Region +import android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR import android.os.Binder import android.os.IBinder import android.view.Gravity @@ -41,6 +41,7 @@ import com.android.internal.policy.GestureNavigationSettingsObserver import com.android.launcher3.DeviceProfile import com.android.launcher3.R import com.android.launcher3.anim.AlphaUpdateListener +import com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NO_RECREATION import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController import com.android.launcher3.util.DisplayController import java.io.PrintWriter @@ -97,11 +98,18 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas 0 } - windowLayoutParams.providedInsets = getProvidedInsets(insetsRoundedCornerFlag) + windowLayoutParams.providedInsets = + if (ENABLE_TASKBAR_NO_RECREATION.get()) { + getProvidedInsets(controllers.sharedState!!.insetsFrameProviders!!, + insetsRoundedCornerFlag) + } else { + getProvidedInsets(insetsRoundedCornerFlag) + } + if (!context.isGestureNav) { if (windowLayoutParams.paramsForRotation != null) { for (layoutParams in windowLayoutParams.paramsForRotation) { - layoutParams.providedInsets = getProvidedInsets(insetsRoundedCornerFlag) + layoutParams.providedInsets = windowLayoutParams.providedInsets } } } @@ -153,6 +161,26 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas context.notifyUpdateLayoutParams() } + /** + * This is for when ENABLE_TASKBAR_NO_RECREATION is enabled. We generate one instance of + * providedInsets and use it across the entire lifecycle of TaskbarManager. The only thing + * we need to reset is nav bar flags based on insetsRoundedCornerFlag. + */ + private fun getProvidedInsets(providedInsets: Array, + insetsRoundedCornerFlag: Int): Array { + val navBarsFlag = + (if (context.isGestureNav) FLAG_SUPPRESS_SCRIM else 0) or insetsRoundedCornerFlag + for (provider in providedInsets) { + if (provider.type == navigationBars()) { + provider.setFlags( + navBarsFlag, + FLAG_SUPPRESS_SCRIM or FLAG_INSETS_ROUNDED_CORNER + ) + } + } + return providedInsets + } + /** * The inset types and number of insets provided have to match for both gesture nav and button * nav. The values and the order of the elements in array are allowed to differ. diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index c423fb3608..6d9a4823e9 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING; import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING_KEY; import static com.android.launcher3.LauncherState.OVERVIEW; +import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NO_RECREATION; 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; @@ -45,6 +46,8 @@ import android.os.Trace; import android.provider.Settings; import android.util.Log; import android.view.Display; +import android.view.WindowManager; +import android.widget.FrameLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -104,6 +107,9 @@ public class TaskbarManager { Settings.Secure.NAV_BAR_KIDS_MODE); private final Context mContext; + private WindowManager mWindowManager; + private FrameLayout mTaskbarRootLayout; + private boolean mAddedWindow; private final TaskbarNavButtonController mNavButtonController; private final ComponentCallbacks mComponentCallbacks; @@ -175,6 +181,10 @@ public class TaskbarManager { Display display = service.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY); mContext = service.createWindowContext(display, TYPE_NAVIGATION_BAR_PANEL, null); + if (ENABLE_TASKBAR_NO_RECREATION.get()) { + mWindowManager = mContext.getSystemService(WindowManager.class); + mTaskbarRootLayout = new FrameLayout(mContext); + } mNavButtonController = new TaskbarNavButtonController(service, SystemUiProxy.INSTANCE.get(mContext), new Handler()); mComponentCallbacks = new ComponentCallbacks() { @@ -256,10 +266,15 @@ public class TaskbarManager { LauncherPrefs.get(mContext).removeListener(mTaskbarPinningPreferenceChangeListener, TASKBAR_PINNING); mTaskbarActivityContext.onDestroy(); - if (!FLAG_HIDE_NAVBAR_WINDOW) { + if (!FLAG_HIDE_NAVBAR_WINDOW || ENABLE_TASKBAR_NO_RECREATION.get()) { mTaskbarActivityContext = null; } } + DeviceProfile dp = mUserUnlocked ? + LauncherAppState.getIDP(mContext).getDeviceProfile(mContext) : null; + if (dp == null || !isTaskbarPresent(dp)) { + removeTaskbarRootViewFromWindow(); + } } /** @@ -308,6 +323,7 @@ public class TaskbarManager { mUserUnlocked = true; LauncherAppState.getIDP(mContext).addOnChangeListener(mIdpChangeListener); recreateTaskbar(); + addTaskbarRootViewToWindow(); } /** @@ -388,10 +404,9 @@ public class TaskbarManager { return; } - if (mTaskbarActivityContext == null) { + if (ENABLE_TASKBAR_NO_RECREATION.get() || mTaskbarActivityContext == null) { mTaskbarActivityContext = new TaskbarActivityContext(mContext, dp, - mNavButtonController, - mUnfoldProgressProvider); + mNavButtonController, mUnfoldProgressProvider); } else { mTaskbarActivityContext.updateDeviceProfile(dp); } @@ -402,6 +417,13 @@ public class TaskbarManager { createTaskbarUIControllerForActivity(mActivity)); } + if (ENABLE_TASKBAR_NO_RECREATION.get()) { + addTaskbarRootViewToWindow(); + mTaskbarRootLayout.removeAllViews(); + mTaskbarRootLayout.addView(mTaskbarActivityContext.getDragLayer()); + mTaskbarActivityContext.notifyUpdateLayoutParams(); + } + // We to wait until user unlocks the device to attach listener. LauncherPrefs.get(mContext).addListener(mTaskbarPinningPreferenceChangeListener, TASKBAR_PINNING); @@ -523,6 +545,22 @@ public class TaskbarManager { } } + private void addTaskbarRootViewToWindow() { + if (ENABLE_TASKBAR_NO_RECREATION.get() && !mAddedWindow + && mTaskbarActivityContext != null) { + mWindowManager.addView(mTaskbarRootLayout, + mTaskbarActivityContext.getWindowLayoutParams()); + mAddedWindow = true; + } + } + + private void removeTaskbarRootViewFromWindow() { + if (ENABLE_TASKBAR_NO_RECREATION.get() && mAddedWindow) { + mWindowManager.removeViewImmediate(mTaskbarRootLayout); + mAddedWindow = false; + } + } + /** Temp logs for b/254119092. */ public void debugWhyTaskbarNotDestroyed(String debugReason) { StringJoiner log = new StringJoiner("\n"); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java index 66ca7d927f..abbd18b70a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java @@ -15,15 +15,28 @@ */ package com.android.launcher3.taskbar; +import static android.view.InsetsFrameProvider.SOURCE_DISPLAY; +import static android.view.WindowInsets.Type.mandatorySystemGestures; +import static android.view.WindowInsets.Type.navigationBars; +import static android.view.WindowInsets.Type.systemGestures; +import static android.view.WindowInsets.Type.tappableElement; + import static com.android.launcher3.taskbar.LauncherTaskbarUIController.DISPLAY_PROGRESS_COUNT; import android.app.PendingIntent; +import android.os.Binder; +import android.os.IBinder; +import android.view.InsetsFrameProvider; /** * State shared across different taskbar instance */ public class TaskbarSharedState { + private final IBinder mInsetsOwner = new Binder(); + private static int INDEX_LEFT = 0; + private static int INDEX_RIGHT = 1; + // TaskbarManager#onSystemUiFlagsChanged public int sysuiStateFlags; @@ -48,4 +61,14 @@ public class TaskbarSharedState { // Taskbar System Action public PendingIntent taskbarSystemActionPendingIntent; + + public final InsetsFrameProvider[] insetsFrameProviders = new InsetsFrameProvider[] { + new InsetsFrameProvider(mInsetsOwner, 0, navigationBars()), + new InsetsFrameProvider(mInsetsOwner, 0, tappableElement()), + new InsetsFrameProvider(mInsetsOwner, 0, mandatorySystemGestures()), + new InsetsFrameProvider(mInsetsOwner, INDEX_LEFT, systemGestures()) + .setSource(SOURCE_DISPLAY), + new InsetsFrameProvider(mInsetsOwner, INDEX_RIGHT, systemGestures()) + .setSource(SOURCE_DISPLAY) + }; } diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 42857553ff..03a7d8762e 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -213,6 +213,10 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag(270395798, "ENABLE_TRANSIENT_TASKBAR", ENABLED, "Enables transient taskbar."); + public static final BooleanFlag ENABLE_TASKBAR_NO_RECREATION = getDebugFlag(299193589, + "ENABLE_TASKBAR_NO_RECREATION", DISABLED, + "Enables taskbar with no recreation from lifecycle changes of TaskbarActivityContext."); + // TODO(Block 16): Clean up flags // When enabled the promise icon is visible in all apps while installation an app. public static final BooleanFlag PROMISE_APPS_IN_ALL_APPS = getDebugFlag(270390012,