Move common startUninstallActivity to AppUtil

And also suppress the warnings.

Bug: 236346018
Test: Unit test
Change-Id: I469e563fdeea0bec0587a255b15fddcaaab7f2c3
This commit is contained in:
Chaohui Wang
2023-01-04 16:58:39 +08:00
parent e4f2fb56f9
commit 4710cfc7ed
5 changed files with 110 additions and 58 deletions

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.spa.app
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.UserHandle
/**
* Based on PackageManagerService design, and it looks like the suggested replacement in the
* deprecate notes suggest that we use PackageInstaller.uninstall which does not guarantee a pop up
* would open and depends on the calling application. Seems like further investigation is needed
* before we can move over to the new API.
*/
@Suppress("DEPRECATION")
fun Context.startUninstallActivity(
packageName: String,
userHandle: UserHandle,
forAllUsers: Boolean = false,
) {
val packageUri = Uri.parse("package:$packageName")
val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri).apply {
putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, forAllUsers)
}
startActivityAsUser(intent, userHandle)
}

View File

@@ -22,11 +22,11 @@ import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.net.Uri
import android.os.UserHandle
import android.util.Log
import androidx.compose.runtime.Composable
import com.android.settings.overlay.FeatureFactory
import com.android.settings.spa.app.startUninstallActivity
import com.android.settingslib.spa.framework.compose.LocalNavController
import com.android.settingslib.spaprivileged.framework.common.activityManager
import com.android.settingslib.spaprivileged.framework.common.asUser
@@ -116,11 +116,7 @@ class PackageInfoPresenter(
/** Starts the uninstallation activity. */
fun startUninstallActivity(forAllUsers: Boolean = false) {
logAction(SettingsEnums.ACTION_SETTINGS_UNINSTALL_APP)
val packageUri = Uri.parse("package:${packageName}")
val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri).apply {
putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, forAllUsers)
}
context.startActivityAsUser(intent, userHandle)
context.startUninstallActivity(packageName, userHandle, forAllUsers)
}
/** Clears this instant app. */

View File

@@ -17,13 +17,11 @@
package com.android.settings.spa.app.backgroundinstall
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.IBackgroundInstallControlService
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.ParceledListSlice
import android.net.Uri
import android.os.Bundle
import android.os.ServiceManager
import android.provider.DeviceConfig
@@ -40,6 +38,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.android.settings.R
import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider
import com.android.settings.spa.app.startUninstallActivity
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SettingsPageProvider
@@ -54,6 +53,7 @@ import com.android.settingslib.spa.widget.ui.SettingsBody
import com.android.settingslib.spaprivileged.model.app.AppEntry
import com.android.settingslib.spaprivileged.model.app.AppListModel
import com.android.settingslib.spaprivileged.model.app.AppRecord
import com.android.settingslib.spaprivileged.model.app.userHandle
import com.android.settingslib.spaprivileged.template.app.AppList
import com.android.settingslib.spaprivileged.template.app.AppListButtonItem
import com.android.settingslib.spaprivileged.template.app.AppListInput
@@ -150,23 +150,6 @@ fun BackgroundInstalledAppList(
}
)
}
/*
Based on PackageManagerService design, and it looks like the suggested replacement in the deprecate
notes suggest that we use PackageInstaller.uninstall which does not guarantee a pop up would open
and depends on the calling application. Seems like further investigation is needed before we can
move over to the new API.
*/
@Suppress
@VisibleForTesting
fun startUninstallActivity(context: Context,
packageName: String,
forAllUsers: Boolean = false) {
val packageUri = Uri.parse("package:${packageName}")
val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri).apply {
putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, forAllUsers)
}
context.startActivityAsUser(intent, context.user)
}
data class BackgroundInstalledAppListWithGroupingAppRecord(
override val app: ApplicationInfo,
@@ -190,9 +173,10 @@ class BackgroundInstalledAppsWithGroupingListModel(private val context: Context)
@Composable
override fun AppListItemModel<BackgroundInstalledAppListWithGroupingAppRecord>.AppItem() {
val context = LocalContext.current
val app = record.app
AppListButtonItem(
onClick = AppInfoSettingsProvider.navigator(app = record.app),
onButtonClick = { startUninstallActivity(context, record.app.packageName) },
onClick = AppInfoSettingsProvider.navigator(app = app),
onButtonClick = { context.startUninstallActivity(app.packageName, app.userHandle) },
buttonIcon = Icons.Outlined.Delete,
buttonIconDescription = stringResource(
R.string.background_install_uninstall_button_description))
@@ -209,11 +193,6 @@ class BackgroundInstalledAppsWithGroupingListModel(private val context: Context)
}
}
@Composable
override fun getSummary(option: Int, record: BackgroundInstalledAppListWithGroupingAppRecord)
= null
@Suppress
override fun filter(
userIdFlow: Flow<Int>,
option: Int,
@@ -224,6 +203,7 @@ class BackgroundInstalledAppsWithGroupingListModel(private val context: Context)
return flowOf()
}
return userIdFlow.combine(recordListFlow) { userId, recordList ->
@Suppress("UNCHECKED_CAST")
val appList = (backgroundInstallService.getBackgroundInstalledPackages(
PackageManager.MATCH_ALL.toLong(), userId) as ParceledListSlice<PackageInfo>).list
val appNameList = appList.map { it.packageName }

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.spa.app
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Mock
import org.mockito.Mockito.eq
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
@RunWith(AndroidJUnit4::class)
class AppUtilTest {
@get:Rule
val mockito: MockitoRule = MockitoJUnit.rule()
@Mock
private lateinit var context: Context
@Test
fun startUninstallActivity() {
context.startUninstallActivity(packageName = PACKAGE_NAME, userHandle = USER_HANDLE)
val intentCaptor = ArgumentCaptor.forClass(Intent::class.java)
verify(context).startActivityAsUser(intentCaptor.capture(), eq(USER_HANDLE))
val intent = intentCaptor.value
assertThat(intent.action).isEqualTo(Intent.ACTION_UNINSTALL_PACKAGE)
assertThat(intent.data).isEqualTo(Uri.parse("package:$PACKAGE_NAME"))
assertThat(intent.extras?.getBoolean(Intent.EXTRA_UNINSTALL_ALL_USERS)).isFalse()
}
private companion object {
const val PACKAGE_NAME = "package.name"
val USER_HANDLE: UserHandle = UserHandle.of(0)
}
}

View File

@@ -17,14 +17,11 @@
package com.android.settings.spa.app.backgroundinstall
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.IBackgroundInstallControlService
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.ParceledListSlice
import android.net.Uri
import android.os.UserHandle
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
@@ -74,9 +71,6 @@ class BackgroundInstalledAppsPageProviderTest {
private var packageInfoFlagsCaptor =
ArgumentCaptor.forClass(PackageManager.PackageInfoFlags::class.java)
private var intentCaptor =
ArgumentCaptor.forClass(Intent::class.java)
private val fakeNavControllerWrapper = FakeNavControllerWrapper()
@Before
@@ -177,26 +171,6 @@ class BackgroundInstalledAppsPageProviderTest {
.isEqualTo("AppInfoSettings/package.name/0")
}
@Suppress
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun startUninstallActivity_success() = runTest {
val expectedPackageUri = Uri.parse("package:package.name")
val mockUserHandle = UserHandle(0)
Mockito.`when`(mockContext.user).thenReturn(mockUserHandle)
Mockito.`when`(mockContext.startActivityAsUser(
intentCaptor.capture(),
eq(mockUserHandle)
)).then { }
startUninstallActivity(mockContext, TEST_PACKAGE_NAME)
Truth.assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_UNINSTALL_PACKAGE)
Truth.assertThat(intentCaptor.value.data).isEqualTo(expectedPackageUri)
Truth.assertThat(intentCaptor.value.extras?.getBoolean(Intent.EXTRA_UNINSTALL_ALL_USERS))
.isEqualTo(false)
}
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun backgroundInstalledAppsWithGroupingListModel_getGroupTitleOne() = runTest {