Show policy transparent of "Force stop" when no DO
PackageManager.isPackageStateProtected() is moving to permission based, so force stop button can also be protected when no DeviceOwner. The ActivityManger side has already handled correctly, no Settings UI side need to show a device policy transparent dialog. Fix: 319579347 Test: manual - Force stop on AppInfo Test: unit test Change-Id: I4432dcb798a0cfcbb6bfc8b30c9191dd91b980a2
This commit is contained in:
@@ -19,6 +19,7 @@ package com.android.settings.spa.app.appinfo
|
|||||||
import android.app.settings.SettingsEnums
|
import android.app.settings.SettingsEnums
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Report
|
import androidx.compose.material.icons.outlined.Report
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@@ -87,9 +88,10 @@ class AppForceStopButton(
|
|||||||
dialogPresenter.open()
|
dialogPresenter.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAdminRestriction(app: ApplicationInfo): EnforcedAdmin? = when {
|
@VisibleForTesting
|
||||||
|
fun getAdminRestriction(app: ApplicationInfo): EnforcedAdmin? = when {
|
||||||
packageManager.isPackageStateProtected(app.packageName, app.userId) -> {
|
packageManager.isPackageStateProtected(app.packageName, app.userId) -> {
|
||||||
RestrictedLockUtilsInternal.getDeviceOwner(context)
|
RestrictedLockUtilsInternal.getDeviceOwner(context) ?: EnforcedAdmin()
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
|
else -> RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
|
||||||
|
@@ -17,79 +17,82 @@
|
|||||||
package com.android.settings.spa.app.appinfo
|
package com.android.settings.spa.app.appinfo
|
||||||
|
|
||||||
import android.app.admin.DevicePolicyManager
|
import android.app.admin.DevicePolicyManager
|
||||||
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.UserHandle
|
||||||
|
import android.os.UserManager
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.ui.test.assertIsEnabled
|
||||||
|
import androidx.compose.ui.test.assertIsNotEnabled
|
||||||
import androidx.compose.ui.test.junit4.createComposeRule
|
import androidx.compose.ui.test.junit4.createComposeRule
|
||||||
|
import androidx.compose.ui.test.onNodeWithText
|
||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import com.android.settingslib.spa.widget.button.ActionButton
|
import com.android.settings.R
|
||||||
|
import com.android.settingslib.spa.testutils.delay
|
||||||
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
|
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
|
||||||
import com.android.settingslib.spaprivileged.model.app.userId
|
import com.android.settingslib.spaprivileged.model.app.userId
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import org.junit.Before
|
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mock
|
import org.mockito.kotlin.any
|
||||||
import org.mockito.Spy
|
import org.mockito.kotlin.doReturn
|
||||||
import org.mockito.junit.MockitoJUnit
|
import org.mockito.kotlin.mock
|
||||||
import org.mockito.junit.MockitoRule
|
import org.mockito.kotlin.spy
|
||||||
import org.mockito.Mockito.`when` as whenever
|
import org.mockito.kotlin.stub
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class AppForceStopButtonTest {
|
class AppForceStopButtonTest {
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val composeTestRule = createComposeRule()
|
val composeTestRule = createComposeRule()
|
||||||
|
|
||||||
@get:Rule
|
private val mockPackageManager = mock<PackageManager>()
|
||||||
val mockito: MockitoRule = MockitoJUnit.rule()
|
|
||||||
|
|
||||||
@Spy
|
private val mockDevicePolicyManager = mock<DevicePolicyManager>()
|
||||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
|
||||||
|
|
||||||
@Mock
|
private val mockUserManager = mock<UserManager> {
|
||||||
private lateinit var packageInfoPresenter: PackageInfoPresenter
|
on { getUserRestrictionSources(any(), any()) } doReturn emptyList()
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var packageManager: PackageManager
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private lateinit var devicePolicyManager: DevicePolicyManager
|
|
||||||
|
|
||||||
private lateinit var appForceStopButton: AppForceStopButton
|
|
||||||
|
|
||||||
@Before
|
|
||||||
fun setUp() {
|
|
||||||
whenever(packageInfoPresenter.context).thenReturn(context)
|
|
||||||
whenever(context.packageManager).thenReturn(packageManager)
|
|
||||||
whenever(context.devicePolicyManager).thenReturn(devicePolicyManager)
|
|
||||||
appForceStopButton = AppForceStopButton(packageInfoPresenter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||||
fun getActionButton() {
|
on { packageManager } doReturn mockPackageManager
|
||||||
|
on { devicePolicyManager } doReturn mockDevicePolicyManager
|
||||||
|
on { getSystemService(Context.DEVICE_POLICY_SERVICE) } doReturn mockDevicePolicyManager
|
||||||
|
on { getSystemService(Context.USER_SERVICE) } doReturn mockUserManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val packageInfoPresenter = mock<PackageInfoPresenter> {
|
||||||
|
on { context } doReturn context
|
||||||
|
}
|
||||||
|
|
||||||
|
private val appForceStopButton = AppForceStopButton(packageInfoPresenter)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getActionButton_isActiveAdmin_buttonDisabled() {
|
fun getActionButton_isActiveAdmin_buttonDisabled() {
|
||||||
val app = createApp()
|
val app = createApp()
|
||||||
whenever(devicePolicyManager.packageHasActiveAdmins(PACKAGE_NAME, app.userId))
|
mockDevicePolicyManager.stub {
|
||||||
.thenReturn(true)
|
on { packageHasActiveAdmins(PACKAGE_NAME, app.userId) } doReturn true
|
||||||
|
}
|
||||||
|
|
||||||
val actionButton = setForceStopButton(app)
|
setForceStopButton(app)
|
||||||
|
|
||||||
assertThat(actionButton.enabled).isFalse()
|
composeTestRule.onNodeWithText(context.getString(R.string.force_stop)).assertIsNotEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getActionButton_isUninstallInQueue_buttonDisabled() {
|
fun getActionButton_isUninstallInQueue_buttonDisabled() {
|
||||||
val app = createApp()
|
val app = createApp()
|
||||||
whenever(devicePolicyManager.isUninstallInQueue(PACKAGE_NAME)).thenReturn(true)
|
mockDevicePolicyManager.stub {
|
||||||
|
on { isUninstallInQueue(PACKAGE_NAME) } doReturn true
|
||||||
|
}
|
||||||
|
|
||||||
val actionButton = setForceStopButton(app)
|
setForceStopButton(app)
|
||||||
|
|
||||||
assertThat(actionButton.enabled).isFalse()
|
composeTestRule.onNodeWithText(context.getString(R.string.force_stop)).assertIsNotEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -98,35 +101,79 @@ class AppForceStopButtonTest {
|
|||||||
flags = ApplicationInfo.FLAG_STOPPED
|
flags = ApplicationInfo.FLAG_STOPPED
|
||||||
}
|
}
|
||||||
|
|
||||||
val actionButton = setForceStopButton(app)
|
setForceStopButton(app)
|
||||||
|
|
||||||
assertThat(actionButton.enabled).isFalse()
|
composeTestRule.onNodeWithText(context.getString(R.string.force_stop)).assertIsNotEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getActionButton_regularApp_buttonEnabled() {
|
fun getActionButton_regularApp_buttonEnabled() {
|
||||||
val app = createApp()
|
val app = createApp()
|
||||||
|
|
||||||
val actionButton = setForceStopButton(app)
|
setForceStopButton(app)
|
||||||
|
|
||||||
assertThat(actionButton.enabled).isTrue()
|
composeTestRule.onNodeWithText(context.getString(R.string.force_stop)).assertIsEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setForceStopButton(app: ApplicationInfo): ActionButton {
|
@Test
|
||||||
lateinit var actionButton: ActionButton
|
fun getAdminRestriction_packageNotProtected() {
|
||||||
|
mockPackageManager.stub {
|
||||||
|
on { isPackageStateProtected(PACKAGE_NAME, UserHandle.getUserId(UID)) } doReturn false
|
||||||
|
}
|
||||||
|
|
||||||
|
val admin = appForceStopButton.getAdminRestriction(createApp())
|
||||||
|
|
||||||
|
assertThat(admin).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getAdminRestriction_packageProtectedAndHaveOwner() {
|
||||||
|
mockPackageManager.stub {
|
||||||
|
on { isPackageStateProtected(PACKAGE_NAME, UserHandle.getUserId(UID)) } doReturn true
|
||||||
|
}
|
||||||
|
mockDevicePolicyManager.stub {
|
||||||
|
on { deviceOwnerComponentOnAnyUser } doReturn DEVICE_OWNER
|
||||||
|
}
|
||||||
|
|
||||||
|
val admin = appForceStopButton.getAdminRestriction(createApp())!!
|
||||||
|
|
||||||
|
assertThat(admin.component).isEqualTo(DEVICE_OWNER)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getAdminRestriction_packageProtectedAndNotHaveOwner() {
|
||||||
|
mockPackageManager.stub {
|
||||||
|
on { isPackageStateProtected(PACKAGE_NAME, UserHandle.getUserId(UID)) } doReturn true
|
||||||
|
}
|
||||||
|
mockDevicePolicyManager.stub {
|
||||||
|
on { deviceOwnerComponentOnAnyUser } doReturn null
|
||||||
|
}
|
||||||
|
|
||||||
|
val admin = appForceStopButton.getAdminRestriction(createApp())!!
|
||||||
|
|
||||||
|
assertThat(admin.component).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setForceStopButton(app: ApplicationInfo) {
|
||||||
composeTestRule.setContent {
|
composeTestRule.setContent {
|
||||||
actionButton = appForceStopButton.getActionButton(app)
|
val actionButton = appForceStopButton.getActionButton(app)
|
||||||
|
Button(onClick = {}, enabled = actionButton.enabled) {
|
||||||
|
Text(actionButton.text)
|
||||||
}
|
}
|
||||||
return actionButton
|
}
|
||||||
|
composeTestRule.delay()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createApp(builder: ApplicationInfo.() -> Unit = {}) =
|
private fun createApp(builder: ApplicationInfo.() -> Unit = {}) =
|
||||||
ApplicationInfo().apply {
|
ApplicationInfo().apply {
|
||||||
packageName = PACKAGE_NAME
|
packageName = PACKAGE_NAME
|
||||||
|
uid = UID
|
||||||
enabled = true
|
enabled = true
|
||||||
}.apply(builder)
|
}.apply(builder)
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val PACKAGE_NAME = "package.name"
|
const val PACKAGE_NAME = "package.name"
|
||||||
|
const val UID = 10000
|
||||||
|
val DEVICE_OWNER = ComponentName("device", "Owner")
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user