Merge "[Partial Screensharing] Support enterprise policy" into udc-dev am: fb1f31f8ad
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23316819 Change-Id: Ic708328e4fa3f3676432441f8ff725da835b5803 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -38,8 +38,6 @@ import com.android.internal.app.ResolverListController
|
|||||||
import com.android.internal.app.chooser.NotSelectableTargetInfo
|
import com.android.internal.app.chooser.NotSelectableTargetInfo
|
||||||
import com.android.internal.app.chooser.TargetInfo
|
import com.android.internal.app.chooser.TargetInfo
|
||||||
import com.android.systemui.R
|
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.MediaProjectionAppSelectorComponent
|
||||||
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorController
|
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorController
|
||||||
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler
|
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler
|
||||||
@@ -53,7 +51,6 @@ import javax.inject.Inject
|
|||||||
class MediaProjectionAppSelectorActivity(
|
class MediaProjectionAppSelectorActivity(
|
||||||
private val componentFactory: MediaProjectionAppSelectorComponent.Factory,
|
private val componentFactory: MediaProjectionAppSelectorComponent.Factory,
|
||||||
private val activityLauncher: AsyncActivityLauncher,
|
private val activityLauncher: AsyncActivityLauncher,
|
||||||
private val featureFlags: FeatureFlags,
|
|
||||||
/** This is used to override the dependency in a screenshot test */
|
/** This is used to override the dependency in a screenshot test */
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
private val listControllerFactory: ((userHandle: UserHandle) -> ResolverListController)?
|
private val listControllerFactory: ((userHandle: UserHandle) -> ResolverListController)?
|
||||||
@@ -62,9 +59,8 @@ class MediaProjectionAppSelectorActivity(
|
|||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
componentFactory: MediaProjectionAppSelectorComponent.Factory,
|
componentFactory: MediaProjectionAppSelectorComponent.Factory,
|
||||||
activityLauncher: AsyncActivityLauncher,
|
activityLauncher: AsyncActivityLauncher
|
||||||
featureFlags: FeatureFlags
|
) : this(componentFactory, activityLauncher, listControllerFactory = null)
|
||||||
) : this(componentFactory, activityLauncher, featureFlags, listControllerFactory = null)
|
|
||||||
|
|
||||||
private lateinit var configurationController: ConfigurationController
|
private lateinit var configurationController: ConfigurationController
|
||||||
private lateinit var controller: MediaProjectionAppSelectorController
|
private lateinit var controller: MediaProjectionAppSelectorController
|
||||||
@@ -108,11 +104,7 @@ class MediaProjectionAppSelectorActivity(
|
|||||||
override fun appliedThemeResId(): Int = R.style.Theme_SystemUI_MediaProjectionAppSelector
|
override fun appliedThemeResId(): Int = R.style.Theme_SystemUI_MediaProjectionAppSelector
|
||||||
|
|
||||||
override fun createBlockerEmptyStateProvider(): EmptyStateProvider =
|
override fun createBlockerEmptyStateProvider(): EmptyStateProvider =
|
||||||
if (featureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES)) {
|
|
||||||
component.emptyStateProvider
|
component.emptyStateProvider
|
||||||
} else {
|
|
||||||
object : EmptyStateProvider {}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createListController(userHandle: UserHandle): ResolverListController =
|
override fun createListController(userHandle: UserHandle): ResolverListController =
|
||||||
listControllerFactory?.invoke(userHandle) ?: super.createListController(userHandle)
|
listControllerFactory?.invoke(userHandle) ?: super.createListController(userHandle)
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ package com.android.systemui.mediaprojection.appselector
|
|||||||
|
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.os.UserHandle
|
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.RecentTask
|
||||||
import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
|
import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
|
||||||
|
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
@@ -32,7 +32,7 @@ class MediaProjectionAppSelectorController
|
|||||||
constructor(
|
constructor(
|
||||||
private val recentTaskListProvider: RecentTaskListProvider,
|
private val recentTaskListProvider: RecentTaskListProvider,
|
||||||
private val view: MediaProjectionAppSelectorView,
|
private val view: MediaProjectionAppSelectorView,
|
||||||
private val flags: FeatureFlags,
|
private val devicePolicyResolver: ScreenCaptureDevicePolicyResolver,
|
||||||
@HostUserHandle private val hostUserHandle: UserHandle,
|
@HostUserHandle private val hostUserHandle: UserHandle,
|
||||||
@MediaProjectionAppSelector private val scope: CoroutineScope,
|
@MediaProjectionAppSelector private val scope: CoroutineScope,
|
||||||
@MediaProjectionAppSelector private val appSelectorComponentName: ComponentName,
|
@MediaProjectionAppSelector private val appSelectorComponentName: ComponentName,
|
||||||
@@ -54,11 +54,13 @@ constructor(
|
|||||||
scope.cancel()
|
scope.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Removes all recent tasks that should be blocked according to the policy */
|
||||||
* Removes all recent tasks that are different from the profile of the host app to avoid any
|
private fun List<RecentTask>.filterDevicePolicyRestrictedTasks(): List<RecentTask> = filter {
|
||||||
* cross-profile sharing
|
devicePolicyResolver.isScreenCaptureAllowed(
|
||||||
*/
|
targetAppUserHandle = UserHandle.of(it.userId),
|
||||||
private fun List<RecentTask>.filterDevicePolicyRestrictedTasks(): List<RecentTask> = this
|
hostAppUserHandle = hostUserHandle
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun List<RecentTask>.filterAppSelector(): List<RecentTask> = filter {
|
private fun List<RecentTask>.filterAppSelector(): List<RecentTask> = filter {
|
||||||
// Only take tasks that is not the app selector
|
// Only take tasks that is not the app selector
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ constructor(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hostAppUserHandle.isWorkProfile() && personalProfileScreenCaptureDisabled) {
|
if (personalProfileScreenCaptureDisabled) {
|
||||||
// Disable screen capturing as personal apps should not capture the screen
|
// Disable screen capturing as personal apps should not capture the screen
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,15 @@ import android.os.UserHandle
|
|||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
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.RecentTask
|
||||||
import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
|
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.mock
|
||||||
import com.android.systemui.util.mockito.whenever
|
import com.android.systemui.util.mockito.whenever
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
@@ -27,23 +28,28 @@ class MediaProjectionAppSelectorControllerTest : SysuiTestCase() {
|
|||||||
private val callerPackageName = "com.test.caller"
|
private val callerPackageName = "com.test.caller"
|
||||||
private val callerComponentName = ComponentName(callerPackageName, "Caller")
|
private val callerComponentName = ComponentName(callerPackageName, "Caller")
|
||||||
|
|
||||||
private val hostUserHandle = UserHandle.of(123)
|
private val personalUserHandle = UserHandle.of(123)
|
||||||
private val otherUserHandle = UserHandle.of(456)
|
private val workUserHandle = UserHandle.of(456)
|
||||||
|
|
||||||
private val view: MediaProjectionAppSelectorView = mock()
|
private val view: MediaProjectionAppSelectorView = mock()
|
||||||
private val featureFlags: FeatureFlags = mock()
|
private val policyResolver: ScreenCaptureDevicePolicyResolver = mock()
|
||||||
|
|
||||||
private val controller =
|
private val controller =
|
||||||
MediaProjectionAppSelectorController(
|
MediaProjectionAppSelectorController(
|
||||||
taskListProvider,
|
taskListProvider,
|
||||||
view,
|
view,
|
||||||
featureFlags,
|
policyResolver,
|
||||||
hostUserHandle,
|
personalUserHandle,
|
||||||
scope,
|
scope,
|
||||||
appSelectorComponentName,
|
appSelectorComponentName,
|
||||||
callerPackageName
|
callerPackageName
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
givenCaptureAllowed(isAllow = true)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun initNoRecentTasks_bindsEmptyList() {
|
fun initNoRecentTasks_bindsEmptyList() {
|
||||||
taskListProvider.tasks = emptyList()
|
taskListProvider.tasks = emptyList()
|
||||||
@@ -132,73 +138,57 @@ class MediaProjectionAppSelectorControllerTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesDisabled_bindsAllTasks() {
|
fun initRecentTasksWithAppSelectorTasks_withEnterprisePolicies_bindsAllTasks() {
|
||||||
givenEnterprisePoliciesFeatureFlag(enabled = false)
|
|
||||||
|
|
||||||
val tasks =
|
val tasks =
|
||||||
listOf(
|
listOf(
|
||||||
createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
|
createRecentTask(taskId = 1, userId = personalUserHandle.identifier),
|
||||||
createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
|
createRecentTask(taskId = 2, userId = workUserHandle.identifier),
|
||||||
createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
|
createRecentTask(taskId = 3, userId = personalUserHandle.identifier),
|
||||||
createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
|
createRecentTask(taskId = 4, userId = workUserHandle.identifier),
|
||||||
createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
|
createRecentTask(taskId = 5, userId = personalUserHandle.identifier),
|
||||||
)
|
)
|
||||||
taskListProvider.tasks = tasks
|
taskListProvider.tasks = tasks
|
||||||
|
|
||||||
controller.init()
|
controller.init()
|
||||||
|
|
||||||
// TODO (b/263950746): Cross-profile filtering is removed for now. This should be brought
|
|
||||||
// back with the future fix
|
|
||||||
verify(view)
|
verify(view)
|
||||||
.bind(
|
.bind(
|
||||||
listOf(
|
listOf(
|
||||||
createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
|
createRecentTask(taskId = 1, userId = personalUserHandle.identifier),
|
||||||
createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
|
createRecentTask(taskId = 2, userId = workUserHandle.identifier),
|
||||||
createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
|
createRecentTask(taskId = 3, userId = personalUserHandle.identifier),
|
||||||
createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
|
createRecentTask(taskId = 4, userId = workUserHandle.identifier),
|
||||||
createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
|
createRecentTask(taskId = 5, userId = personalUserHandle.identifier),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesEnabled_bindsAllTasks() {
|
fun initRecentTasksWithAppSelectorTasks_withEnterprisePolicies_blocksAllTasks() {
|
||||||
givenEnterprisePoliciesFeatureFlag(enabled = true)
|
|
||||||
|
|
||||||
val tasks =
|
val tasks =
|
||||||
listOf(
|
listOf(
|
||||||
createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
|
createRecentTask(taskId = 1, userId = personalUserHandle.identifier),
|
||||||
createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
|
createRecentTask(taskId = 2, userId = workUserHandle.identifier),
|
||||||
createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
|
createRecentTask(taskId = 3, userId = personalUserHandle.identifier),
|
||||||
createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
|
createRecentTask(taskId = 4, userId = workUserHandle.identifier),
|
||||||
createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
|
createRecentTask(taskId = 5, userId = personalUserHandle.identifier),
|
||||||
)
|
)
|
||||||
taskListProvider.tasks = tasks
|
taskListProvider.tasks = tasks
|
||||||
|
|
||||||
|
givenCaptureAllowed(isAllow = false)
|
||||||
controller.init()
|
controller.init()
|
||||||
|
|
||||||
// TODO(b/233348916) should filter depending on the policies
|
verify(view).bind(emptyList())
|
||||||
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),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun givenEnterprisePoliciesFeatureFlag(enabled: Boolean) {
|
private fun givenCaptureAllowed(isAllow: Boolean) {
|
||||||
whenever(featureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES))
|
whenever(policyResolver.isScreenCaptureAllowed(any(), any())).thenReturn(isAllow)
|
||||||
.thenReturn(enabled)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createRecentTask(
|
private fun createRecentTask(
|
||||||
taskId: Int,
|
taskId: Int,
|
||||||
topActivityComponent: ComponentName? = null,
|
topActivityComponent: ComponentName? = null,
|
||||||
userId: Int = hostUserHandle.identifier
|
userId: Int = personalUserHandle.identifier
|
||||||
): RecentTask {
|
): RecentTask {
|
||||||
return RecentTask(
|
return RecentTask(
|
||||||
taskId = taskId,
|
taskId = taskId,
|
||||||
|
|||||||
@@ -400,28 +400,6 @@ class IsAllowedScreenCaptureDevicePolicyResolverTest(
|
|||||||
),
|
),
|
||||||
expectedScreenCaptureAllowed = false,
|
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(
|
IsScreenCaptureAllowedTestCase(
|
||||||
given =
|
given =
|
||||||
Preconditions(
|
Preconditions(
|
||||||
@@ -621,26 +599,6 @@ class IsCompletelyNotAllowedScreenCaptureDevicePolicyResolverTest(
|
|||||||
),
|
),
|
||||||
expectedScreenCaptureCompletelyDisabled = true,
|
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(
|
IsScreenCaptureCompletelyDisabledTestCase(
|
||||||
given =
|
given =
|
||||||
Preconditions(
|
Preconditions(
|
||||||
@@ -686,7 +644,8 @@ class IsCompletelyNotAllowedScreenCaptureDevicePolicyResolverTest(
|
|||||||
"personal screen capture disabled = ${given.personalScreenCaptureDisabled}, " +
|
"personal screen capture disabled = ${given.personalScreenCaptureDisabled}, " +
|
||||||
"work screen capture disabled = ${given.workScreenCaptureDisabled}, " +
|
"work screen capture disabled = ${given.workScreenCaptureDisabled}, " +
|
||||||
"disallow share into managed profile = ${given.disallowShareIntoManagedProfile}, " +
|
"disallow share into managed profile = ${given.disallowShareIntoManagedProfile}, " +
|
||||||
"expected screen capture completely disabled = $expectedScreenCaptureCompletelyDisabled"
|
"expected screen capture completely disabled = " +
|
||||||
|
"$expectedScreenCaptureCompletelyDisabled"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user