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

Commit 5b992152 authored by Eghosa Ewansiha-Vlachavas's avatar Eghosa Ewansiha-Vlachavas
Browse files

[1/n] Include default home package in windowing exemptions check

Flag: NONE (bug fix)
Test: atest WMShellUnitTests:DesktopModeCompatPolicyTest,
      atest WMShellUnitTests:DesktopModeWindowDecorViewModelTests,
      atest WMShellUnitTests:DesktopTasksControllerTest
Fixes: 389906224

Change-Id: I15cb6663ab2ca9f43aa1bf90e29cce73637de1b6
parent 0d74af4e
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -20,20 +20,23 @@ import android.app.TaskInfo
import android.content.Context
import android.window.DesktopModeFlags
import com.android.internal.R
import java.util.ArrayList

/**
 * Class to decide whether to apply app compat policies in desktop mode.
 */
// TODO(b/347289970): Consider replacing with API
class DesktopModeCompatPolicy(context: Context) {
class DesktopModeCompatPolicy(private val context: Context) {

    private val systemUiPackage: String = context.resources.getString(R.string.config_systemUi)
    private val defaultHomePackage: String?
        get() = context.getPackageManager().getHomeActivities(ArrayList())?.packageName

    /**
     * If the top activity should be exempt from desktop windowing and forced back to fullscreen.
     * Currently includes all system ui activities and modal dialogs. However if the top activity is
     * not being displayed, regardless of its configuration, we will not exempt it as to remain in
     * the desktop windowing environment.
     * Currently includes all system ui, default home and transparent stack activities. However if
     * the top activity is not being displayed, regardless of its configuration, we will not exempt
     * it as to remain in the desktop windowing environment.
     */
    fun isTopActivityExemptFromDesktopWindowing(task: TaskInfo) =
        isTopActivityExemptFromDesktopWindowing(task.baseActivity?.packageName,
@@ -43,6 +46,7 @@ class DesktopModeCompatPolicy(context: Context) {
        numActivities: Int, isTopActivityNoDisplay: Boolean, isActivityStackTransparent: Boolean) =
        DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue
                && ((isSystemUiTask(packageName)
                || isPartOfDefaultHomePackage(packageName)
                || isTransparentTask(isActivityStackTransparent, numActivities))
                && !isTopActivityNoDisplay)

@@ -57,4 +61,10 @@ class DesktopModeCompatPolicy(context: Context) {
        isActivityStackTransparent && numActivities > 0

    private fun isSystemUiTask(packageName: String?) = packageName == systemUiPackage

    /**
     * Returns true if the tasks base activity is part of the default home package.
     */
    private fun isPartOfDefaultHomePackage(packageName: String?) =
        packageName != null && packageName == defaultHomePackage
}
+0 −12
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
import android.app.IActivityManager;
import android.app.IActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
@@ -1660,9 +1659,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        if (mDesktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(taskInfo)) {
            return false;
        }
        if (isPartOfDefaultHomePackage(taskInfo)) {
            return false;
        }
        final boolean isOnLargeScreen = taskInfo.getConfiguration().smallestScreenWidthDp
                >= WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
        if (!DesktopModeStatus.canEnterDesktopMode(mContext)
@@ -1678,14 +1674,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                && !taskInfo.configuration.windowConfiguration.isAlwaysOnTop();
    }

    private boolean isPartOfDefaultHomePackage(RunningTaskInfo taskInfo) {
        final ComponentName currentDefaultHome =
                mContext.getPackageManager().getHomeActivities(new ArrayList<>());
        return currentDefaultHome != null && taskInfo.baseActivity != null
                && currentDefaultHome.getPackageName()
                .equals(taskInfo.baseActivity.getPackageName());
    }

    private void createWindowDecoration(
            ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl taskSurface,
+76 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.content.pm.ActivityInfo.CONFIG_DENSITY
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
import android.content.pm.PackageManager
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
import android.content.res.Configuration.ORIENTATION_PORTRAIT
import android.content.res.Resources
@@ -1422,6 +1423,41 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
            .isEqualTo(WINDOWING_MODE_FREEFORM)
    }

    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
    fun moveRunningTaskToDesktop_defaultHomePackageWithDisplay_doesNothing() {
        val packageManager: PackageManager = org.mockito.kotlin.mock()
        val homeActivities = ComponentName("defaultHomePackage", /* class */ "")
        val task =
            setUpFullscreenTask().apply {
                baseActivity = homeActivities
                isTopActivityNoDisplay = false
            }
        mContext.setMockPackageManager(packageManager)
        whenever(packageManager.getHomeActivities(any())).thenReturn(homeActivities)

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

    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
    fun moveRunningTaskToDesktop_defaultHomePackageWithoutDisplay_doesNothing() {
        val packageManager: PackageManager = org.mockito.kotlin.mock()
        val homeActivities = ComponentName("defaultHomePackage", /* class */ "")
        val task =
            setUpFullscreenTask().apply {
                baseActivity = homeActivities
                isTopActivityNoDisplay = false
            }
        mContext.setMockPackageManager(packageManager)
        whenever(packageManager.getHomeActivities(any())).thenReturn(homeActivities)

        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)

        val wct = getLatestEnterDesktopWct()
        assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
            .isEqualTo(WINDOWING_MODE_FREEFORM)
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
    fun moveBackgroundTaskToDesktop_remoteTransition_usesOneShotHandler() {
@@ -3018,6 +3054,46 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
            .isEqualTo(WINDOWING_MODE_FREEFORM)
    }

    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
    fun handleRequest_defaultHomePackageWithDisplay_returnSwitchToFullscreenWCT() {
        val freeformTask = setUpFreeformTask()
        markTaskVisible(freeformTask)

        val packageManager: PackageManager = org.mockito.kotlin.mock()
        val homeActivities = ComponentName("defaultHomePackage", /* class */ "")
        val task =
            setUpFullscreenTask().apply {
                baseActivity = homeActivities
                isTopActivityNoDisplay = false
            }
        mContext.setMockPackageManager(packageManager)
        whenever(packageManager.getHomeActivities(any())).thenReturn(homeActivities)

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

    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
    fun handleRequest_defaultHomePackageWithoutDisplay_returnSwitchToFreeformWCT() {
        val freeformTask = setUpFreeformTask()
        markTaskVisible(freeformTask)

        val packageManager: PackageManager = org.mockito.kotlin.mock()
        val homeActivities = ComponentName("defaultHomePackage", /* class */ "")
        val task =
            setUpFullscreenTask().apply {
                baseActivity = homeActivities
                isTopActivityNoDisplay = false
            }
        mContext.setMockPackageManager(packageManager)
        whenever(packageManager.getHomeActivities(any())).thenReturn(homeActivities)

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

    @Test
    fun handleRequest_systemUIActivityWithDisplay_returnSwitchToFullscreenWCT_enforcedDesktop() {
        whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true)
+32 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.wm.shell.shared.desktopmode

import android.content.ComponentName
import android.content.pm.PackageManager
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.internal.R
@@ -27,6 +28,9 @@ import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever

/**
 * Tests for [@link DesktopModeCompatPolicy].
@@ -110,4 +114,32 @@ class DesktopModeCompatPolicyTest : CompatUIShellTestCase() {
                    isTopActivityNoDisplay = true
                }))
    }

    @Test
    fun testIsTopActivityExemptFromDesktopWindowing_defaultHomePackage() {
        val packageManager: PackageManager = mock()
        val homeActivities = ComponentName("defaultHomePackage", /* class */ "")
        whenever(packageManager.getHomeActivities(any())).thenReturn(homeActivities)
        mContext.setMockPackageManager(packageManager)
        assertTrue(desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
            createFreeformTask(/* displayId */ 0)
                .apply {
                    baseActivity = homeActivities
                    isTopActivityNoDisplay = false
                }))
    }

    @Test
    fun testIsTopActivityExemptFromDesktopWindowing_defaultHomePackage_notDisplayed() {
        val packageManager: PackageManager = mock()
        val homeActivities = ComponentName("defaultHomePackage", /* class */ "")
        whenever(packageManager.getHomeActivities(any())).thenReturn(homeActivities)
        mContext.setMockPackageManager(packageManager)
        assertFalse(desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
            createFreeformTask(/* displayId */ 0)
                .apply {
                    baseActivity = homeActivities
                    isTopActivityNoDisplay = true
                }))
    }
}
+18 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.Intent.ACTION_MAIN
import android.content.pm.PackageManager
import android.graphics.Rect
import android.graphics.Region
import android.hardware.display.DisplayManager
@@ -96,7 +97,6 @@ import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
import java.util.function.Consumer


/**
 * Tests of [DesktopModeWindowDecorViewModel]
 * Usage: atest WMShellUnitTests:DesktopModeWindowDecorViewModelTests
@@ -306,6 +306,23 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest
        assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
    fun testDecorationIsNotCreatedForDefaultHomePackage() {
        val packageManager: PackageManager = org.mockito.kotlin.mock()
        val homeActivities = ComponentName("defaultHomePackage", /* class */ "")
        val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN).apply {
            baseActivity = homeActivities
            isTopActivityNoDisplay = false
        }
        mContext.setMockPackageManager(packageManager)
        whenever(packageManager.getHomeActivities(any())).thenReturn(homeActivities)

        onTaskOpening(task)

        assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_IMMERSIVE_HANDLE_HIDING)
    fun testInsetsStateChanged_notifiesAllDecorsInDisplay() {
Loading