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

Commit f7ca8d60 authored by Brian Isganitis's avatar Brian Isganitis Committed by Android (Google) Code Review
Browse files

Merge changes I6e7c349d,If6c74b3b,Ib276e9dc,Ida0f7cc0 into main

* changes:
  Override DisplayController on main thread.
  Add annotations for manipulating secure settings.
  Don't use UiThreadTest for Taskbar Unit tests.
  Suspend Launcher taskbar while removed for tests.
parents f49f87de bfa3b7c8
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING;
import static com.android.wm.shell.Flags.enableTinyTaskbar;

import static java.lang.invoke.MethodHandles.Lookup.PROTECTED;

import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.app.ActivityOptions;
@@ -1515,7 +1517,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
        return mIsNavBarKidsMode && isThreeButtonNav();
    }

    protected boolean isNavBarForceVisible() {
    @VisibleForTesting(otherwise = PROTECTED)
    public boolean isNavBarForceVisible() {
        return mIsNavBarForceVisible;
    }

+19 −3
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ public class TaskbarManager {
    private WindowManager mWindowManager;
    private FrameLayout mTaskbarRootLayout;
    private boolean mAddedWindow;
    private boolean mIsSuspended;
    private final TaskbarNavButtonController mNavButtonController;
    private final ComponentCallbacks mComponentCallbacks;

@@ -443,6 +444,8 @@ public class TaskbarManager {
     */
    @VisibleForTesting
    public synchronized void recreateTaskbar() {
        if (mIsSuspended) return;

        Trace.beginSection("recreateTaskbar");
        try {
            DeviceProfile dp = mUserUnlocked ?
@@ -648,8 +651,22 @@ public class TaskbarManager {
        }
    }

    /**
     * Removes Taskbar from the window manager and prevents recreation if {@code true}.
     * <p>
     * Suspending is for testing purposes only; avoid calling this method in production.
     */
    @VisibleForTesting
    public void addTaskbarRootViewToWindow() {
    public void setSuspended(boolean isSuspended) {
        mIsSuspended = isSuspended;
        if (mIsSuspended) {
            removeTaskbarRootViewFromWindow();
        } else {
            addTaskbarRootViewToWindow();
        }
    }

    private void addTaskbarRootViewToWindow() {
        if (enableTaskbarNoRecreate() && !mAddedWindow && mTaskbarActivityContext != null) {
            mWindowManager.addView(mTaskbarRootLayout,
                    mTaskbarActivityContext.getWindowLayoutParams());
@@ -657,8 +674,7 @@ public class TaskbarManager {
        }
    }

    @VisibleForTesting
    public void removeTaskbarRootViewFromWindow() {
    private void removeTaskbarRootViewFromWindow() {
        if (enableTaskbarNoRecreate() && mAddedWindow) {
            mWindowManager.removeViewImmediate(mTaskbarRootLayout);
            mAddedWindow = false;
+63 −53
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.animation.AnimatorTestRule
import android.content.ComponentName
import android.content.Intent
import android.os.Process
import androidx.test.annotation.UiThreadTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.android.launcher3.BubbleTextView
import com.android.launcher3.appprediction.PredictionRowView
@@ -34,6 +33,7 @@ import com.android.launcher3.taskbar.rules.TaskbarWindowSandboxContext
import com.android.launcher3.util.LauncherMultivalentJUnit
import com.android.launcher3.util.LauncherMultivalentJUnit.EmulatedDevices
import com.android.launcher3.util.PackageUserKey
import com.android.launcher3.util.TestUtil
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
@@ -55,17 +55,17 @@ class TaskbarAllAppsControllerTest {
    @InjectController lateinit var overlayController: TaskbarOverlayController

    @Test
    @UiThreadTest
    fun testToggle_once_showsAllApps() {
        allAppsController.toggle()
        getInstrumentation().runOnMainSync { allAppsController.toggle() }
        assertThat(allAppsController.isOpen).isTrue()
    }

    @Test
    @UiThreadTest
    fun testToggle_twice_closesAllApps() {
        getInstrumentation().runOnMainSync {
            allAppsController.toggle()
            allAppsController.toggle()
        }
        assertThat(allAppsController.isOpen).isFalse()
    }

@@ -77,54 +77,62 @@ class TaskbarAllAppsControllerTest {
    }

    @Test
    @UiThreadTest
    fun testSetApps_beforeOpened_cachesInfo() {
        val overlayContext =
            TestUtil.getOnUiThread {
                allAppsController.setApps(TEST_APPS, 0, emptyMap())
                allAppsController.toggle()
                overlayController.requestWindow()
            }

        val overlayContext = overlayController.requestWindow()
        assertThat(overlayContext.appsView.appsStore.apps).isEqualTo(TEST_APPS)
    }

    @Test
    @UiThreadTest
    fun testSetApps_afterOpened_updatesStore() {
        val overlayContext =
            TestUtil.getOnUiThread {
                allAppsController.toggle()
                allAppsController.setApps(TEST_APPS, 0, emptyMap())
                overlayController.requestWindow()
            }

        val overlayContext = overlayController.requestWindow()
        assertThat(overlayContext.appsView.appsStore.apps).isEqualTo(TEST_APPS)
    }

    @Test
    @UiThreadTest
    fun testSetPredictedApps_beforeOpened_cachesInfo() {
        val predictedApps =
            TestUtil.getOnUiThread {
                allAppsController.setPredictedApps(TEST_PREDICTED_APPS)
                allAppsController.toggle()

        val predictedApps =
                overlayController
                    .requestWindow()
                    .appsView
                    .floatingHeaderView
                    .findFixedRowByType(PredictionRowView::class.java)
                    .predictedApps
            }

        assertThat(predictedApps).isEqualTo(TEST_PREDICTED_APPS)
    }

    @Test
    @UiThreadTest
    fun testSetPredictedApps_afterOpened_cachesInfo() {
        val predictedApps =
            TestUtil.getOnUiThread {
                allAppsController.toggle()
                allAppsController.setPredictedApps(TEST_PREDICTED_APPS)

        val predictedApps =
                overlayController
                    .requestWindow()
                    .appsView
                    .floatingHeaderView
                    .findFixedRowByType(PredictionRowView::class.java)
                    .predictedApps
            }

        assertThat(predictedApps).isEqualTo(TEST_PREDICTED_APPS)
    }

@@ -140,36 +148,38 @@ class TaskbarAllAppsControllerTest {
        }

        // Ensure the recycler view fully inflates before trying to grab an icon.
        getInstrumentation().runOnMainSync {
        val btv =
            TestUtil.getOnUiThread {
                overlayController
                    .requestWindow()
                    .appsView
                    .activeRecyclerView
                    .findViewHolderForAdapterPosition(0)
                    ?.itemView as? BubbleTextView
            assertThat(btv?.hasDot()).isTrue()
            }
        assertThat(btv?.hasDot()).isTrue()
    }

    @Test
    @UiThreadTest
    fun testUpdateNotificationDots_predictedApp_hasDot() {
        getInstrumentation().runOnMainSync {
            allAppsController.setPredictedApps(TEST_PREDICTED_APPS)
            allAppsController.toggle()

            taskbarUnitTestRule.activityContext.popupDataProvider.onNotificationPosted(
                PackageUserKey.fromItemInfo(TEST_PREDICTED_APPS[0]),
                NotificationKeyData("key"),
            )
        }

        val predictionRowView =
        val btv =
            TestUtil.getOnUiThread {
                overlayController
                    .requestWindow()
                    .appsView
                    .floatingHeaderView
                    .findFixedRowByType(PredictionRowView::class.java)
        val btv = predictionRowView.getChildAt(0) as BubbleTextView
                    .getChildAt(0) as BubbleTextView
            }
        assertThat(btv.hasDot()).isTrue()
    }

+69 −71
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.launcher3.taskbar.overlay

import android.app.ActivityManager.RunningTaskInfo
import android.view.MotionEvent
import androidx.test.annotation.UiThreadTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.android.launcher3.AbstractFloatingView
import com.android.launcher3.AbstractFloatingView.TYPE_OPTIONS_POPUP
@@ -31,7 +30,7 @@ import com.android.launcher3.taskbar.rules.TaskbarUnitTestRule.InjectController
import com.android.launcher3.taskbar.rules.TaskbarWindowSandboxContext
import com.android.launcher3.util.LauncherMultivalentJUnit
import com.android.launcher3.util.LauncherMultivalentJUnit.EmulatedDevices
import com.android.launcher3.views.BaseDragLayer
import com.android.launcher3.util.TestUtil.getOnUiThread
import com.android.systemui.shared.system.TaskStackChangeListeners
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
@@ -54,74 +53,69 @@ class TaskbarOverlayControllerTest {
        get() = taskbarUnitTestRule.activityContext

    @Test
    @UiThreadTest
    fun testRequestWindow_twice_reusesWindow() {
        val context1 = overlayController.requestWindow()
        val context2 = overlayController.requestWindow()
        val (context1, context2) =
            getOnUiThread {
                Pair(overlayController.requestWindow(), overlayController.requestWindow())
            }
        assertThat(context1).isSameInstanceAs(context2)
    }

    @Test
    @UiThreadTest
    fun testRequestWindow_afterHidingExistingWindow_createsNewWindow() {
        val context1 = overlayController.requestWindow()
        overlayController.hideWindow()
        val context1 = getOnUiThread { overlayController.requestWindow() }
        getInstrumentation().runOnMainSync { overlayController.hideWindow() }

        val context2 = overlayController.requestWindow()
        val context2 = getOnUiThread { overlayController.requestWindow() }
        assertThat(context1).isNotSameInstanceAs(context2)
    }

    @Test
    @UiThreadTest
    fun testRequestWindow_afterHidingOverlay_createsNewWindow() {
        val context1 = overlayController.requestWindow()
        val context1 = getOnUiThread { overlayController.requestWindow() }
        getInstrumentation().runOnMainSync {
            TestOverlayView.show(context1)
            overlayController.hideWindow()
        }

        val context2 = overlayController.requestWindow()
        val context2 = getOnUiThread { overlayController.requestWindow() }
        assertThat(context1).isNotSameInstanceAs(context2)
    }

    @Test
    @UiThreadTest
    fun testRequestWindow_addsProxyView() {
        getInstrumentation().runOnMainSync {
            TestOverlayView.show(overlayController.requestWindow())
        }
        assertThat(hasOpenView(taskbarContext, TYPE_TASKBAR_OVERLAY_PROXY)).isTrue()
    }

    @Test
    @UiThreadTest
    fun testRequestWindow_closeProxyView_closesOverlay() {
        val overlay = TestOverlayView.show(overlayController.requestWindow())
        val overlay = getOnUiThread { TestOverlayView.show(overlayController.requestWindow()) }
        getInstrumentation().runOnMainSync {
            AbstractFloatingView.closeOpenContainer(taskbarContext, TYPE_TASKBAR_OVERLAY_PROXY)
        }
        assertThat(overlay.isOpen).isFalse()
    }

    @Test
    fun testRequestWindow_attachesDragLayer() {
        lateinit var dragLayer: BaseDragLayer<*>
        getInstrumentation().runOnMainSync {
            dragLayer = overlayController.requestWindow().dragLayer
        }

        val dragLayer = getOnUiThread { overlayController.requestWindow().dragLayer }
        // Allow drag layer to attach before checking.
        getInstrumentation().runOnMainSync { assertThat(dragLayer.isAttachedToWindow).isTrue() }
    }

    @Test
    @UiThreadTest
    fun testHideWindow_closesOverlay() {
        val overlay = TestOverlayView.show(overlayController.requestWindow())
        overlayController.hideWindow()
        val overlay = getOnUiThread { TestOverlayView.show(overlayController.requestWindow()) }
        getInstrumentation().runOnMainSync { overlayController.hideWindow() }
        assertThat(overlay.isOpen).isFalse()
    }

    @Test
    fun testHideWindow_detachesDragLayer() {
        lateinit var dragLayer: BaseDragLayer<*>
        getInstrumentation().runOnMainSync {
            dragLayer = overlayController.requestWindow().dragLayer
        }
        val dragLayer = getOnUiThread { overlayController.requestWindow().dragLayer }

        // Wait for drag layer to be attached to window before hiding.
        getInstrumentation().runOnMainSync {
@@ -131,26 +125,30 @@ class TaskbarOverlayControllerTest {
    }

    @Test
    @UiThreadTest
    fun testTwoOverlays_closeOne_windowStaysOpen() {
        val (overlay1, overlay2) =
            getOnUiThread {
                val context = overlayController.requestWindow()
        val overlay1 = TestOverlayView.show(context)
        val overlay2 = TestOverlayView.show(context)
                Pair(TestOverlayView.show(context), TestOverlayView.show(context))
            }

        overlay1.close(false)
        getInstrumentation().runOnMainSync { overlay1.close(false) }
        assertThat(overlay2.isOpen).isTrue()
        assertThat(hasOpenView(taskbarContext, TYPE_TASKBAR_OVERLAY_PROXY)).isTrue()
    }

    @Test
    @UiThreadTest
    fun testTwoOverlays_closeAll_closesWindow() {
        val (overlay1, overlay2) =
            getOnUiThread {
                val context = overlayController.requestWindow()
        val overlay1 = TestOverlayView.show(context)
        val overlay2 = TestOverlayView.show(context)
                Pair(TestOverlayView.show(context), TestOverlayView.show(context))
            }

        getInstrumentation().runOnMainSync {
            overlay1.close(false)
            overlay2.close(false)
        }
        assertThat(hasOpenView(taskbarContext, TYPE_TASKBAR_OVERLAY_PROXY)).isFalse()
    }

@@ -165,11 +163,7 @@ class TaskbarOverlayControllerTest {

    @Test
    fun testTaskMovedToFront_closesOverlay() {
        lateinit var overlay: TestOverlayView
        getInstrumentation().runOnMainSync {
            overlay = TestOverlayView.show(overlayController.requestWindow())
        }

        val overlay = getOnUiThread { TestOverlayView.show(overlayController.requestWindow()) }
        TaskStackChangeListeners.getInstance().listenerImpl.onTaskMovedToFront(RunningTaskInfo())
        // Make sure TaskStackChangeListeners' Handler posts the callback before checking state.
        getInstrumentation().runOnMainSync { assertThat(overlay.isOpen).isFalse() }
@@ -177,9 +171,8 @@ class TaskbarOverlayControllerTest {

    @Test
    fun testTaskStackChanged_allAppsClosed_overlayStaysOpen() {
        lateinit var overlay: TestOverlayView
        val overlay = getOnUiThread { TestOverlayView.show(overlayController.requestWindow()) }
        getInstrumentation().runOnMainSync {
            overlay = TestOverlayView.show(overlayController.requestWindow())
            taskbarContext.controllers.sharedState?.allAppsVisible = false
        }

@@ -189,9 +182,8 @@ class TaskbarOverlayControllerTest {

    @Test
    fun testTaskStackChanged_allAppsOpen_closesOverlay() {
        lateinit var overlay: TestOverlayView
        val overlay = getOnUiThread { TestOverlayView.show(overlayController.requestWindow()) }
        getInstrumentation().runOnMainSync {
            overlay = TestOverlayView.show(overlayController.requestWindow())
            taskbarContext.controllers.sharedState?.allAppsVisible = true
        }

@@ -200,33 +192,39 @@ class TaskbarOverlayControllerTest {
    }

    @Test
    @UiThreadTest
    fun testUpdateLauncherDeviceProfile_overlayNotRebindSafe_closesOverlay() {
        val overlayContext = overlayController.requestWindow()
        val overlay = TestOverlayView.show(overlayContext).apply { type = TYPE_OPTIONS_POPUP }
        val context = getOnUiThread { overlayController.requestWindow() }
        val overlay = getOnUiThread {
            TestOverlayView.show(context).apply { type = TYPE_OPTIONS_POPUP }
        }

        getInstrumentation().runOnMainSync {
            overlayController.updateLauncherDeviceProfile(
                overlayController.launcherDeviceProfile
                .toBuilder(overlayContext)
                    .toBuilder(context)
                    .setGestureMode(false)
                    .build()
            )
        }

        assertThat(overlay.isOpen).isFalse()
    }

    @Test
    @UiThreadTest
    fun testUpdateLauncherDeviceProfile_overlayRebindSafe_overlayStaysOpen() {
        val overlayContext = overlayController.requestWindow()
        val overlay = TestOverlayView.show(overlayContext).apply { type = TYPE_TASKBAR_ALL_APPS }
        val context = getOnUiThread { overlayController.requestWindow() }
        val overlay = getOnUiThread {
            TestOverlayView.show(context).apply { type = TYPE_TASKBAR_ALL_APPS }
        }

        getInstrumentation().runOnMainSync {
            overlayController.updateLauncherDeviceProfile(
                overlayController.launcherDeviceProfile
                .toBuilder(overlayContext)
                    .toBuilder(context)
                    .setGestureMode(false)
                    .build()
            )
        }

        assertThat(overlay.isOpen).isTrue()
    }
+19 −16
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.launcher3.taskbar.rules

import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.android.launcher3.taskbar.rules.TaskbarModeRule.Mode
import com.android.launcher3.taskbar.rules.TaskbarModeRule.TaskbarMode
import com.android.launcher3.util.DisplayController
@@ -59,6 +60,7 @@ class TaskbarModeRule(private val context: TaskbarWindowSandboxContext) : TestRu
            override fun evaluate() {
                val mode = taskbarMode.mode

                getInstrumentation().runOnMainSync {
                    context.applicationContext.putObject(
                        DisplayController.INSTANCE,
                        object : DisplayController(context) {
@@ -76,6 +78,7 @@ class TaskbarModeRule(private val context: TaskbarWindowSandboxContext) : TestRu
                            }
                        },
                    )
                }

                base.evaluate()
            }
Loading