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.content.pm.ApplicationInfo
|
||||
import android.os.UserManager
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Report
|
||||
import androidx.compose.material3.Text
|
||||
@@ -87,9 +88,10 @@ class AppForceStopButton(
|
||||
dialogPresenter.open()
|
||||
}
|
||||
|
||||
private fun getAdminRestriction(app: ApplicationInfo): EnforcedAdmin? = when {
|
||||
@VisibleForTesting
|
||||
fun getAdminRestriction(app: ApplicationInfo): EnforcedAdmin? = when {
|
||||
packageManager.isPackageStateProtected(app.packageName, app.userId) -> {
|
||||
RestrictedLockUtilsInternal.getDeviceOwner(context)
|
||||
RestrictedLockUtilsInternal.getDeviceOwner(context) ?: EnforcedAdmin()
|
||||
}
|
||||
|
||||
else -> RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
|
||||
|
@@ -17,79 +17,82 @@
|
||||
package com.android.settings.spa.app.appinfo
|
||||
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
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.onNodeWithText
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
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.model.app.userId
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Spy
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoRule
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.stub
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class AppForceStopButtonTest {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@get:Rule
|
||||
val mockito: MockitoRule = MockitoJUnit.rule()
|
||||
private val mockPackageManager = mock<PackageManager>()
|
||||
|
||||
@Spy
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
private val mockDevicePolicyManager = mock<DevicePolicyManager>()
|
||||
|
||||
@Mock
|
||||
private lateinit var packageInfoPresenter: PackageInfoPresenter
|
||||
|
||||
@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)
|
||||
private val mockUserManager = mock<UserManager> {
|
||||
on { getUserRestrictionSources(any(), any()) } doReturn emptyList()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getActionButton() {
|
||||
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||
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
|
||||
fun getActionButton_isActiveAdmin_buttonDisabled() {
|
||||
val app = createApp()
|
||||
whenever(devicePolicyManager.packageHasActiveAdmins(PACKAGE_NAME, app.userId))
|
||||
.thenReturn(true)
|
||||
mockDevicePolicyManager.stub {
|
||||
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
|
||||
fun getActionButton_isUninstallInQueue_buttonDisabled() {
|
||||
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
|
||||
@@ -98,35 +101,79 @@ class AppForceStopButtonTest {
|
||||
flags = ApplicationInfo.FLAG_STOPPED
|
||||
}
|
||||
|
||||
val actionButton = setForceStopButton(app)
|
||||
setForceStopButton(app)
|
||||
|
||||
assertThat(actionButton.enabled).isFalse()
|
||||
composeTestRule.onNodeWithText(context.getString(R.string.force_stop)).assertIsNotEnabled()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getActionButton_regularApp_buttonEnabled() {
|
||||
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 {
|
||||
lateinit var actionButton: ActionButton
|
||||
composeTestRule.setContent {
|
||||
actionButton = appForceStopButton.getActionButton(app)
|
||||
@Test
|
||||
fun getAdminRestriction_packageNotProtected() {
|
||||
mockPackageManager.stub {
|
||||
on { isPackageStateProtected(PACKAGE_NAME, UserHandle.getUserId(UID)) } doReturn false
|
||||
}
|
||||
return actionButton
|
||||
|
||||
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 {
|
||||
val actionButton = appForceStopButton.getActionButton(app)
|
||||
Button(onClick = {}, enabled = actionButton.enabled) {
|
||||
Text(actionButton.text)
|
||||
}
|
||||
}
|
||||
composeTestRule.delay()
|
||||
}
|
||||
|
||||
private fun createApp(builder: ApplicationInfo.() -> Unit = {}) =
|
||||
ApplicationInfo().apply {
|
||||
packageName = PACKAGE_NAME
|
||||
uid = UID
|
||||
enabled = true
|
||||
}.apply(builder)
|
||||
|
||||
private companion object {
|
||||
const val PACKAGE_NAME = "package.name"
|
||||
const val UID = 10000
|
||||
val DEVICE_OWNER = ComponentName("device", "Owner")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user