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

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

Merge "Prevent system ui applications from entering dw" into main

parents 710a75b1 98741941
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -155,6 +155,8 @@ class DesktopTasksController(
                visualIndicator = null
            }
        }
    private val sysUIPackageName = context.resources.getString(
        com.android.internal.R.string.config_systemUi)

    private val transitionAreaHeight
        get() =
@@ -214,6 +216,11 @@ 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)
@@ -349,6 +356,14 @@ class DesktopTasksController(
            )
            return
        }
        if (isSystemUIApplication(task)) {
            KtProtoLog.w(
                WM_SHELL_DESKTOP_MODE,
                "DesktopTasksController: Cannot enter desktop, " +
                        "systemUI top activity found."
            )
            return
        }
        KtProtoLog.v(
            WM_SHELL_DESKTOP_MODE,
            "DesktopTasksController: moveToDesktop taskId=%d",
@@ -896,7 +911,9 @@ class DesktopTasksController(
                when {
                    request.type == TRANSIT_TO_BACK -> handleBackNavigation(task)
                    // Check if the task has a top transparent activity
                    shouldLaunchAsModal(task) -> handleTransparentTaskLaunch(task)
                    shouldLaunchAsModal(task) -> handleIncompatibleTaskLaunch(task)
                    // Check if the task has a top systemUI activity
                    isSystemUIApplication(task) -> handleIncompatibleTaskLaunch(task)
                    // Check if fullscreen task should be updated
                    task.isFullscreen -> handleFullscreenTaskLaunch(task, transition)
                    // Check if freeform task should be updated
@@ -930,6 +947,7 @@ class DesktopTasksController(
            .forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) }
    }

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

@@ -996,8 +1014,11 @@ class DesktopTasksController(
        return null
    }

    // Always launch transparent tasks in fullscreen.
    private fun handleTransparentTaskLaunch(task: RunningTaskInfo): WindowContainerTransaction? {
    /**
     * If a task is not compatible with desktop mode freeform, it should always be launched in
     * fullscreen.
     */
    private fun handleIncompatibleTaskLaunch(task: RunningTaskInfo): WindowContainerTransaction? {
        // Already fullscreen, no-op.
        if (task.isFullscreen) return null
        return WindowContainerTransaction().also { wct -> addMoveToFullscreenChanges(wct, task) }
+16 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionReg
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;

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

@@ -152,6 +153,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
    private final DisplayInsetsController mDisplayInsetsController;
    private final Region mExclusionRegion = Region.obtain();
    private boolean mInImmersiveMode;
    private final String mSysUIPackageName;

    private final ISystemGestureExclusionListener mGestureExclusionListener =
            new ISystemGestureExclusionListener.Stub() {
@@ -247,6 +249,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
        mInputManager = mContext.getSystemService(InputManager.class);
        mWindowDecorByTaskId = windowDecorByTaskId;
        mSysUIPackageName = mContext.getResources().getString(
                com.android.internal.R.string.config_systemUi);

        shellInit.addInitCallback(this::onInit, this);
    }
@@ -1035,10 +1039,14 @@ 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)) {
            return false;
        }
        return DesktopModeStatus.canEnterDesktopMode(mContext)
                && !DesktopWallpaperActivity.isWallpaperTask(taskInfo)
                && taskInfo.getWindowingMode() != WINDOWING_MODE_PINNED
@@ -1109,6 +1117,14 @@ 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");
+32 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.content.ComponentName
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.ActivityInfo.CONFIG_DENSITY
@@ -667,6 +668,20 @@ class DesktopTasksControllerTest : ShellTestCase() {
    verifyEnterDesktopWCTNotExecuted()
  }

  @Test
  fun moveToDesktop_systemUIActivity_doesNothing() {
    val task = setUpFullscreenTask()

    // Set task as systemUI package
    val systemUIPackageName = context.resources.getString(
      com.android.internal.R.string.config_systemUi)
    val baseComponent = ComponentName(systemUIPackageName, /* class */ "")
    task.baseActivity = baseComponent

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    verifyEnterDesktopWCTNotExecuted()
  }

  @Test
  fun moveToDesktop_deviceSupported_taskIsMovedToDesktop() {
    val task = setUpFullscreenTask()
@@ -1169,6 +1184,21 @@ class DesktopTasksControllerTest : ShellTestCase() {
        .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
  }

  @Test
  fun handleRequest_systemUIActivity_returnSwitchToFullscreenWCT() {
    val task = setUpFreeformTask()

    // Set task as systemUI package
    val systemUIPackageName = context.resources.getString(
      com.android.internal.R.string.config_systemUi)
    val baseComponent = ComponentName(systemUIPackageName, /* class */ "")
    task.baseActivity = baseComponent

    val result = controller.handleRequest(Binder(), createTransition(task))
    assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode)
            .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
  fun handleRequest_backTransition_singleActiveTask_noToken() {
@@ -1581,6 +1611,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
      bounds: Rect? = null
  ): RunningTaskInfo {
    val task = createFreeformTask(displayId, bounds)
    val activityInfo = ActivityInfo()
    task.topActivityInfo = activityInfo
    whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
    desktopModeTaskRepository.addActiveTask(displayId, task.taskId)
    desktopModeTaskRepository.addOrMoveFreeformTaskToTop(displayId, task.taskId)
+22 −2
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@ import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.content.ComponentName
import android.content.Context
import android.content.pm.ActivityInfo
import android.graphics.Rect
import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
@@ -341,7 +343,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
    }

    @Test
    fun testDescorationIsNotCreatedForTopTranslucentActivities() {
    fun testDecorationIsNotCreatedForTopTranslucentActivities() {
        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
        val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true).apply {
            isTopActivityTransparent = true
@@ -353,6 +355,22 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
    }

    @Test
    fun testDecorationIsNotCreatedForSystemUIActivities() {
        val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true)

        // Set task as systemUI package
        val systemUIPackageName = context.resources.getString(
            com.android.internal.R.string.config_systemUi)
        val baseComponent = ComponentName(systemUIPackageName, /* class */ "")
        task.baseActivity = baseComponent

        onTaskOpening(task)

        verify(mockDesktopModeWindowDecorFactory, never())
                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_IMMERSIVE_HANDLE_HIDING)
    fun testRelayoutRunsWhenStatusBarsInsetsSourceVisibilityChanges() {
@@ -522,7 +540,8 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
            displayId: Int = DEFAULT_DISPLAY,
            @WindowConfiguration.WindowingMode windowingMode: Int,
            activityType: Int = ACTIVITY_TYPE_STANDARD,
            focused: Boolean = true
            focused: Boolean = true,
            activityInfo: ActivityInfo = ActivityInfo()
    ): RunningTaskInfo {
        return TestRunningTaskInfoBuilder()
                .setDisplayId(displayId)
@@ -530,6 +549,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
                .setVisible(true)
                .setActivityType(activityType)
                .build().apply {
                    topActivityInfo = activityInfo
                    isFocused = focused
                }
    }