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

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

Merge "Exempt desktop demo app from desktop" into main

parents 9c29636b 13a129be
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -31,7 +31,9 @@ import android.window.DesktopModeFlags;
import com.android.internal.R;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
@@ -41,6 +43,8 @@ public class DesktopModeCompatPolicy {
    private final Context mContext;
    @NonNull
    private final String mSystemUiPackage;
    @NonNull
    private final List<String> mConfigExemptPackages;
    private final Map<String, Boolean> mPackageInfoCache = new HashMap<>();
    private PackageManager mPackageManager = null;

@@ -49,6 +53,8 @@ public class DesktopModeCompatPolicy {
    public DesktopModeCompatPolicy(@NonNull Context context) {
        mContext = context;
        mSystemUiPackage = context.getResources().getString(R.string.config_systemUi);
        mConfigExemptPackages = Arrays.asList(context.getResources().getStringArray(
                R.array.config_desktopExemptPackages));
    }

    public void setDefaultHomePackageSupplier(
@@ -113,6 +119,11 @@ public class DesktopModeCompatPolicy {
        if (isTopActivityNoDisplay) {
            return false;
        }
        // TODO: b/434943016 - Replace with permission.
        // If activity belongs to package exempt via device config, force out of desktop.
        if (isPackageExemptViaConfig(packageName) && !isActivityStackTransparent) {
            return true;
        }
        // If activity belongs to system ui package, safe to force out of desktop.
        if (isSystemUiTask(packageName)) {
            return true;
@@ -162,6 +173,11 @@ public class DesktopModeCompatPolicy {
        if (isPartOfDefaultHomePackageOrNoHomeAvailable(packageName)) {
            return true;
        }
        // TODO: b/434943016 - Replace with permission.
        // If activity belongs to package exempt via device config, hide desktop entry point.
        if (isPackageExemptViaConfig(packageName)) {
            return true;
        }
        // If all activities in task stack are transparent AND package has the relevant fullscreen
        // transparent permission, safe to force out of desktop.
        return isTransparentTask(isActivityStackTransparent, numActivities);
@@ -197,6 +213,10 @@ public class DesktopModeCompatPolicy {
        return Objects.equals(packageName, mSystemUiPackage);
    }

    private boolean isPackageExemptViaConfig(@Nullable String packageName) {
        return mConfigExemptPackages.contains(packageName);
    }

    // Checks if the app for the given package has the SYSTEM_ALERT_WINDOW permission.
    private boolean hasFullscreenTransparentPermission(@NonNull String packageName, int userId) {
        if (!DesktopModeFlags.ENABLE_MODALS_FULLSCREEN_WITH_PERMISSIONS.isTrue()) {
+3 −0
Original line number Diff line number Diff line
@@ -7522,6 +7522,9 @@
    <!-- Whether the home screen should be shown behind freeform tasks in desktop mode. -->
    <bool name="config_showHomeBehindDesktop">false</bool>

    <!-- List of packages which should be exempt from desktop mode. -->
    <string-array name="config_desktopExemptPackages" translatable="false"/>

    <!-- Frame rate compatibility value for Wallpaper
         FRAME_RATE_COMPATIBILITY_MIN (102) is used by default for lower power consumption -->
    <integer name="config_wallpaperFrameRateCompatibility">102</integer>
+3 −0
Original line number Diff line number Diff line
@@ -6099,6 +6099,9 @@
  <!-- Whether the home screen should be shown behind freeform tasks in desktop mode. -->
  <java-symbol type="bool" name="config_showHomeBehindDesktop" />

  <!-- List of packages which should be exempt from desktop mode. -->
  <java-symbol type="array" name="config_desktopExemptPackages" />

  <!-- Frame rate compatibility value for Wallpaper -->
  <java-symbol type="integer" name="config_wallpaperFrameRateCompatibility" />

+46 −5
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.Process
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.AndroidTestingRunner
import android.testing.TestableContext
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.internal.policy.DesktopModeCompatPolicy
@@ -47,8 +48,10 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.spy
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@@ -62,16 +65,24 @@ import org.mockito.kotlin.whenever
@SmallTest
class DesktopModeCompatPolicyTest : ShellTestCase() {
    @get:Rule val compatRule = PlatformCompatChangeRule()
    private lateinit var mockContext: TestableContext
    private lateinit var desktopModeCompatPolicy: DesktopModeCompatPolicy
    private val packageManager: PackageManager = mock()
    private val homeActivities = ComponentName(HOME_LAUNCHER_PACKAGE_NAME, /* class */ "")
    private val baseActivityTest = ComponentName("com.test.dummypackage", "TestClass")
    private val configExemptActivity = ComponentName("com.test.configExemptPackage", /* class */ "")
    private val configExemptPackageList = arrayOf(configExemptActivity.packageName)

    @Before
    fun setUp() {
        desktopModeCompatPolicy = DesktopModeCompatPolicy(mContext)
        mockContext = spy(mContext)
        val resources = spy(mockContext.resources)
        doReturn(configExemptPackageList).`when`(resources)
            .getStringArray(R.array.config_desktopExemptPackages)
        doReturn(resources).`when`(mockContext).resources
        desktopModeCompatPolicy = DesktopModeCompatPolicy(mockContext)
        whenever(packageManager.getHomeActivities(any())).thenReturn(homeActivities)
        mContext.setMockPackageManager(packageManager)
        mockContext.setMockPackageManager(packageManager)
    }

    @Test
@@ -277,7 +288,7 @@ class DesktopModeCompatPolicyTest : ShellTestCase() {
    @Test
    fun testIsTopActivityExemptFromDesktopWindowing_defaultHomePackage_notYetAvailable() {
        val emptyHomeActivities: ComponentName = mock()
        mContext.setMockPackageManager(packageManager)
        mockContext.setMockPackageManager(packageManager)

        whenever(emptyHomeActivities.packageName).thenReturn(null)
        whenever(packageManager.getHomeActivities(any())).thenReturn(emptyHomeActivities)
@@ -290,6 +301,27 @@ class DesktopModeCompatPolicyTest : ShellTestCase() {
                }))
    }

    @Test
    fun testIsTopActivityExemptFromDesktopWindowing_packageInConfigExemptionList() {
        assertTrue(desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
            createFreeformTask(/* displayId */ 0)
                .apply {
                    baseActivity = configExemptActivity
                    isTopActivityNoDisplay = false
                }))
    }

    @Test
    fun testIsTopActivityExemptFromDesktopWindowing_packageInConfigExemptionList_transparentTask() {
        assertFalse(desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
            createFreeformTask(/* displayId */ 0)
                .apply {
                    baseActivity = configExemptActivity
                    isTopActivityNoDisplay = false
                    isActivityStackTransparent = true
                }))
    }

    @Test
    fun testShouldDisableDesktopEntryPoints_noDisplayActivity() {
        assertTrue(desktopModeCompatPolicy.shouldDisableDesktopEntryPoints(
@@ -321,7 +353,7 @@ class DesktopModeCompatPolicyTest : ShellTestCase() {
    @Test
    fun testShouldDisableDesktopEntryPoints_defaultHomePackage_notYetAvailable() {
        val emptyHomeActivities: ComponentName = mock()
        mContext.setMockPackageManager(packageManager)
        mockContext.setMockPackageManager(packageManager)

        whenever(emptyHomeActivities.packageName).thenReturn(null)
        whenever(packageManager.getHomeActivities(any())).thenReturn(emptyHomeActivities)
@@ -341,6 +373,15 @@ class DesktopModeCompatPolicyTest : ShellTestCase() {
                }))
    }

    @Test
    fun testShouldDisableDesktopEntryPoints_packageInConfigExemptionList() {
        assertTrue(desktopModeCompatPolicy.shouldDisableDesktopEntryPoints(
            createFreeformTask(/* displayId */ 0)
                .apply {
                    baseActivity = configExemptActivity
                }))
    }

    @Test
    @EnableFlags(Flags.FLAG_EXCLUDE_CAPTION_FROM_APP_BOUNDS)
    @DisableCompatChanges(ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED)
@@ -383,7 +424,7 @@ class DesktopModeCompatPolicyTest : ShellTestCase() {
        createFreeformTask().apply {
            val componentName =
                ComponentName.createRelative(
                    mContext,
                    mockContext,
                    DesktopModeCompatPolicyTest::class.java.simpleName
                )
            baseActivity = componentName