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
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index aadca5c..388a510 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -986,17 +986,6 @@
         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 d357299..8bd1884 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.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 @@
         title = stringResource(R.string.all_apps),
         listModel = rememberContext(::AllAppListModel),
         showInstantApps = true,
+        matchAnyUserForAdmin = true,
         moreOptions = { ResetAppPreferences(resetAppDialogPresenter::open) },
         appList = appList,
     )
@@ -133,8 +135,13 @@
         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 e1792a9..490a98c 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.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 @@
         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 a03fec7..52c8ad7 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 @@
     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 56c16df..9fc358b 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 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 @@
         }
 
     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 7303b74..f0a18ec 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -161,30 +161,6 @@
     }
 
     @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 b5dfddc..2e7752e 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 @@
         val listModel = AllAppListModel(context) { stateOf(SUMMARY) }
         val disabledApp = ApplicationInfo().apply {
             packageName = PACKAGE_NAME
+            flags = ApplicationInfo.FLAG_INSTALLED
             enabled = false
         }
 
@@ -159,6 +160,23 @@
         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<String>
+        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<AppRecordWithSize> {
         lateinit var input: AppListInput<AppRecordWithSize>
         composeTestRule.setContent {
@@ -192,6 +210,7 @@
         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 c54d35f..37f3a11 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 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 @@
 
     @Test
     fun title_displayed() {
-        setContent()
+        setContent(APP)
 
         composeTestRule.onNodeWithText(context.getString(R.string.notifications_label))
             .assertIsDisplayed()
@@ -80,14 +81,25 @@
 
     @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 @@
         }
     }
 
-    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 @@
         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 5e2b8c6..f90d639 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 @@
         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