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

Commit ca533b12 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Simplifying taskbar recreation logic" into udc-qpr-dev

parents 5fc34e1c c87f7c74
Loading
Loading
Loading
Loading
+40 −45
Original line number Diff line number Diff line
@@ -49,7 +49,6 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.Process;
import android.os.SystemProperties;
import android.os.Trace;
import android.provider.Settings;
import android.util.Log;
@@ -128,8 +127,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext {

    private static final String IME_DRAWS_IME_NAV_BAR_RES_NAME = "config_imeDrawsImeNavBar";

    private static final boolean ENABLE_THREE_BUTTON_TASKBAR =
            SystemProperties.getBoolean("persist.debug.taskbar_three_button", false);
    private static final String TAG = "TaskbarActivityContext";

    private static final String WINDOW_TITLE = "Taskbar";
@@ -169,30 +166,27 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
            TaskbarNavButtonController buttonController, ScopedUnfoldTransitionProgressProvider
            unfoldTransitionProgressProvider) {
        super(windowContext);
        final Resources resources = getResources();

        matchDeviceProfile(launcherDp, getResources());
        applyDeviceProfile(launcherDp);

        final Resources resources = getResources();

        mNavMode = DisplayController.getNavigationMode(windowContext);
        mImeDrawsImeNavBar = getBoolByName(IME_DRAWS_IME_NAV_BAR_RES_NAME, resources, false);
        mIsSafeModeEnabled = TraceHelper.allowIpcs("isSafeMode",
                () -> getPackageManager().isSafeMode());

        // TODO(b/244231596) For shared Taskbar window, update this value in applyDeviceProfile()
        //  instead so to get correct value when recreating the taskbar
        SettingsCache settingsCache = SettingsCache.INSTANCE.get(this);
        mIsUserSetupComplete = settingsCache.getValue(
                Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), 0);
        mIsNavBarForceVisible = settingsCache.getValue(
                Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE), 0);

        // TODO(b/244231596) For shared Taskbar window, update this value in init() instead so
        //  to get correct value when recreating the taskbar
        mIsNavBarKidsMode = settingsCache.getValue(
                Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE), 0);
        mIsNavBarForceVisible = mIsNavBarKidsMode;

        // Get display and corners first, as views might use them in constructor.
        Display display = windowContext.getDisplay();
        Context c = display.getDisplayId() == Display.DEFAULT_DISPLAY
                ? windowContext.getApplicationContext()
                : windowContext.getApplicationContext().createDisplayContext(display);
        Context c = getApplicationContext();
        mWindowManager = c.getSystemService(WindowManager.class);
        mLeftCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT);
        mRightCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT);
@@ -267,6 +261,38 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
                bubbleControllersOptional);
    }

    /** Updates {@link DeviceProfile} instances for any Taskbar windows. */
    public void updateDeviceProfile(DeviceProfile launcherDp) {
        applyDeviceProfile(launcherDp);

        mControllers.taskbarOverlayController.updateLauncherDeviceProfile(launcherDp);
        AbstractFloatingView.closeAllOpenViewsExcept(this, false, TYPE_REBIND_SAFE);
        // Reapply fullscreen to take potential new screen size into account.
        setTaskbarWindowFullscreen(mIsFullscreen);

        dispatchDeviceProfileChanged();
    }

    /**
     * Copy the original DeviceProfile, match the number of hotseat icons and qsb width and update
     * the icon size
     */
    private void applyDeviceProfile(DeviceProfile originDeviceProfile) {
        mDeviceProfile = originDeviceProfile.toBuilder(this)
                .withDimensionsOverride(deviceProfile -> {
                    // Taskbar should match the number of icons of hotseat
                    deviceProfile.numShownHotseatIcons = originDeviceProfile.numShownHotseatIcons;
                    // Same QSB width to have a smooth animation
                    deviceProfile.hotseatQsbWidth = originDeviceProfile.hotseatQsbWidth;

                    // Update icon size
                    deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
                    deviceProfile.updateIconSize(1f, getResources());
                }).build();
        mNavMode = DisplayController.getNavigationMode(this);
    }


    public void init(@NonNull TaskbarSharedState sharedState) {
        mLastRequestedNonFullscreenHeight = getDefaultTaskbarWindowHeight();
        mWindowLayoutParams =
@@ -308,19 +334,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
        return mDeviceProfile;
    }

    /** Updates {@link DeviceProfile} instances for any Taskbar windows. */
    public void updateDeviceProfile(DeviceProfile launcherDp, NavigationMode navMode) {
        mNavMode = navMode;
        mControllers.taskbarOverlayController.updateLauncherDeviceProfile(launcherDp);
        matchDeviceProfile(launcherDp, getResources());

        AbstractFloatingView.closeAllOpenViewsExcept(this, false, TYPE_REBIND_SAFE);
        // Reapply fullscreen to take potential new screen size into account.
        setTaskbarWindowFullscreen(mIsFullscreen);

        dispatchDeviceProfileChanged();
    }

    @Override
    public void dispatchDeviceProfileChanged() {
        super.dispatchDeviceProfileChanged();
@@ -328,24 +341,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
                getDeviceProfile().toSmallString());
    }

    /**
     * Copy the original DeviceProfile, match the number of hotseat icons and qsb width and update
     * the icon size
     */
    private void matchDeviceProfile(DeviceProfile originDeviceProfile, Resources resources) {
        mDeviceProfile = originDeviceProfile.toBuilder(this)
                .withDimensionsOverride(deviceProfile -> {
                    // Taskbar should match the number of icons of hotseat
                    deviceProfile.numShownHotseatIcons = originDeviceProfile.numShownHotseatIcons;
                    // Same QSB width to have a smooth animation
                    deviceProfile.hotseatQsbWidth = originDeviceProfile.hotseatQsbWidth;

                    // Update icon size
                    deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
                    deviceProfile.updateIconSize(1f, resources);
                }).build();
    }

    /**
     * Returns the View bounds of transient taskbar.
     */
+49 −85
Original line number Diff line number Diff line
@@ -22,8 +22,6 @@ 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.util.DisplayController.CHANGE_DENSITY;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
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;
@@ -51,6 +49,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile.OnIDPChangeListener;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -58,8 +57,6 @@ import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.quickstep.RecentsActivity;
@@ -79,6 +76,22 @@ public class TaskbarManager {
    private static final String TAG = "TaskbarManager";
    private static final boolean DEBUG = false;

    /**
     * All the configurations which do not initiate taskbar recreation.
     * This includes all the configurations defined in Launcher's manifest entry and
     * ActivityController#filterConfigChanges
     */
    private static final int SKIP_RECREATE_CONFIG_CHANGES = ActivityInfo.CONFIG_WINDOW_CONFIGURATION
            | ActivityInfo.CONFIG_KEYBOARD
            | ActivityInfo.CONFIG_KEYBOARD_HIDDEN
            | ActivityInfo.CONFIG_MCC
            | ActivityInfo.CONFIG_MNC
            | ActivityInfo.CONFIG_NAVIGATION
            | ActivityInfo.CONFIG_ORIENTATION
            | ActivityInfo.CONFIG_SCREEN_SIZE
            | ActivityInfo.CONFIG_SCREEN_LAYOUT
            | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;

    public static final boolean FLAG_HIDE_NAVBAR_WINDOW =
            SystemProperties.getBoolean("persist.wm.debug.hide_navbar_window", false);

@@ -89,12 +102,11 @@ public class TaskbarManager {
            Settings.Secure.NAV_BAR_KIDS_MODE);

    private final Context mContext;
    private final DisplayController mDisplayController;
    private final TaskbarNavButtonController mNavButtonController;
    private final SettingsCache.OnChangeListener mUserSetupCompleteListener;
    private final SettingsCache.OnChangeListener mNavBarKidsModeListener;
    private final ComponentCallbacks mComponentCallbacks;
    private final SimpleBroadcastReceiver mShutdownReceiver;

    private final SimpleBroadcastReceiver mShutdownReceiver =
            new SimpleBroadcastReceiver(i -> destroyExistingTaskbar());

    // The source for this provider is set when Launcher is available
    // We use 'non-destroyable' version here so the original provider won't be destroyed
@@ -102,7 +114,6 @@ public class TaskbarManager {
    // It's destruction/creation will be managed by the activity.
    private final ScopedUnfoldTransitionProgressProvider mUnfoldProgressProvider =
            new NonDestroyableScopedUnfoldTransitionProgressProvider();
    private NavigationMode mNavMode;

    private TaskbarActivityContext mTaskbarActivityContext;
    private StatefulActivity mActivity;
@@ -113,19 +124,11 @@ public class TaskbarManager {
    private final TaskbarSharedState mSharedState = new TaskbarSharedState();

    /**
     * We use WindowManager's ComponentCallbacks() for most of the config changes, however for
     * navigation mode, that callback gets called too soon, before it's internal navigation mode
     * reflects the current one.
     * DisplayController's callback is delayed enough to get the correct nav mode value
     *
     * We also use density change here because DeviceProfile has had a chance to update it's state
     * whereas density for component callbacks registered in this class don't update DeviceProfile.
     * Confused? Me too. Make it less confusing (TODO: b/227669780)
     *
     * Flags used with {@link #mDispInfoChangeListener}
     * We use WindowManager's ComponentCallbacks() for internal UI changes (similar to an Activity)
     * which comes via a different channel
     */
    private static final int CHANGE_FLAGS = CHANGE_NAVIGATION_MODE | CHANGE_DENSITY;
    private final DisplayController.DisplayInfoChangeListener mDispInfoChangeListener;
    private final OnIDPChangeListener mIdpChangeListener = c -> recreateTaskbar();
    private final SettingsCache.OnChangeListener mOnSettingsChangeListener = c -> recreateTaskbar();

    private boolean mUserUnlocked = false;

@@ -167,15 +170,11 @@ public class TaskbarManager {

    @SuppressLint("WrongConstant")
    public TaskbarManager(TouchInteractionService service) {
        mDisplayController = DisplayController.INSTANCE.get(service);
        Display display =
                service.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
        mContext = service.createWindowContext(display, TYPE_NAVIGATION_BAR_PANEL, null);
        mNavButtonController = new TaskbarNavButtonController(service,
                SystemUiProxy.INSTANCE.get(mContext), new Handler());
        mUserSetupCompleteListener = isUserSetupComplete -> recreateTaskbar();
        mNavBarKidsModeListener = isNavBarKidsMode -> recreateTaskbar();
        // TODO(b/227669780): Consolidate this w/ DisplayController callbacks
        mComponentCallbacks = new ComponentCallbacks() {
            private Configuration mOldConfig = mContext.getResources().getConfiguration();

@@ -186,80 +185,42 @@ public class TaskbarManager {
                DeviceProfile dp = mUserUnlocked
                        ? LauncherAppState.getIDP(mContext).getDeviceProfile(mContext)
                        : null;
                int configDiff = mOldConfig.diff(newConfig);
                int configDiffForRecreate = configDiff;
                int configsRequiringRecreate = ActivityInfo.CONFIG_ASSETS_PATHS
                        | ActivityInfo.CONFIG_LAYOUT_DIRECTION | ActivityInfo.CONFIG_UI_MODE
                        | ActivityInfo.CONFIG_SCREEN_SIZE;
                if ((configDiff & ActivityInfo.CONFIG_SCREEN_SIZE) != 0
                        && mTaskbarActivityContext != null && dp != null
                        && !isPhoneMode(dp)) {
                    // Additional check since this callback gets fired multiple times w/o
                    // screen size changing, or when simply rotating the device.
                    // In the case of phone device rotation, we do want to call recreateTaskbar()
                    DeviceProfile oldDp = mTaskbarActivityContext.getDeviceProfile();
                    boolean isOrientationChange =
                            (configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0;

                    int newOrientation = newConfig.windowConfiguration.getRotation();
                    int oldOrientation = mOldConfig.windowConfiguration.getRotation();
                    int oldWidth = isOrientationChange ? oldDp.heightPx : oldDp.widthPx;
                    int oldHeight = isOrientationChange ? oldDp.widthPx : oldDp.heightPx;

                    if ((dp.widthPx == oldWidth && dp.heightPx == oldHeight)
                            || (newOrientation == oldOrientation)) {
                        configDiffForRecreate &= ~ActivityInfo.CONFIG_SCREEN_SIZE;
                    }
                }
                int configDiff = mOldConfig.diff(newConfig) & ~SKIP_RECREATE_CONFIG_CHANGES;

                if ((configDiff & ActivityInfo.CONFIG_UI_MODE) != 0) {
                    // 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);
                    if (oldUiNightMode == newUiNightMode) {
                        configDiffForRecreate &= ~ActivityInfo.CONFIG_UI_MODE;
                        configDiff &= ~ActivityInfo.CONFIG_UI_MODE;
                    }
                }

                debugWhyTaskbarNotDestroyed("ComponentCallbacks#onConfigurationChanged() "
                        + "configDiffForRecreate="
                        + Configuration.configurationDiffToString(configDiffForRecreate));
                if ((configDiffForRecreate & configsRequiringRecreate) != 0) {
                        + "configDiff=" + Configuration.configurationDiffToString(configDiff));
                if (configDiff != 0 || mTaskbarActivityContext == null) {
                    recreateTaskbar();
                } else {
                    // Config change might be handled without re-creating the taskbar
                    if (mTaskbarActivityContext != null) {
                    if (dp != null && !isTaskbarPresent(dp)) {
                        destroyExistingTaskbar();
                    } else {
                        if (dp != null && isTaskbarPresent(dp)) {
                                mTaskbarActivityContext.updateDeviceProfile(dp, mNavMode);
                            mTaskbarActivityContext.updateDeviceProfile(dp);
                        }
                        mTaskbarActivityContext.onConfigurationChanged(configDiff);
                    }
                }
                }
                mOldConfig = newConfig;
                mOldConfig = new Configuration(newConfig);
            }

            @Override
            public void onLowMemory() { }
        };
        mShutdownReceiver = new SimpleBroadcastReceiver(i ->
                destroyExistingTaskbar());
        mDispInfoChangeListener = (context, info, flags) -> {
            if ((flags & CHANGE_FLAGS) != 0) {
                mNavMode = info.navigationMode;
                recreateTaskbar();
            }
            debugWhyTaskbarNotDestroyed("DisplayInfoChangeListener#"
                    + mDisplayController.getChangeFlagsString(flags));
        };
        mNavMode = mDisplayController.getInfo().navigationMode;
        mDisplayController.addChangeListener(mDispInfoChangeListener);
        SettingsCache.INSTANCE.get(mContext).register(USER_SETUP_COMPLETE_URI,
                mUserSetupCompleteListener);
        SettingsCache.INSTANCE.get(mContext).register(NAV_BAR_KIDS_MODE,
                mNavBarKidsModeListener);
        SettingsCache.INSTANCE.get(mContext)
                .register(USER_SETUP_COMPLETE_URI, mOnSettingsChangeListener);
        SettingsCache.INSTANCE.get(mContext)
                .register(NAV_BAR_KIDS_MODE, mOnSettingsChangeListener);
        mContext.registerComponentCallbacks(mComponentCallbacks);
        mShutdownReceiver.register(mContext, Intent.ACTION_SHUTDOWN);
        UI_HELPER_EXECUTOR.execute(() -> {
@@ -315,6 +276,7 @@ public class TaskbarManager {
     */
    public void onUserUnlocked() {
        mUserUnlocked = true;
        LauncherAppState.getIDP(mContext).addOnChangeListener(mIdpChangeListener);
        recreateTaskbar();
    }

@@ -398,7 +360,7 @@ public class TaskbarManager {
            mTaskbarActivityContext = new TaskbarActivityContext(mContext, dp, mNavButtonController,
                    mUnfoldProgressProvider);
        } else {
            mTaskbarActivityContext.updateDeviceProfile(dp, mNavMode);
            mTaskbarActivityContext.updateDeviceProfile(dp);
        }
        mTaskbarActivityContext.init(mSharedState);

@@ -501,11 +463,13 @@ public class TaskbarManager {
        UI_HELPER_EXECUTOR.execute(
                () -> mTaskbarBroadcastReceiver.unregisterReceiverSafely(mContext));
        destroyExistingTaskbar();
        mDisplayController.removeChangeListener(mDispInfoChangeListener);
        SettingsCache.INSTANCE.get(mContext).unregister(USER_SETUP_COMPLETE_URI,
                mUserSetupCompleteListener);
        SettingsCache.INSTANCE.get(mContext).unregister(NAV_BAR_KIDS_MODE,
                mNavBarKidsModeListener);
        if (mUserUnlocked) {
            LauncherAppState.getIDP(mContext).removeOnChangeListener(mIdpChangeListener);
        }
        SettingsCache.INSTANCE.get(mContext)
                .unregister(USER_SETUP_COMPLETE_URI, mOnSettingsChangeListener);
        SettingsCache.INSTANCE.get(mContext)
                .unregister(NAV_BAR_KIDS_MODE, mOnSettingsChangeListener);
        mContext.unregisterComponentCallbacks(mComponentCallbacks);
        mContext.unregisterReceiver(mShutdownReceiver);
    }