Fix flicker of AppButtons
Also remove check for isSystemModule(), since it's also covered by AppUtils.isMainlineModule(). Bug: 236346018 Test: Unit test Test: Manually with Settings Change-Id: Icf8245145a2b2af98847db6040b9e5e930788d4f
This commit is contained in:
@@ -21,23 +21,21 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import com.android.settingslib.applications.AppUtils
|
import com.android.settingslib.applications.AppUtils
|
||||||
import com.android.settingslib.spa.framework.compose.collectAsStateWithLifecycle
|
|
||||||
import com.android.settingslib.spa.widget.button.ActionButton
|
import com.android.settingslib.spa.widget.button.ActionButton
|
||||||
import com.android.settingslib.spa.widget.button.ActionButtons
|
import com.android.settingslib.spa.widget.button.ActionButtons
|
||||||
import com.android.settingslib.spaprivileged.model.app.isSystemModule
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.flow
|
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AppButtons(packageInfoPresenter: PackageInfoPresenter) {
|
fun AppButtons(packageInfoPresenter: PackageInfoPresenter) {
|
||||||
|
if (remember(packageInfoPresenter) { packageInfoPresenter.isMainlineModule() }) return
|
||||||
val presenter = remember { AppButtonsPresenter(packageInfoPresenter) }
|
val presenter = remember { AppButtonsPresenter(packageInfoPresenter) }
|
||||||
if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return
|
|
||||||
presenter.Dialogs()
|
presenter.Dialogs()
|
||||||
ActionButtons(actionButtons = presenter.rememberActionsButtons().value)
|
ActionButtons(actionButtons = presenter.rememberActionsButtons().value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun PackageInfoPresenter.isMainlineModule(): Boolean =
|
||||||
|
AppUtils.isMainlineModule(userPackageManager, packageName)
|
||||||
|
|
||||||
private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoPresenter) {
|
private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoPresenter) {
|
||||||
private val appLaunchButton = AppLaunchButton(packageInfoPresenter)
|
private val appLaunchButton = AppLaunchButton(packageInfoPresenter)
|
||||||
private val appInstallButton = AppInstallButton(packageInfoPresenter)
|
private val appInstallButton = AppInstallButton(packageInfoPresenter)
|
||||||
@@ -46,15 +44,6 @@ private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoP
|
|||||||
private val appClearButton = AppClearButton(packageInfoPresenter)
|
private val appClearButton = AppClearButton(packageInfoPresenter)
|
||||||
private val appForceStopButton = AppForceStopButton(packageInfoPresenter)
|
private val appForceStopButton = AppForceStopButton(packageInfoPresenter)
|
||||||
|
|
||||||
val isAvailableFlow = flow { emit(isAvailable()) }
|
|
||||||
|
|
||||||
private suspend fun isAvailable(): Boolean = withContext(Dispatchers.IO) {
|
|
||||||
!packageInfoPresenter.userPackageManager.isSystemModule(packageInfoPresenter.packageName) &&
|
|
||||||
!AppUtils.isMainlineModule(
|
|
||||||
packageInfoPresenter.userPackageManager, packageInfoPresenter.packageName
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun rememberActionsButtons() = remember {
|
fun rememberActionsButtons() = remember {
|
||||||
packageInfoPresenter.flow.map { packageInfo ->
|
packageInfoPresenter.flow.map { packageInfo ->
|
||||||
|
@@ -148,9 +148,7 @@ class PackageInfoPresenter(
|
|||||||
private fun getPackageInfo() =
|
private fun getPackageInfo() =
|
||||||
PackageManagers.getPackageInfoAsUser(
|
PackageManagers.getPackageInfoAsUser(
|
||||||
packageName = packageName,
|
packageName = packageName,
|
||||||
flags = PackageManager.MATCH_DISABLED_COMPONENTS or
|
flags = PackageManager.MATCH_DISABLED_COMPONENTS or PackageManager.GET_PERMISSIONS,
|
||||||
PackageManager.GET_SIGNATURES or
|
|
||||||
PackageManager.GET_PERMISSIONS,
|
|
||||||
userId = userId,
|
userId = userId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -18,12 +18,8 @@ package com.android.settings.spa.app.appinfo
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.content.pm.ModuleInfo
|
|
||||||
import android.content.pm.PackageInfo
|
import android.content.pm.PackageInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.PackageManager.NameNotFoundException
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.test.assertIsDisplayed
|
import androidx.compose.ui.test.assertIsDisplayed
|
||||||
import androidx.compose.ui.test.assertIsNotDisplayed
|
import androidx.compose.ui.test.assertIsNotDisplayed
|
||||||
import androidx.compose.ui.test.junit4.createComposeRule
|
import androidx.compose.ui.test.junit4.createComposeRule
|
||||||
@@ -33,16 +29,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
|||||||
import com.android.dx.mockito.inline.extended.ExtendedMockito
|
import com.android.dx.mockito.inline.extended.ExtendedMockito
|
||||||
import com.android.settingslib.applications.AppUtils
|
import com.android.settingslib.applications.AppUtils
|
||||||
import com.android.settingslib.spa.testutils.delay
|
import com.android.settingslib.spa.testutils.delay
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.stateIn
|
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
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.Mock
|
||||||
import org.mockito.Mockito.doReturn
|
|
||||||
import org.mockito.Mockito.doThrow
|
|
||||||
import org.mockito.MockitoSession
|
import org.mockito.MockitoSession
|
||||||
import org.mockito.Spy
|
import org.mockito.Spy
|
||||||
import org.mockito.quality.Strictness
|
import org.mockito.quality.Strictness
|
||||||
@@ -74,7 +67,6 @@ class AppButtonsTest {
|
|||||||
whenever(packageInfoPresenter.context).thenReturn(context)
|
whenever(packageInfoPresenter.context).thenReturn(context)
|
||||||
whenever(packageInfoPresenter.packageName).thenReturn(PACKAGE_NAME)
|
whenever(packageInfoPresenter.packageName).thenReturn(PACKAGE_NAME)
|
||||||
whenever(packageInfoPresenter.userPackageManager).thenReturn(packageManager)
|
whenever(packageInfoPresenter.userPackageManager).thenReturn(packageManager)
|
||||||
doThrow(NameNotFoundException()).`when`(packageManager).getModuleInfo(PACKAGE_NAME, 0)
|
|
||||||
whenever(packageManager.getPackageInfo(PACKAGE_NAME, 0)).thenReturn(PACKAGE_INFO)
|
whenever(packageManager.getPackageInfo(PACKAGE_NAME, 0)).thenReturn(PACKAGE_INFO)
|
||||||
whenever(AppUtils.isMainlineModule(packageManager, PACKAGE_NAME)).thenReturn(false)
|
whenever(AppUtils.isMainlineModule(packageManager, PACKAGE_NAME)).thenReturn(false)
|
||||||
}
|
}
|
||||||
@@ -84,15 +76,6 @@ class AppButtonsTest {
|
|||||||
mockSession.finishMocking()
|
mockSession.finishMocking()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun isSystemModule_notDisplayed() {
|
|
||||||
doReturn(ModuleInfo()).`when`(packageManager).getModuleInfo(PACKAGE_NAME, 0)
|
|
||||||
|
|
||||||
setContent()
|
|
||||||
|
|
||||||
composeTestRule.onRoot().assertIsNotDisplayed()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isMainlineModule_notDisplayed() {
|
fun isMainlineModule_notDisplayed() {
|
||||||
whenever(AppUtils.isMainlineModule(packageManager, PACKAGE_NAME)).thenReturn(true)
|
whenever(AppUtils.isMainlineModule(packageManager, PACKAGE_NAME)).thenReturn(true)
|
||||||
@@ -110,12 +93,8 @@ class AppButtonsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setContent() {
|
private fun setContent() {
|
||||||
|
whenever(packageInfoPresenter.flow).thenReturn(MutableStateFlow(PACKAGE_INFO))
|
||||||
composeTestRule.setContent {
|
composeTestRule.setContent {
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
whenever(packageInfoPresenter.flow).thenReturn(flowOf(PACKAGE_INFO).stateIn(scope))
|
|
||||||
}
|
|
||||||
|
|
||||||
AppButtons(packageInfoPresenter)
|
AppButtons(packageInfoPresenter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user