Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 01cc8561 authored by Tracy Zhou's avatar Tracy Zhou
Browse files

Always recreate TaskbarActivityContext

- Add ENABLE_TASKBAR_NO_RECREATION flag
  When the flag is turned on,
  * Always destroy and recreate
  * Move task bar drag layer lifecycle from TaskbarActivityContext to TaskbarManager
  * Wrap the drag layer into a fullscreen root view

Note that in order to preserve the window across multiple TaskbarActivityContext creations, the inset types and ids must stay the same, so it's extracted out.

Bug: 274517647
Test: Fold and unfold a few times. Use a few applications. Make sure the task bar is visible and in the right place (tested with ENABLE_TASKBAR_NO_RECREATION and FLAG_HIDE_NAVBAR_WINDOW both on, both off, and one on and one off)
Change-Id: Ic3f0aa3d056fe178a53b76b2ad6cc6b9bffd5898
parent 20bbe42c
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -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,14 +1230,18 @@ 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()) {
            if (ENABLE_TASKBAR_NO_RECREATION.get()) {
                mWindowManager.updateViewLayout(mDragLayer.getRootView(), mWindowLayoutParams);
            } else {
                mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
            }
        }
    }

    public void showPopupMenuForIcon(BubbleTextView btv) {
        setTaskbarWindowFullscreen(true);
+31 −3
Original line number Diff line number Diff line
@@ -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<InsetsFrameProvider>,
                                  insetsRoundedCornerFlag: Int): Array<InsetsFrameProvider> {
        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.
+42 −4
Original line number Diff line number Diff line
@@ -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");
+23 −0
Original line number Diff line number Diff line
@@ -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)
    };
}
+4 −0
Original line number Diff line number Diff line
@@ -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,