From c688f93ed94c4a86a43f1e507d63975ca4564640 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Mon, 10 Apr 2023 01:32:35 +0800 Subject: [PATCH] Display App installed in other user in All Apps Only for admin user. Also clean up unused getInstallationStatus(). Fix: 277299765 Test: Manually with All Apps when multiple users is on Test: Unit test Change-Id: I4de681c101a605e3517dcd8765bf7a95d1b76417 --- src/com/android/settings/Utils.java | 11 --------- .../android/settings/spa/app/AllAppList.kt | 11 +++++++-- .../app/appinfo/AppNotificationPreference.kt | 3 +++ .../spa/app/appinfo/PackageInfoPresenter.kt | 4 +++- .../spa/app/specialaccess/PictureInPicture.kt | 8 ++++--- .../src/com/android/settings/UtilsTest.java | 24 ------------------- .../settings/spa/app/AllAppListTest.kt | 19 +++++++++++++++ .../appinfo/AppNotificationPreferenceTest.kt | 23 ++++++++++++++---- .../app/specialaccess/PictureInPictureTest.kt | 1 + 9 files changed, 58 insertions(+), 46 deletions(-) diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index aadca5c4be5..388a510211f 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -986,17 +986,6 @@ public final class Utils extends com.android.settingslib.Utils { return false; } - /** - * Return the resource id to represent the install status for an app - */ - @StringRes - public static int getInstallationStatus(ApplicationInfo info) { - if ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) { - return R.string.not_installed; - } - return info.enabled ? R.string.installed : R.string.disabled; - } - private static boolean isVolumeValid(VolumeInfo volume) { return (volume != null) && (volume.getType() == VolumeInfo.TYPE_PRIVATE) && volume.isMountedReadable(); diff --git a/src/com/android/settings/spa/app/AllAppList.kt b/src/com/android/settings/spa/app/AllAppList.kt index d3572996402..8bd18844998 100644 --- a/src/com/android/settings/spa/app/AllAppList.kt +++ b/src/com/android/settings/spa/app/AllAppList.kt @@ -38,6 +38,7 @@ import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.ui.SpinnerOption import com.android.settingslib.spaprivileged.model.app.AppListModel import com.android.settingslib.spaprivileged.model.app.AppRecord +import com.android.settingslib.spaprivileged.model.app.installed import com.android.settingslib.spaprivileged.template.app.AppList import com.android.settingslib.spaprivileged.template.app.AppListInput import com.android.settingslib.spaprivileged.template.app.AppListItem @@ -75,6 +76,7 @@ fun AllAppListPage( title = stringResource(R.string.all_apps), listModel = rememberContext(::AllAppListModel), showInstantApps = true, + matchAnyUserForAdmin = true, moreOptions = { ResetAppPreferences(resetAppDialogPresenter::open) }, appList = appList, ) @@ -133,8 +135,13 @@ class AllAppListModel( return remember { derivedStateOf { storageSummary.value + - when (isDisabled(record)) { - true -> System.lineSeparator() + context.getString(R.string.disabled) + when { + !record.app.installed -> { + System.lineSeparator() + context.getString(R.string.not_installed) + } + isDisabled(record) -> { + System.lineSeparator() + context.getString(R.string.disabled) + } else -> "" } } diff --git a/src/com/android/settings/spa/app/appinfo/AppNotificationPreference.kt b/src/com/android/settings/spa/app/appinfo/AppNotificationPreference.kt index e1792a915ba..490a98c795e 100644 --- a/src/com/android/settings/spa/app/appinfo/AppNotificationPreference.kt +++ b/src/com/android/settings/spa/app/appinfo/AppNotificationPreference.kt @@ -30,8 +30,10 @@ import com.android.settings.notification.app.AppNotificationSettings import com.android.settings.spa.notification.AppNotificationRepository import com.android.settings.spa.notification.IAppNotificationRepository import com.android.settingslib.spa.framework.compose.rememberContext +import com.android.settingslib.spa.framework.compose.stateOf import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel +import com.android.settingslib.spaprivileged.model.app.installed import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn @@ -53,6 +55,7 @@ fun AppNotificationPreference( override val summary = summaryFlow.collectAsStateWithLifecycle( initialValue = stringResource(R.string.summary_placeholder) ) + override val enabled = stateOf(app.installed) override val onClick = { navigateToAppNotificationSettings(context, app) } }) } diff --git a/src/com/android/settings/spa/app/appinfo/PackageInfoPresenter.kt b/src/com/android/settings/spa/app/appinfo/PackageInfoPresenter.kt index a03fec727f4..52c8ad7b160 100644 --- a/src/com/android/settings/spa/app/appinfo/PackageInfoPresenter.kt +++ b/src/com/android/settings/spa/app/appinfo/PackageInfoPresenter.kt @@ -141,7 +141,9 @@ class PackageInfoPresenter( private fun getPackageInfo() = packageManagers.getPackageInfoAsUser( packageName = packageName, - flags = PackageManager.MATCH_DISABLED_COMPONENTS or PackageManager.GET_PERMISSIONS, + flags = PackageManager.MATCH_ANY_USER or + PackageManager.MATCH_DISABLED_COMPONENTS or + PackageManager.GET_PERMISSIONS, userId = userId, ) } diff --git a/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt b/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt index 56c16df1dae..9fc358b5cf8 100644 --- a/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt +++ b/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt @@ -28,6 +28,7 @@ import androidx.compose.runtime.livedata.observeAsState import com.android.settings.R import com.android.settingslib.spaprivileged.model.app.AppOpsController import com.android.settingslib.spaprivileged.model.app.AppRecord +import com.android.settingslib.spaprivileged.model.app.installed import com.android.settingslib.spaprivileged.model.app.userId import com.android.settingslib.spaprivileged.template.app.TogglePermissionAppListModel import com.android.settingslib.spaprivileged.template.app.TogglePermissionAppListProvider @@ -67,11 +68,12 @@ class PictureInPictureListModel(private val context: Context) : } override fun transformItem(app: ApplicationInfo): PictureInPictureRecord { - val packageInfo = - packageManager.getPackageInfoAsUser(app.packageName, GET_ACTIVITIES_FLAGS, app.userId) return createPictureInPictureRecord( app = app, - isSupport = packageInfo.supportsPictureInPicture(), + isSupport = app.installed && + packageManager + .getPackageInfoAsUser(app.packageName, GET_ACTIVITIES_FLAGS, app.userId) + .supportsPictureInPicture(), ) } diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java index 7303b74772a..f0a18ec5565 100644 --- a/tests/robotests/src/com/android/settings/UtilsTest.java +++ b/tests/robotests/src/com/android/settings/UtilsTest.java @@ -160,30 +160,6 @@ public class UtilsTest { Utils.maybeInitializeVolume(storageManager, new Bundle()); } - @Test - public void getInstallationStatus_notInstalled_shouldReturnUninstalled() { - assertThat(Utils.getInstallationStatus(new ApplicationInfo())) - .isEqualTo(R.string.not_installed); - } - - @Test - public void getInstallationStatus_enabled_shouldReturnInstalled() { - final ApplicationInfo info = new ApplicationInfo(); - info.flags = ApplicationInfo.FLAG_INSTALLED; - info.enabled = true; - - assertThat(Utils.getInstallationStatus(info)).isEqualTo(R.string.installed); - } - - @Test - public void getInstallationStatus_disabled_shouldReturnDisabled() { - final ApplicationInfo info = new ApplicationInfo(); - info.flags = ApplicationInfo.FLAG_INSTALLED; - info.enabled = false; - - assertThat(Utils.getInstallationStatus(info)).isEqualTo(R.string.disabled); - } - @Test public void isProfileOrDeviceOwner_deviceOwnerApp_returnTrue() { when(mDevicePolicyManager.isDeviceOwnerAppOnAnyUser(PACKAGE_NAME)).thenReturn(true); diff --git a/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt index b5dfddcb5bd..2e7752e4964 100644 --- a/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/app/AllAppListTest.kt @@ -147,6 +147,7 @@ class AllAppListTest { val listModel = AllAppListModel(context) { stateOf(SUMMARY) } val disabledApp = ApplicationInfo().apply { packageName = PACKAGE_NAME + flags = ApplicationInfo.FLAG_INSTALLED enabled = false } @@ -159,6 +160,23 @@ class AllAppListTest { assertThat(summaryState.value).isEqualTo("$SUMMARY${System.lineSeparator()}Disabled") } + @Test + fun allAppListModel_getSummaryWhenNotInstalled() { + val listModel = AllAppListModel(context) { stateOf(SUMMARY) } + val notInstalledApp = ApplicationInfo().apply { + packageName = PACKAGE_NAME + } + + lateinit var summaryState: State + composeTestRule.setContent { + summaryState = + listModel.getSummary(option = 0, record = AppRecordWithSize(app = notInstalledApp)) + } + + assertThat(summaryState.value) + .isEqualTo("$SUMMARY${System.lineSeparator()}Not installed for this user") + } + private fun getAppListInput(): AppListInput { lateinit var input: AppListInput composeTestRule.setContent { @@ -192,6 +210,7 @@ class AllAppListTest { const val SUMMARY = "Summary" val APP = ApplicationInfo().apply { packageName = PACKAGE_NAME + flags = ApplicationInfo.FLAG_INSTALLED } } } diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppNotificationPreferenceTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppNotificationPreferenceTest.kt index c54d35f3c62..37f3a119d0a 100644 --- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppNotificationPreferenceTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppNotificationPreferenceTest.kt @@ -21,6 +21,7 @@ import android.content.pm.ApplicationInfo import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onRoot @@ -72,7 +73,7 @@ class AppNotificationPreferenceTest { @Test fun title_displayed() { - setContent() + setContent(APP) composeTestRule.onNodeWithText(context.getString(R.string.notifications_label)) .assertIsDisplayed() @@ -80,14 +81,25 @@ class AppNotificationPreferenceTest { @Test fun summary_displayed() { - setContent() + setContent(APP) composeTestRule.onNodeWithText(SUMMARY).assertIsDisplayed() } + @Test + fun whenNotInstalled_disable() { + setContent(ApplicationInfo().apply { + packageName = PACKAGE_NAME + uid = UID + }) + + composeTestRule.onNodeWithText(context.getString(R.string.notifications_label)) + .assertIsNotEnabled() + } + @Test fun onClick_startActivity() { - setContent() + setContent(APP) composeTestRule.onRoot().performClick() composeTestRule.delay() @@ -102,10 +114,10 @@ class AppNotificationPreferenceTest { } } - private fun setContent() { + private fun setContent(app: ApplicationInfo) { composeTestRule.setContent { CompositionLocalProvider(LocalContext provides context) { - AppNotificationPreference(app = APP, repository = repository) + AppNotificationPreference(app = app, repository = repository) } } } @@ -116,6 +128,7 @@ class AppNotificationPreferenceTest { val APP = ApplicationInfo().apply { packageName = PACKAGE_NAME uid = UID + flags = ApplicationInfo.FLAG_INSTALLED } const val SUMMARY = "Summary" } diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt index 5e2b8c6e4cd..f90d63947d0 100644 --- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt @@ -167,6 +167,7 @@ class PictureInPictureTest { const val PICTURE_IN_PICTURE_PACKAGE_NAME = "picture.in.picture.package.name" val PICTURE_IN_PICTURE_APP = ApplicationInfo().apply { packageName = PICTURE_IN_PICTURE_PACKAGE_NAME + flags = ApplicationInfo.FLAG_INSTALLED } val PICTURE_IN_PICTURE_PACKAGE_INFO = PackageInfo().apply { packageName = PICTURE_IN_PICTURE_PACKAGE_NAME