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

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

Merge "Modify desktop windowing exemption logic and criteria" into main

parents 0071c61d 4795368f
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -296,6 +296,12 @@ public class TaskInfo {
     */
    public boolean isTopActivityTransparent;

    /**
     * Whether the top activity has specified style floating.
     * @hide
     */
    public boolean isTopActivityStyleFloating;

    /**
     * Encapsulate specific App Compat information.
     * @hide
@@ -429,6 +435,7 @@ public class TaskInfo {
                && parentTaskId == that.parentTaskId
                && Objects.equals(topActivity, that.topActivity)
                && isTopActivityTransparent == that.isTopActivityTransparent
                && isTopActivityStyleFloating == that.isTopActivityStyleFloating
                && appCompatTaskInfo.equalsForTaskOrganizer(that.appCompatTaskInfo);
    }

@@ -498,6 +505,7 @@ public class TaskInfo {
        mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR);
        displayAreaFeatureId = source.readInt();
        isTopActivityTransparent = source.readBoolean();
        isTopActivityStyleFloating = source.readBoolean();
        appCompatTaskInfo = source.readTypedObject(AppCompatTaskInfo.CREATOR);
    }

@@ -545,6 +553,7 @@ public class TaskInfo {
        dest.writeTypedObject(mTopActivityLocusId, flags);
        dest.writeInt(displayAreaFeatureId);
        dest.writeBoolean(isTopActivityTransparent);
        dest.writeBoolean(isTopActivityStyleFloating);
        dest.writeTypedObject(appCompatTaskInfo, flags);
    }

@@ -582,6 +591,7 @@ public class TaskInfo {
                + " locusId=" + mTopActivityLocusId
                + " displayAreaFeatureId=" + displayAreaFeatureId
                + " isTopActivityTransparent=" + isTopActivityTransparent
                + " isTopActivityStyleFloating=" + isTopActivityStyleFloating
                + " appCompatTaskInfo=" + appCompatTaskInfo
                + "}";
    }
+12 −2
Original line number Diff line number Diff line
@@ -19,6 +19,16 @@
package com.android.wm.shell.compatui

import android.app.TaskInfo
fun isSingleTopActivityTranslucent(task: TaskInfo) =
    task.isTopActivityTransparent && task.numActivities == 1
import android.content.Context
import com.android.internal.R

// TODO(b/347289970): Consider replacing with API
fun isTopActivityExemptFromDesktopWindowing(context: Context, task: TaskInfo) =
    isSystemUiTask(context, task) || (task.isTopActivityTransparent && task.numActivities == 1
            && !task.isTopActivityStyleFloating)

private fun isSystemUiTask(context: Context, task: TaskInfo): Boolean {
    val sysUiPackageName: String =
        context.resources.getString(R.string.config_systemUi)
    return task.baseActivity?.packageName == sysUiPackageName
}
+9 −25
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
import com.android.wm.shell.compatui.isSingleTopActivityTranslucent
import com.android.wm.shell.compatui.isTopActivityExemptFromDesktopWindowing
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.DragToDesktopStateListener
import com.android.wm.shell.draganddrop.DragAndDropController
@@ -158,8 +158,6 @@ class DesktopTasksController(
                visualIndicator = null
            }
        }
    private val sysUIPackageName = context.resources.getString(
        com.android.internal.R.string.config_systemUi)

    private val transitionAreaHeight
        get() =
@@ -219,11 +217,6 @@ class DesktopTasksController(
        return visualIndicator
    }

    // TODO(b/347289970): Consider replacing with API
    private fun isSystemUIApplication(taskInfo: RunningTaskInfo): Boolean {
        return taskInfo.baseActivity?.packageName == sysUIPackageName
    }

    fun setOnTaskResizeAnimationListener(listener: OnTaskResizeAnimationListener) {
        toggleResizeDesktopTaskTransitionHandler.setOnTaskResizeAnimationListener(listener)
        enterDesktopTaskTransitionHandler.setOnTaskResizeAnimationListener(listener)
@@ -351,19 +344,12 @@ class DesktopTasksController(
        wct: WindowContainerTransaction = WindowContainerTransaction(),
        transitionSource: DesktopModeTransitionSource,
    ) {
        if (Flags.enableDesktopWindowingModalsPolicy() && isSingleTopActivityTranslucent(task)) {
            KtProtoLog.w(
                WM_SHELL_DESKTOP_MODE,
                "DesktopTasksController: Cannot enter desktop, " +
                    "translucent top activity found. This is likely a modal dialog."
            )
            return
        }
        if (isSystemUIApplication(task)) {
        if (Flags.enableDesktopWindowingModalsPolicy()
            && isTopActivityExemptFromDesktopWindowing(context, task)) {
            KtProtoLog.w(
                WM_SHELL_DESKTOP_MODE,
                "DesktopTasksController: Cannot enter desktop, " +
                        "systemUI top activity found."
                        "ineligible top activity found."
            )
            return
        }
@@ -942,10 +928,8 @@ class DesktopTasksController(
                when {
                    // Check if the closing task needs to be handled
                    TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task)
                    // Check if the task has a top transparent activity
                    shouldLaunchAsModal(task) -> handleIncompatibleTaskLaunch(task)
                    // Check if the task has a top systemUI activity
                    isSystemUIApplication(task) -> handleIncompatibleTaskLaunch(task)
                    // Check if the top task shouldn't be allowed to enter desktop mode
                    isIncompatibleTask(task) -> handleIncompatibleTaskLaunch(task)
                    // Check if fullscreen task should be updated
                    task.isFullscreen -> handleFullscreenTaskLaunch(task, transition)
                    // Check if freeform task should be updated
@@ -979,9 +963,9 @@ class DesktopTasksController(
            .forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) }
    }

    // TODO(b/347289970): Consider replacing with API
    private fun shouldLaunchAsModal(task: TaskInfo) =
        Flags.enableDesktopWindowingModalsPolicy() && isSingleTopActivityTranslucent(task)
    private fun isIncompatibleTask(task: TaskInfo) =
        Flags.enableDesktopWindowingModalsPolicy()
                && isTopActivityExemptFromDesktopWindowing(context, task)

    private fun shouldHandleTaskClosing(request: TransitionRequestInfo): Boolean {
        return Flags.enableDesktopWindowingWallpaperActivity() &&
+2 −15
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ import static android.view.WindowInsets.Type.statusBars;

import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.compatui.AppCompatUtils.isSingleTopActivityTranslucent;
import static com.android.wm.shell.compatui.AppCompatUtils.isTopActivityExemptFromDesktopWindowing;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
@@ -105,7 +105,6 @@ import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;

import java.io.PrintWriter;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;

@@ -1034,12 +1033,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                && taskInfo.isFocused) {
            return false;
        }
        // TODO(b/347289970): Consider replacing with API
        if (Flags.enableDesktopWindowingModalsPolicy()
                && isSingleTopActivityTranslucent(taskInfo)) {
            return false;
        }
        if (isSystemUIApplication(taskInfo)) {
                && isTopActivityExemptFromDesktopWindowing(mContext, taskInfo)) {
            return false;
        }
        return DesktopModeStatus.canEnterDesktopMode(mContext)
@@ -1118,14 +1113,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                && mSplitScreenController.isTaskInSplitScreen(taskId);
    }

    // TODO(b/347289970): Consider replacing with API
    private boolean isSystemUIApplication(RunningTaskInfo taskInfo) {
        if (taskInfo.baseActivity != null) {
            return (Objects.equals(taskInfo.baseActivity.getPackageName(), mSysUIPackageName));
        }
        return false;
    }

    private void dump(PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
        pw.println(prefix + "DesktopModeWindowDecorViewModel");
+37 −6
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.wm.shell.compatui

import android.content.ComponentName
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
import org.junit.Assert.assertFalse
@@ -34,26 +36,55 @@ import org.junit.runner.RunWith
@RunWith(AndroidTestingRunner::class)
@SmallTest
class AppCompatUtilsTest : ShellTestCase() {

    @Test
    fun testIsSingleTopActivityTranslucent() {
        assertTrue(isSingleTopActivityTranslucent(
    fun testIsTopActivityExemptFromDesktopWindowing_topActivityTransparent() {
        assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
            createFreeformTask(/* displayId */ 0)
                    .apply {
                        isTopActivityTransparent = true
                        numActivities = 1
                    }))
        assertFalse(isSingleTopActivityTranslucent(
        assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
            createFreeformTask(/* displayId */ 0)
                    .apply {
                        isTopActivityTransparent = true
                        numActivities = 0
                    }))
        assertFalse(isSingleTopActivityTranslucent(
    }

    @Test
    fun testIsTopActivityExemptFromDesktopWindowing_singleTopActivity() {
        assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
            createFreeformTask(/* displayId */ 0)
                    .apply {
                        isTopActivityTransparent = true
                        numActivities = 1
                    }))
        assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
            createFreeformTask(/* displayId */ 0)
                    .apply {
                        isTopActivityTransparent = false
                        numActivities = 1
                    }))
    }

    @Test
    fun testIsTopActivityExemptFromDesktopWindowing__topActivityStyleFloating() {
        assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
            createFreeformTask(/* displayId */ 0)
                    .apply {
                        isTopActivityStyleFloating = true
                    }))
    }

    @Test
    fun testIsTopActivityExemptFromDesktopWindowing_systemUiTask() {
        val systemUIPackageName = context.resources.getString(R.string.config_systemUi)
        val baseComponent = ComponentName(systemUIPackageName, /* class */ "")
        assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
            createFreeformTask(/* displayId */ 0)
                    .apply {
                        baseActivity = baseComponent
                    }))
    }
}
Loading