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

Commit 08dfef3b authored by Yalan Yiue's avatar Yalan Yiue Committed by Automerger Merge Worker
Browse files

Merge "[Partial Screensharing] Support enterprise policy" into udc-dev am: fb1f31f8

parents ac5005d6 fb1f31f8
Loading
Loading
Loading
Loading
+3 −11
Original line number Diff line number Diff line
@@ -38,8 +38,6 @@ import com.android.internal.app.ResolverListController
import com.android.internal.app.chooser.NotSelectableTargetInfo
import com.android.internal.app.chooser.TargetInfo
import com.android.systemui.R
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorComponent
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorController
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler
@@ -53,7 +51,6 @@ import javax.inject.Inject
class MediaProjectionAppSelectorActivity(
    private val componentFactory: MediaProjectionAppSelectorComponent.Factory,
    private val activityLauncher: AsyncActivityLauncher,
    private val featureFlags: FeatureFlags,
    /** This is used to override the dependency in a screenshot test */
    @VisibleForTesting
    private val listControllerFactory: ((userHandle: UserHandle) -> ResolverListController)?
@@ -62,9 +59,8 @@ class MediaProjectionAppSelectorActivity(
    @Inject
    constructor(
        componentFactory: MediaProjectionAppSelectorComponent.Factory,
        activityLauncher: AsyncActivityLauncher,
        featureFlags: FeatureFlags
    ) : this(componentFactory, activityLauncher, featureFlags, listControllerFactory = null)
        activityLauncher: AsyncActivityLauncher
    ) : this(componentFactory, activityLauncher, listControllerFactory = null)

    private lateinit var configurationController: ConfigurationController
    private lateinit var controller: MediaProjectionAppSelectorController
@@ -108,11 +104,7 @@ class MediaProjectionAppSelectorActivity(
    override fun appliedThemeResId(): Int = R.style.Theme_SystemUI_MediaProjectionAppSelector

    override fun createBlockerEmptyStateProvider(): EmptyStateProvider =
        if (featureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES)) {
        component.emptyStateProvider
        } else {
            object : EmptyStateProvider {}
        }

    override fun createListController(userHandle: UserHandle): ResolverListController =
        listControllerFactory?.invoke(userHandle) ?: super.createListController(userHandle)
+9 −7
Original line number Diff line number Diff line
@@ -18,9 +18,9 @@ package com.android.systemui.mediaprojection.appselector

import android.content.ComponentName
import android.os.UserHandle
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.mediaprojection.appselector.data.RecentTask
import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
@@ -32,7 +32,7 @@ class MediaProjectionAppSelectorController
constructor(
    private val recentTaskListProvider: RecentTaskListProvider,
    private val view: MediaProjectionAppSelectorView,
    private val flags: FeatureFlags,
    private val devicePolicyResolver: ScreenCaptureDevicePolicyResolver,
    @HostUserHandle private val hostUserHandle: UserHandle,
    @MediaProjectionAppSelector private val scope: CoroutineScope,
    @MediaProjectionAppSelector private val appSelectorComponentName: ComponentName,
@@ -54,11 +54,13 @@ constructor(
        scope.cancel()
    }

    /**
     * Removes all recent tasks that are different from the profile of the host app to avoid any
     * cross-profile sharing
     */
    private fun List<RecentTask>.filterDevicePolicyRestrictedTasks(): List<RecentTask> = this
    /** Removes all recent tasks that should be blocked according to the policy */
    private fun List<RecentTask>.filterDevicePolicyRestrictedTasks(): List<RecentTask> = filter {
        devicePolicyResolver.isScreenCaptureAllowed(
            targetAppUserHandle = UserHandle.of(it.userId),
            hostAppUserHandle = hostUserHandle
        )
    }

    private fun List<RecentTask>.filterAppSelector(): List<RecentTask> = filter {
        // Only take tasks that is not the app selector
+1 −1
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ constructor(
            return false
        }

        if (!hostAppUserHandle.isWorkProfile() && personalProfileScreenCaptureDisabled) {
        if (personalProfileScreenCaptureDisabled) {
            // Disable screen capturing as personal apps should not capture the screen
            return false
        }
+35 −45
Original line number Diff line number Diff line
@@ -5,14 +5,15 @@ import android.os.UserHandle
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.mediaprojection.appselector.data.RecentTask
import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.verify
@@ -27,23 +28,28 @@ class MediaProjectionAppSelectorControllerTest : SysuiTestCase() {
    private val callerPackageName = "com.test.caller"
    private val callerComponentName = ComponentName(callerPackageName, "Caller")

    private val hostUserHandle = UserHandle.of(123)
    private val otherUserHandle = UserHandle.of(456)
    private val personalUserHandle = UserHandle.of(123)
    private val workUserHandle = UserHandle.of(456)

    private val view: MediaProjectionAppSelectorView = mock()
    private val featureFlags: FeatureFlags = mock()
    private val policyResolver: ScreenCaptureDevicePolicyResolver = mock()

    private val controller =
        MediaProjectionAppSelectorController(
            taskListProvider,
            view,
            featureFlags,
            hostUserHandle,
            policyResolver,
            personalUserHandle,
            scope,
            appSelectorComponentName,
            callerPackageName
        )

    @Before
    fun setup() {
        givenCaptureAllowed(isAllow = true)
    }

    @Test
    fun initNoRecentTasks_bindsEmptyList() {
        taskListProvider.tasks = emptyList()
@@ -132,73 +138,57 @@ class MediaProjectionAppSelectorControllerTest : SysuiTestCase() {
    }

    @Test
    fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesDisabled_bindsAllTasks() {
        givenEnterprisePoliciesFeatureFlag(enabled = false)

    fun initRecentTasksWithAppSelectorTasks_withEnterprisePolicies_bindsAllTasks() {
        val tasks =
            listOf(
                createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
                createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
                createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
                createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
                createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
                createRecentTask(taskId = 1, userId = personalUserHandle.identifier),
                createRecentTask(taskId = 2, userId = workUserHandle.identifier),
                createRecentTask(taskId = 3, userId = personalUserHandle.identifier),
                createRecentTask(taskId = 4, userId = workUserHandle.identifier),
                createRecentTask(taskId = 5, userId = personalUserHandle.identifier),
            )
        taskListProvider.tasks = tasks

        controller.init()

        // TODO (b/263950746): Cross-profile filtering is removed for now. This should be brought
        // back with the future fix
        verify(view)
            .bind(
                listOf(
                    createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
                    createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
                    createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
                    createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
                    createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
                    createRecentTask(taskId = 1, userId = personalUserHandle.identifier),
                    createRecentTask(taskId = 2, userId = workUserHandle.identifier),
                    createRecentTask(taskId = 3, userId = personalUserHandle.identifier),
                    createRecentTask(taskId = 4, userId = workUserHandle.identifier),
                    createRecentTask(taskId = 5, userId = personalUserHandle.identifier),
                )
            )
    }

    @Test
    fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesEnabled_bindsAllTasks() {
        givenEnterprisePoliciesFeatureFlag(enabled = true)

    fun initRecentTasksWithAppSelectorTasks_withEnterprisePolicies_blocksAllTasks() {
        val tasks =
            listOf(
                createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
                createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
                createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
                createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
                createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
                createRecentTask(taskId = 1, userId = personalUserHandle.identifier),
                createRecentTask(taskId = 2, userId = workUserHandle.identifier),
                createRecentTask(taskId = 3, userId = personalUserHandle.identifier),
                createRecentTask(taskId = 4, userId = workUserHandle.identifier),
                createRecentTask(taskId = 5, userId = personalUserHandle.identifier),
            )
        taskListProvider.tasks = tasks

        givenCaptureAllowed(isAllow = false)
        controller.init()

        // TODO(b/233348916) should filter depending on the policies
        verify(view)
            .bind(
                listOf(
                    createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
                    createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
                    createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
                    createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
                    createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
                )
            )
        verify(view).bind(emptyList())
    }

    private fun givenEnterprisePoliciesFeatureFlag(enabled: Boolean) {
        whenever(featureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES))
            .thenReturn(enabled)
    private fun givenCaptureAllowed(isAllow: Boolean) {
        whenever(policyResolver.isScreenCaptureAllowed(any(), any())).thenReturn(isAllow)
    }

    private fun createRecentTask(
        taskId: Int,
        topActivityComponent: ComponentName? = null,
        userId: Int = hostUserHandle.identifier
        userId: Int = personalUserHandle.identifier
    ): RecentTask {
        return RecentTask(
            taskId = taskId,
+2 −43
Original line number Diff line number Diff line
@@ -400,28 +400,6 @@ class IsAllowedScreenCaptureDevicePolicyResolverTest(
                        ),
                    expectedScreenCaptureAllowed = false,
                ),
                IsScreenCaptureAllowedTestCase(
                    given =
                        Preconditions(
                            isHostInWorkProfile = true,
                            isTargetInWorkProfile = true,
                            personalScreenCaptureDisabled = true,
                            workScreenCaptureDisabled = false,
                            disallowShareIntoManagedProfile = false
                        ),
                    expectedScreenCaptureAllowed = true,
                ),
                IsScreenCaptureAllowedTestCase(
                    given =
                        Preconditions(
                            isHostInWorkProfile = true,
                            isTargetInWorkProfile = true,
                            personalScreenCaptureDisabled = true,
                            workScreenCaptureDisabled = false,
                            disallowShareIntoManagedProfile = true
                        ),
                    expectedScreenCaptureAllowed = true,
                ),
                IsScreenCaptureAllowedTestCase(
                    given =
                        Preconditions(
@@ -621,26 +599,6 @@ class IsCompletelyNotAllowedScreenCaptureDevicePolicyResolverTest(
                        ),
                    expectedScreenCaptureCompletelyDisabled = true,
                ),
                IsScreenCaptureCompletelyDisabledTestCase(
                    given =
                        Preconditions(
                            isHostInWorkProfile = true,
                            personalScreenCaptureDisabled = true,
                            workScreenCaptureDisabled = false,
                            disallowShareIntoManagedProfile = false
                        ),
                    expectedScreenCaptureCompletelyDisabled = false,
                ),
                IsScreenCaptureCompletelyDisabledTestCase(
                    given =
                        Preconditions(
                            isHostInWorkProfile = true,
                            personalScreenCaptureDisabled = true,
                            workScreenCaptureDisabled = false,
                            disallowShareIntoManagedProfile = true
                        ),
                    expectedScreenCaptureCompletelyDisabled = false,
                ),
                IsScreenCaptureCompletelyDisabledTestCase(
                    given =
                        Preconditions(
@@ -686,7 +644,8 @@ class IsCompletelyNotAllowedScreenCaptureDevicePolicyResolverTest(
                "personal screen capture disabled = ${given.personalScreenCaptureDisabled}, " +
                "work screen capture disabled = ${given.workScreenCaptureDisabled}, " +
                "disallow share into managed profile = ${given.disallowShareIntoManagedProfile}, " +
                "expected screen capture completely disabled = $expectedScreenCaptureCompletelyDisabled"
                "expected screen capture completely disabled = " +
                "$expectedScreenCaptureCompletelyDisabled"
    }

    @Test