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:
Chaohui Wang
2022-11-28 13:28:29 +08:00
parent d2378be135
commit d70dbe408a
3 changed files with 7 additions and 41 deletions

View File

@@ -21,23 +21,21 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
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.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.withContext
@Composable
fun AppButtons(packageInfoPresenter: PackageInfoPresenter) {
if (remember(packageInfoPresenter) { packageInfoPresenter.isMainlineModule() }) return
val presenter = remember { AppButtonsPresenter(packageInfoPresenter) }
if (!presenter.isAvailableFlow.collectAsStateWithLifecycle(initialValue = false).value) return
presenter.Dialogs()
ActionButtons(actionButtons = presenter.rememberActionsButtons().value)
}
private fun PackageInfoPresenter.isMainlineModule(): Boolean =
AppUtils.isMainlineModule(userPackageManager, packageName)
private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoPresenter) {
private val appLaunchButton = AppLaunchButton(packageInfoPresenter)
private val appInstallButton = AppInstallButton(packageInfoPresenter)
@@ -46,15 +44,6 @@ private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoP
private val appClearButton = AppClearButton(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
fun rememberActionsButtons() = remember {
packageInfoPresenter.flow.map { packageInfo ->

View File

@@ -148,9 +148,7 @@ class PackageInfoPresenter(
private fun getPackageInfo() =
PackageManagers.getPackageInfoAsUser(
packageName = packageName,
flags = PackageManager.MATCH_DISABLED_COMPONENTS or
PackageManager.GET_SIGNATURES or
PackageManager.GET_PERMISSIONS,
flags = PackageManager.MATCH_DISABLED_COMPONENTS or PackageManager.GET_PERMISSIONS,
userId = userId,
)
}

View File

@@ -18,12 +18,8 @@ package com.android.settings.spa.app.appinfo
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.ModuleInfo
import android.content.pm.PackageInfo
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.assertIsNotDisplayed
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.settingslib.applications.AppUtils
import com.android.settingslib.spa.testutils.delay
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.doThrow
import org.mockito.MockitoSession
import org.mockito.Spy
import org.mockito.quality.Strictness
@@ -74,7 +67,6 @@ class AppButtonsTest {
whenever(packageInfoPresenter.context).thenReturn(context)
whenever(packageInfoPresenter.packageName).thenReturn(PACKAGE_NAME)
whenever(packageInfoPresenter.userPackageManager).thenReturn(packageManager)
doThrow(NameNotFoundException()).`when`(packageManager).getModuleInfo(PACKAGE_NAME, 0)
whenever(packageManager.getPackageInfo(PACKAGE_NAME, 0)).thenReturn(PACKAGE_INFO)
whenever(AppUtils.isMainlineModule(packageManager, PACKAGE_NAME)).thenReturn(false)
}
@@ -84,15 +76,6 @@ class AppButtonsTest {
mockSession.finishMocking()
}
@Test
fun isSystemModule_notDisplayed() {
doReturn(ModuleInfo()).`when`(packageManager).getModuleInfo(PACKAGE_NAME, 0)
setContent()
composeTestRule.onRoot().assertIsNotDisplayed()
}
@Test
fun isMainlineModule_notDisplayed() {
whenever(AppUtils.isMainlineModule(packageManager, PACKAGE_NAME)).thenReturn(true)
@@ -110,12 +93,8 @@ class AppButtonsTest {
}
private fun setContent() {
whenever(packageInfoPresenter.flow).thenReturn(MutableStateFlow(PACKAGE_INFO))
composeTestRule.setContent {
val scope = rememberCoroutineScope()
LaunchedEffect(Unit) {
whenever(packageInfoPresenter.flow).thenReturn(flowOf(PACKAGE_INFO).stateIn(scope))
}
AppButtons(packageInfoPresenter)
}