Merge "Camera quick affordance respects device policy." into tm-qpr-dev
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
package com.android.systemui.keyguard.data.quickaffordance
|
||||
|
||||
import android.app.StatusBarManager
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import com.android.systemui.R
|
||||
@@ -27,10 +28,14 @@ import com.android.systemui.common.shared.model.ContentDescription
|
||||
import com.android.systemui.common.shared.model.Icon
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import dagger.Lazy
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@SysUISingleton
|
||||
class CameraQuickAffordanceConfig
|
||||
@@ -39,6 +44,9 @@ constructor(
|
||||
@Application private val context: Context,
|
||||
private val packageManager: PackageManager,
|
||||
private val cameraGestureHelper: Lazy<CameraGestureHelper>,
|
||||
private val userTracker: UserTracker,
|
||||
private val devicePolicyManager: DevicePolicyManager,
|
||||
@Background private val backgroundDispatcher: CoroutineDispatcher,
|
||||
) : KeyguardQuickAffordanceConfig {
|
||||
|
||||
override val key: String
|
||||
@@ -79,7 +87,12 @@ constructor(
|
||||
return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
|
||||
}
|
||||
|
||||
private fun isLaunchable(): Boolean {
|
||||
return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
|
||||
private suspend fun isLaunchable(): Boolean {
|
||||
return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) &&
|
||||
withContext(backgroundDispatcher) {
|
||||
!devicePolicyManager.getCameraDisabled(null, userTracker.userId) &&
|
||||
devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId) and
|
||||
DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package com.android.systemui.keyguard.data.quickaffordance
|
||||
|
||||
import android.app.StatusBarManager
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.android.systemui.ActivityIntentHelper
|
||||
@@ -29,10 +30,13 @@ import com.android.systemui.common.shared.model.ContentDescription
|
||||
import com.android.systemui.common.shared.model.Icon
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@SysUISingleton
|
||||
class VideoCameraQuickAffordanceConfig
|
||||
@@ -42,6 +46,8 @@ constructor(
|
||||
private val cameraIntents: CameraIntentsWrapper,
|
||||
private val activityIntentHelper: ActivityIntentHelper,
|
||||
private val userTracker: UserTracker,
|
||||
private val devicePolicyManager: DevicePolicyManager,
|
||||
@Background private val backgroundDispatcher: CoroutineDispatcher,
|
||||
) : KeyguardQuickAffordanceConfig {
|
||||
|
||||
private val intent: Intent by lazy {
|
||||
@@ -63,8 +69,8 @@ constructor(
|
||||
get() = R.drawable.ic_videocam
|
||||
|
||||
override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState>
|
||||
get() =
|
||||
flowOf(
|
||||
get() = flow {
|
||||
emit(
|
||||
if (isLaunchable()) {
|
||||
KeyguardQuickAffordanceConfig.LockScreenState.Visible(
|
||||
icon =
|
||||
@@ -77,6 +83,7 @@ constructor(
|
||||
KeyguardQuickAffordanceConfig.LockScreenState.Hidden
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
|
||||
return if (isLaunchable()) {
|
||||
@@ -95,11 +102,14 @@ constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun isLaunchable(): Boolean {
|
||||
private suspend fun isLaunchable(): Boolean {
|
||||
return activityIntentHelper.getTargetActivityInfo(
|
||||
intent,
|
||||
userTracker.userId,
|
||||
true,
|
||||
) != null
|
||||
) != null &&
|
||||
withContext(backgroundDispatcher) {
|
||||
!devicePolicyManager.getCameraDisabled(null, userTracker.userId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,15 +18,19 @@
|
||||
package com.android.systemui.keyguard.data.quickaffordance
|
||||
|
||||
import android.app.StatusBarManager
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.camera.CameraGestureHelper
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.google.common.truth.Truth
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
@@ -44,21 +48,28 @@ class CameraQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
@Mock private lateinit var cameraGestureHelper: CameraGestureHelper
|
||||
@Mock private lateinit var context: Context
|
||||
@Mock private lateinit var packageManager: PackageManager
|
||||
@Mock private lateinit var userTracker: UserTracker
|
||||
@Mock private lateinit var devicePolicyManager: DevicePolicyManager
|
||||
|
||||
private lateinit var underTest: CameraQuickAffordanceConfig
|
||||
private lateinit var testScope: TestScope
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
setLaunchable(true)
|
||||
setLaunchable()
|
||||
|
||||
val testDispatcher = StandardTestDispatcher()
|
||||
testScope = TestScope(testDispatcher)
|
||||
underTest =
|
||||
CameraQuickAffordanceConfig(
|
||||
context,
|
||||
packageManager,
|
||||
) {
|
||||
cameraGestureHelper
|
||||
}
|
||||
{ cameraGestureHelper },
|
||||
userTracker,
|
||||
devicePolicyManager,
|
||||
testDispatcher,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -73,23 +84,57 @@ class CameraQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPickerScreenState - default when launchable`() = runTest {
|
||||
setLaunchable(true)
|
||||
fun `getPickerScreenState - default when launchable`() =
|
||||
testScope.runTest {
|
||||
setLaunchable(true)
|
||||
|
||||
Truth.assertThat(underTest.getPickerScreenState())
|
||||
.isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java)
|
||||
}
|
||||
Truth.assertThat(underTest.getPickerScreenState())
|
||||
.isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPickerScreenState - unavailable when not launchable`() = runTest {
|
||||
setLaunchable(false)
|
||||
fun `getPickerScreenState - unavailable when camera app not installed`() =
|
||||
testScope.runTest {
|
||||
setLaunchable(isCameraAppInstalled = false)
|
||||
|
||||
Truth.assertThat(underTest.getPickerScreenState())
|
||||
.isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
|
||||
}
|
||||
Truth.assertThat(underTest.getPickerScreenState())
|
||||
.isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
|
||||
}
|
||||
|
||||
private fun setLaunchable(isLaunchable: Boolean) {
|
||||
@Test
|
||||
fun `getPickerScreenState - unavailable when camera disabled by admin`() =
|
||||
testScope.runTest {
|
||||
setLaunchable(isCameraDisabledByDeviceAdmin = true)
|
||||
|
||||
Truth.assertThat(underTest.getPickerScreenState())
|
||||
.isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPickerScreenState - unavailable when secure camera disabled by admin`() =
|
||||
testScope.runTest {
|
||||
setLaunchable(isSecureCameraDisabledByDeviceAdmin = true)
|
||||
|
||||
Truth.assertThat(underTest.getPickerScreenState())
|
||||
.isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
|
||||
}
|
||||
|
||||
private fun setLaunchable(
|
||||
isCameraAppInstalled: Boolean = true,
|
||||
isCameraDisabledByDeviceAdmin: Boolean = false,
|
||||
isSecureCameraDisabledByDeviceAdmin: Boolean = false,
|
||||
) {
|
||||
whenever(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY))
|
||||
.thenReturn(isLaunchable)
|
||||
.thenReturn(isCameraAppInstalled)
|
||||
whenever(devicePolicyManager.getCameraDisabled(null, userTracker.userId))
|
||||
.thenReturn(isCameraDisabledByDeviceAdmin)
|
||||
whenever(devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId))
|
||||
.thenReturn(
|
||||
if (isSecureCameraDisabledByDeviceAdmin) {
|
||||
DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA
|
||||
} else {
|
||||
0
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package com.android.systemui.keyguard.data.quickaffordance
|
||||
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.ActivityIntentHelper
|
||||
@@ -24,11 +25,14 @@ import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.camera.CameraIntentsWrapper
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.settings.FakeUserTracker
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@@ -44,59 +48,94 @@ import org.mockito.MockitoAnnotations
|
||||
class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var activityIntentHelper: ActivityIntentHelper
|
||||
@Mock private lateinit var devicePolicyManager: DevicePolicyManager
|
||||
|
||||
private lateinit var underTest: VideoCameraQuickAffordanceConfig
|
||||
private lateinit var userTracker: UserTracker
|
||||
private lateinit var testScope: TestScope
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
val testDispatcher = StandardTestDispatcher()
|
||||
testScope = TestScope(testDispatcher)
|
||||
userTracker = FakeUserTracker()
|
||||
underTest =
|
||||
VideoCameraQuickAffordanceConfig(
|
||||
context = context,
|
||||
cameraIntents = CameraIntentsWrapper(context),
|
||||
activityIntentHelper = activityIntentHelper,
|
||||
userTracker = FakeUserTracker(),
|
||||
userTracker = userTracker,
|
||||
devicePolicyManager = devicePolicyManager,
|
||||
backgroundDispatcher = testDispatcher,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `lockScreenState - visible when launchable`() = runTest {
|
||||
setLaunchable(true)
|
||||
fun `lockScreenState - visible when launchable`() =
|
||||
testScope.runTest {
|
||||
setLaunchable()
|
||||
|
||||
val lockScreenState = collectLastValue(underTest.lockScreenState)
|
||||
val lockScreenState = collectLastValue(underTest.lockScreenState)
|
||||
|
||||
assertThat(lockScreenState())
|
||||
.isInstanceOf(KeyguardQuickAffordanceConfig.LockScreenState.Visible::class.java)
|
||||
}
|
||||
assertThat(lockScreenState())
|
||||
.isInstanceOf(KeyguardQuickAffordanceConfig.LockScreenState.Visible::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `lockScreenState - hidden when not launchable`() = runTest {
|
||||
setLaunchable(false)
|
||||
fun `lockScreenState - hidden when app not installed on device`() =
|
||||
testScope.runTest {
|
||||
setLaunchable(isVideoCameraAppInstalled = false)
|
||||
|
||||
val lockScreenState = collectLastValue(underTest.lockScreenState)
|
||||
val lockScreenState = collectLastValue(underTest.lockScreenState)
|
||||
|
||||
assertThat(lockScreenState())
|
||||
.isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
|
||||
}
|
||||
assertThat(lockScreenState())
|
||||
.isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPickerScreenState - default when launchable`() = runTest {
|
||||
setLaunchable(true)
|
||||
fun `lockScreenState - hidden when camera disabled by admin`() =
|
||||
testScope.runTest {
|
||||
setLaunchable(isCameraDisabledByAdmin = true)
|
||||
|
||||
assertThat(underTest.getPickerScreenState())
|
||||
.isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java)
|
||||
}
|
||||
val lockScreenState = collectLastValue(underTest.lockScreenState)
|
||||
|
||||
assertThat(lockScreenState())
|
||||
.isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPickerScreenState - unavailable when not launchable`() = runTest {
|
||||
setLaunchable(false)
|
||||
fun `getPickerScreenState - default when launchable`() =
|
||||
testScope.runTest {
|
||||
setLaunchable()
|
||||
|
||||
assertThat(underTest.getPickerScreenState())
|
||||
.isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
|
||||
}
|
||||
assertThat(underTest.getPickerScreenState())
|
||||
.isInstanceOf(KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java)
|
||||
}
|
||||
|
||||
private fun setLaunchable(isLaunchable: Boolean) {
|
||||
@Test
|
||||
fun `getPickerScreenState - unavailable when app not installed on device`() =
|
||||
testScope.runTest {
|
||||
setLaunchable(isVideoCameraAppInstalled = false)
|
||||
|
||||
assertThat(underTest.getPickerScreenState())
|
||||
.isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPickerScreenState - unavailable when camera disabled by admin`() =
|
||||
testScope.runTest {
|
||||
setLaunchable(isCameraDisabledByAdmin = true)
|
||||
|
||||
assertThat(underTest.getPickerScreenState())
|
||||
.isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
|
||||
}
|
||||
|
||||
private fun setLaunchable(
|
||||
isVideoCameraAppInstalled: Boolean = true,
|
||||
isCameraDisabledByAdmin: Boolean = false,
|
||||
) {
|
||||
whenever(
|
||||
activityIntentHelper.getTargetActivityInfo(
|
||||
any(),
|
||||
@@ -105,11 +144,13 @@ class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
)
|
||||
)
|
||||
.thenReturn(
|
||||
if (isLaunchable) {
|
||||
if (isVideoCameraAppInstalled) {
|
||||
mock()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
)
|
||||
whenever(devicePolicyManager.getCameraDisabled(null, userTracker.userId))
|
||||
.thenReturn(isCameraDisabledByAdmin)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user