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

Commit e1054919 authored by Winson Chung's avatar Winson Chung
Browse files

Remove expensive queries for lock task mode (screen pinning)

- Instead use the TaskStackListener callbacks to update the state
  in each component as needed

Bug: 224544468
Test: Enable/disable lock task mode and
      dumpsys activity service SystemUIService to confirm the sysui state
      is still updated
Test: atest SystemUITests
Change-Id: I15ec6251c75a29c563820ea6424768fa33245497
parent 6162cc7f
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -282,17 +282,6 @@ public class ActivityManagerWrapper {
        }
    }

    /**
     * @return whether screen pinning is active.
     */
    public boolean isScreenPinningActive() {
        try {
            return getService().getLockTaskModeState() == LOCK_TASK_MODE_PINNED;
        } catch (RemoteException e) {
            return false;
        }
    }

    /**
     * @return whether screen pinning is enabled.
     */
+53 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.shared.system;

import android.annotation.NonNull;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
import android.app.TaskStackListener;
@@ -27,6 +28,8 @@ import android.os.Trace;
import android.util.Log;
import android.window.TaskSnapshot;

import androidx.annotation.VisibleForTesting;

import com.android.internal.os.SomeArgs;
import com.android.systemui.shared.recents.model.ThumbnailData;

@@ -43,14 +46,50 @@ public class TaskStackChangeListeners {

    private final Impl mImpl;

    /**
     * Proxies calls to the given handler callback synchronously for testing purposes.
     */
    private static class TestSyncHandler extends Handler {
        private Handler.Callback mCb;

        public TestSyncHandler() {
            super(Looper.getMainLooper());
        }

        public void setCallback(Handler.Callback cb) {
            mCb = cb;
        }

        @Override
        public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
            return mCb.handleMessage(msg);
        }
    }

    private TaskStackChangeListeners() {
        mImpl = new Impl(Looper.getMainLooper());
    }

    private TaskStackChangeListeners(Handler h) {
        mImpl = new Impl(h);
    }

    public static TaskStackChangeListeners getInstance() {
        return INSTANCE;
    }

    /**
     * Returns an instance of the listeners that can be called upon synchronously for testsing
     * purposes.
     */
    @VisibleForTesting
    public static TaskStackChangeListeners getTestInstance() {
        TestSyncHandler h = new TestSyncHandler();
        TaskStackChangeListeners l = new TaskStackChangeListeners(h);
        h.setCallback(l.mImpl);
        return l;
    }

    /**
     * Registers a task stack listener with the system.
     * This should be called on the main thread.
@@ -71,7 +110,15 @@ public class TaskStackChangeListeners {
        }
    }

    private static class Impl extends TaskStackListener implements Handler.Callback {
    /**
     * Returns an instance of the listener to call upon from tests.
     */
    @VisibleForTesting
    public TaskStackListener getListenerImpl() {
        return mImpl;
    }

    private class Impl extends TaskStackListener implements Handler.Callback {

        private static final int ON_TASK_STACK_CHANGED = 1;
        private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
@@ -104,10 +151,14 @@ public class TaskStackChangeListeners {
        private final Handler mHandler;
        private boolean mRegistered;

        Impl(Looper looper) {
        private Impl(Looper looper) {
            mHandler = new Handler(looper, this);
        }

        private Impl(Handler handler) {
            mHandler = handler;
        }

        public void addListener(TaskStackChangeListener listener) {
            synchronized (mTaskStackListeners) {
                mTaskStackListeners.add(listener);
+27 −8
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.navigationbar;

import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
@@ -44,6 +45,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
@@ -136,9 +138,10 @@ import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.rotation.RotationButton;
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.AutoHideUiElement;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
@@ -252,6 +255,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
    private final AutoHideController.Factory mAutoHideControllerFactory;
    private final Optional<TelecomManager> mTelecomManagerOptional;
    private final InputMethodManager mInputMethodManager;
    private final TaskStackChangeListeners mTaskStackChangeListeners;

    @VisibleForTesting
    public int mDisplayId;
@@ -488,6 +492,18 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
            }
    };

    private boolean mScreenPinningActive = false;
    private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
        @Override
        public void onLockTaskModeChanged(int mode) {
            mScreenPinningActive = (mode == LOCK_TASK_MODE_PINNED);
            mSysUiFlagsContainer.setFlag(SYSUI_STATE_SCREEN_PINNING, mScreenPinningActive)
                    .commitUpdate(mDisplayId);
            mView.setInScreenPinning(mScreenPinningActive);
            updateScreenPinningGestures();
        }
    };

    @Inject
    NavigationBar(
            NavigationBarView navigationBarView,
@@ -529,7 +545,8 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
            EdgeBackGestureHandler edgeBackGestureHandler,
            Optional<BackAnimation> backAnimation,
            UserContextProvider userContextProvider,
            WakefulnessLifecycle wakefulnessLifecycle) {
            WakefulnessLifecycle wakefulnessLifecycle,
            TaskStackChangeListeners taskStackChangeListeners) {
        super(navigationBarView);
        mFrame = navigationBarFrame;
        mContext = context;
@@ -568,6 +585,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
        mInputMethodManager = inputMethodManager;
        mUserContextProvider = userContextProvider;
        mWakefulnessLifecycle = wakefulnessLifecycle;
        mTaskStackChangeListeners = taskStackChangeListeners;

        mNavColorSampleMargin = getResources()
                .getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin);
@@ -676,6 +694,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
        mCommandQueue.recomputeDisableFlags(mDisplayId, false);

        mNotificationShadeDepthController.addListener(mDepthListener);
        mTaskStackChangeListeners.registerTaskStackListener(mTaskStackListener);
    }

    public void destroyView() {
@@ -689,6 +708,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
        mNotificationShadeDepthController.removeListener(mDepthListener);

        mDeviceConfigProxy.removeOnPropertiesChangedListener(mOnPropertiesChangedListener);
        mTaskStackChangeListeners.unregisterTaskStackListener(mTaskStackListener);
    }

    @Override
@@ -990,6 +1010,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
        pw.println("  mTransientShown=" + mTransientShown);
        pw.println("  mTransientShownFromGestureOnSystemBar="
                + mTransientShownFromGestureOnSystemBar);
        pw.println("  mScreenPinningActive=" + mScreenPinningActive);
        dumpBarTransitions(pw, "mNavigationBarView", getBarTransitions());

        pw.println("  mOrientedHandleSamplingRegion: " + mOrientedHandleSamplingRegion);
@@ -1213,10 +1234,9 @@ public class NavigationBar extends ViewController<NavigationBarView> implements

    private void updateScreenPinningGestures() {
        // Change the cancel pin gesture to home and back if recents button is invisible
        boolean pinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
        ButtonDispatcher backButton = mView.getBackButton();
        ButtonDispatcher recentsButton = mView.getRecentsButton();
        if (pinningActive) {
        if (mScreenPinningActive) {
            boolean recentsVisible = mView.isRecentsButtonVisible();
            backButton.setOnLongClickListener(recentsVisible
                    ? this::onLongPressBackRecents
@@ -1227,8 +1247,8 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
            recentsButton.setOnLongClickListener(null);
        }
        // Note, this needs to be set after even if we're setting the listener to null
        backButton.setLongClickable(pinningActive);
        recentsButton.setLongClickable(pinningActive);
        backButton.setLongClickable(mScreenPinningActive);
        recentsButton.setLongClickable(mScreenPinningActive);
    }

    private void notifyNavigationBarScreenOn() {
@@ -1311,8 +1331,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements

    @VisibleForTesting
    boolean onHomeLongClick(View v) {
        if (!mView.isRecentsButtonVisible()
                && ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
        if (!mView.isRecentsButtonVisible() && mScreenPinningActive) {
            return onLongPressBackHome(v);
        }
        if (shouldDisableNavbarGestures()) {
+3 −4
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import com.android.systemui.flags.Flags;
import com.android.systemui.model.SysUiState;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -88,7 +89,6 @@ public class NavigationBarController implements
    private FeatureFlags mFeatureFlags;
    private final DisplayManager mDisplayManager;
    private final TaskbarDelegate mTaskbarDelegate;
    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
    private int mNavMode;
    @VisibleForTesting boolean mIsTablet;

@@ -112,10 +112,10 @@ public class NavigationBarController implements
            NavBarHelper navBarHelper,
            TaskbarDelegate taskbarDelegate,
            NavigationBarComponent.Factory navigationBarComponentFactory,
            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
            DumpManager dumpManager,
            AutoHideController autoHideController,
            LightBarController lightBarController,
            TaskStackChangeListeners taskStackChangeListeners,
            Optional<Pip> pipOptional,
            Optional<BackAnimation> backAnimation,
            FeatureFlags featureFlags) {
@@ -129,11 +129,10 @@ public class NavigationBarController implements
        mConfigChanges.applyNewConfig(mContext.getResources());
        mNavMode = navigationModeController.addListener(this);
        mTaskbarDelegate = taskbarDelegate;
        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
        mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService,
                navBarHelper, navigationModeController, sysUiFlagsContainer,
                dumpManager, autoHideController, lightBarController, pipOptional,
                backAnimation.orElse(null));
                backAnimation.orElse(null), taskStackChangeListeners);
        mIsTablet = isTablet(mContext);
        dumpManager.registerDumpable(this);
    }
+10 −6
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.navigationbar;

import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
import static android.inputmethodservice.InputMethodService.canImeRenderGesturalNavButtons;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;

@@ -80,6 +81,7 @@ import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdates
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
@@ -160,6 +162,7 @@ public class NavigationBarView extends FrameLayout {
     * fully locked mode we only show that unlocking is blocked.
     */
    private ScreenPinningNotify mScreenPinningNotify;
    private boolean mScreenPinningActive = false;

    /**
     * {@code true} if the IME can render the back button and the IME switcher button.
@@ -636,14 +639,13 @@ public class NavigationBarView extends FrameLayout {
        // When screen pinning, don't hide back and home when connected service or back and
        // recents buttons when disconnected from launcher service in screen pinning mode,
        // as they are used for exiting.
        final boolean pinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
        if (mOverviewProxyEnabled) {
            // Force disable recents when not in legacy mode
            disableRecent |= !QuickStepContract.isLegacyMode(mNavBarMode);
            if (pinningActive && !QuickStepContract.isGesturalMode(mNavBarMode)) {
            if (mScreenPinningActive && !QuickStepContract.isGesturalMode(mNavBarMode)) {
                disableBack = disableHome = false;
            }
        } else if (pinningActive) {
        } else if (mScreenPinningActive) {
            disableBack = disableRecent = false;
        }

@@ -738,9 +740,7 @@ public class NavigationBarView extends FrameLayout {
    public void updateDisabledSystemUiStateFlags(SysUiState sysUiState) {
        int displayId = mContext.getDisplayId();

        sysUiState.setFlag(SYSUI_STATE_SCREEN_PINNING,
                        ActivityManagerWrapper.getInstance().isScreenPinningActive())
                .setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
        sysUiState.setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
                        (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0)
                .setFlag(SYSUI_STATE_HOME_DISABLED,
                        (mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0)
@@ -749,6 +749,10 @@ public class NavigationBarView extends FrameLayout {
                .commitUpdate(displayId);
    }

    public void setInScreenPinning(boolean active) {
        mScreenPinningActive = active;
    }

    private void updatePanelSystemUiStateFlags() {
        if (SysUiState.DEBUG) {
            Log.d(TAG, "Updating panel sysui state flags: panelView=" + mPanelView);
Loading