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

Commit f6ea0a3a authored by Eghosa Ewansiha-Vlachavas's avatar Eghosa Ewansiha-Vlachavas Committed by Android (Google) Code Review
Browse files

Merge "Gate new desktop task menu button with device config check" into main

parents a82ce1fe e885e54d
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.quickstep;

import android.content.Context;
import android.os.SystemProperties;

import com.android.internal.annotations.VisibleForTesting;
import com.android.window.flags.Flags;

// TODO(b/335401172): Explore unifying logic across core and shell
public class DesktopModeStatus {

    /**
     * Flag to indicate whether to restrict desktop mode to supported devices.
     */
    private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean(
            "persist.wm.debug.desktop_mode_enforce_device_restrictions", true);

    /**
     * Return {@code true} if desktop mode should be restricted to supported devices.
     */
    @VisibleForTesting
    public static boolean enforceDeviceRestrictions() {
        return ENFORCE_DEVICE_RESTRICTIONS;
    }

    /**
     * Return {@code true} if the current device supports desktop mode.
     */
    @VisibleForTesting
    public static boolean isDesktopModeSupported(Context context) {
        return context.getResources().getBoolean(
                com.android.internal.R.bool.config_isDesktopModeSupported);
    }

    /**
     * Return {@code true} if desktop mode can be entered on the current device.
     */
    public static boolean canEnterDesktopMode(Context context) {
        return Flags.enableDesktopWindowingMode()
                && (!enforceDeviceRestrictions() || isDesktopModeSupported(context));
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import com.android.launcher3.popup.SystemShortcut
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.RecentsViewContainer
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
import com.android.window.flags.Flags

/** A menu item, "Desktop", that allows the user to bring the current app into Desktop Windowing. */
class DesktopSystemShortcut(
@@ -52,7 +51,7 @@ class DesktopSystemShortcut(
    }

    companion object {
        /** Creates a factory for creating Desktop system shorcuts. */
        /** Creates a factory for creating Desktop system shortcuts. */
        @JvmOverloads
        fun createFactory(
            abstractFloatingViewHelper: AbstractFloatingViewHelper = AbstractFloatingViewHelper()
@@ -62,7 +61,7 @@ class DesktopSystemShortcut(
                    container: RecentsViewContainer,
                    taskContainer: TaskIdAttributeContainer
                ): List<DesktopSystemShortcut>? {
                    return if (!Flags.enableDesktopWindowingMode()) null
                    return if (!DesktopModeStatus.canEnterDesktopMode(container.asContext())) null
                    else if (!taskContainer.task.isDockable) null
                    else
                        listOf(
+3 −3
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@ import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SCREEN;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SELECT_ACTIVE;
import static com.android.window.flags.Flags.enableDesktopWindowingMode;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -167,6 +166,7 @@ import com.android.launcher3.util.TranslateEdgeEffect;
import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.util.ViewPool;
import com.android.quickstep.BaseContainerInterface;
import com.android.quickstep.DesktopModeStatus;
import com.android.quickstep.GestureState;
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.RecentsAnimationController;
@@ -2817,7 +2817,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
    }

    private boolean hasDesktopTask(Task[] runningTasks) {
        if (!enableDesktopWindowingMode()) {
        if (!DesktopModeStatus.canEnterDesktopMode(mContext)) {
            return false;
        }
        for (Task task : runningTasks) {
@@ -6229,7 +6229,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
     */
    public void moveTaskToDesktop(TaskIdAttributeContainer taskContainer,
            Runnable successCallback) {
        if (!enableDesktopWindowingMode()) {
        if (!DesktopModeStatus.canEnterDesktopMode(mContext)) {
            return;
        }
        switchToScreenshot(() -> finishRecentsAnimation(/* toRecents= */true, /* shouldPip= */false,
+65 −2
Original line number Diff line number Diff line
@@ -16,12 +16,14 @@

package com.android.quickstep

import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.StaticMockitoSession
import android.content.ComponentName
import android.content.Intent
import android.platform.test.flag.junit.SetFlagsRule
import com.android.launcher3.AbstractFloatingView
import com.android.launcher3.AbstractFloatingViewHelper
import com.android.launcher3.Launcher
import com.android.launcher3.logging.StatsLogManager
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
import com.android.launcher3.model.data.WorkspaceItemInfo
@@ -33,8 +35,11 @@ import com.android.systemui.shared.recents.model.Task
import com.android.systemui.shared.recents.model.Task.TaskKey
import com.android.window.flags.Flags
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.quality.Strictness
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
@@ -56,8 +61,23 @@ class DesktopSystemShortcutTest {
    private val factory: TaskShortcutFactory =
        DesktopSystemShortcut.createFactory(abstractFloatingViewHelper)

    private lateinit var mockitoSession: StaticMockitoSession

    @Before
    fun setUp(){
        mockitoSession = mockitoSession().strictness(Strictness.LENIENT)
                .spyStatic(DesktopModeStatus::class.java).startMocking()
        doReturn(true).`when` { DesktopModeStatus.enforceDeviceRestrictions() }
        doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
    }

    @After
    fun tearDown(){
        mockitoSession.finishMocking()
    }

    @Test
    fun createDesktopTaskShortcutFactory_featureOff() {
    fun createDesktopTaskShortcutFactory_desktopModeDisabled() {
        setFlagsRule.disableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)

        val task =
@@ -76,6 +96,49 @@ class DesktopSystemShortcutTest {
        assertThat(shortcuts).isNull()
    }

    @Test
    fun createDesktopTaskShortcutFactory_desktopModeEnabled_DeviceNotSupported() {
        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
        doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }

        val task =
            Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
                isDockable = true
            }
        val taskContainer =
            taskView.TaskIdAttributeContainer(
                task,
                null,
                null,
                SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
            )

        val shortcuts = factory.getShortcuts(launcher, taskContainer)
        assertThat(shortcuts).isNull()
    }

    @Test
    fun createDesktopTaskShortcutFactory_desktopModeEnabled_DeviceNotSupported_OverrideEnabled() {
        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
        doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
        doReturn(false).`when` { DesktopModeStatus.enforceDeviceRestrictions() }

        val task =
            Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
                isDockable = true
            }
        val taskContainer =
            taskView.TaskIdAttributeContainer(
                task,
                null,
                null,
                SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
            )

        val shortcuts = factory.getShortcuts(launcher, taskContainer)
        assertThat(shortcuts).isNotNull()
    }

    @Test
    fun createDesktopTaskShortcutFactory_undockable() {
        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)