Merge "Add install & clear app button for instant app"
This commit is contained in:
@@ -33,8 +33,10 @@ fun AppButtons(packageInfoPresenter: PackageInfoPresenter) {
|
|||||||
|
|
||||||
private class AppButtonsHolder(private val packageInfoPresenter: PackageInfoPresenter) {
|
private class AppButtonsHolder(private val packageInfoPresenter: PackageInfoPresenter) {
|
||||||
private val appLaunchButton = AppLaunchButton(packageInfoPresenter)
|
private val appLaunchButton = AppLaunchButton(packageInfoPresenter)
|
||||||
|
private val appInstallButton = AppInstallButton(packageInfoPresenter)
|
||||||
private val appDisableButton = AppDisableButton(packageInfoPresenter)
|
private val appDisableButton = AppDisableButton(packageInfoPresenter)
|
||||||
private val appUninstallButton = AppUninstallButton(packageInfoPresenter)
|
private val appUninstallButton = AppUninstallButton(packageInfoPresenter)
|
||||||
|
private val appClearButton = AppClearButton(packageInfoPresenter)
|
||||||
private val appForceStopButton = AppForceStopButton(packageInfoPresenter)
|
private val appForceStopButton = AppForceStopButton(packageInfoPresenter)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -46,14 +48,17 @@ private class AppButtonsHolder(private val packageInfoPresenter: PackageInfoPres
|
|||||||
|
|
||||||
private fun getActionButtons(packageInfo: PackageInfo): List<ActionButton> = listOfNotNull(
|
private fun getActionButtons(packageInfo: PackageInfo): List<ActionButton> = listOfNotNull(
|
||||||
appLaunchButton.getActionButton(packageInfo),
|
appLaunchButton.getActionButton(packageInfo),
|
||||||
|
appInstallButton.getActionButton(packageInfo),
|
||||||
appDisableButton.getActionButton(packageInfo),
|
appDisableButton.getActionButton(packageInfo),
|
||||||
appUninstallButton.getActionButton(packageInfo),
|
appUninstallButton.getActionButton(packageInfo),
|
||||||
|
appClearButton.getActionButton(packageInfo),
|
||||||
appForceStopButton.getActionButton(packageInfo),
|
appForceStopButton.getActionButton(packageInfo),
|
||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Dialogs() {
|
fun Dialogs() {
|
||||||
appDisableButton.DisableConfirmDialog()
|
appDisableButton.DisableConfirmDialog()
|
||||||
|
appClearButton.ClearConfirmDialog()
|
||||||
appForceStopButton.ForceStopConfirmDialog()
|
appForceStopButton.ForceStopConfirmDialog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.appsettings
|
||||||
|
|
||||||
|
import android.content.pm.PackageInfo
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Delete
|
||||||
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import com.android.settings.R
|
||||||
|
import com.android.settingslib.spa.widget.button.ActionButton
|
||||||
|
|
||||||
|
class AppClearButton(
|
||||||
|
private val packageInfoPresenter: PackageInfoPresenter,
|
||||||
|
) {
|
||||||
|
private val context = packageInfoPresenter.context
|
||||||
|
|
||||||
|
private var openConfirmDialog by mutableStateOf(false)
|
||||||
|
|
||||||
|
fun getActionButton(packageInfo: PackageInfo): ActionButton? {
|
||||||
|
val app = packageInfo.applicationInfo
|
||||||
|
if (!app.isInstantApp) return null
|
||||||
|
|
||||||
|
return clearButton()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearButton() = ActionButton(
|
||||||
|
text = context.getString(R.string.clear_instant_app_data),
|
||||||
|
imageVector = Icons.Outlined.Delete,
|
||||||
|
) { openConfirmDialog = true }
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ClearConfirmDialog() {
|
||||||
|
if (!openConfirmDialog) return
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = { openConfirmDialog = false },
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
openConfirmDialog = false
|
||||||
|
packageInfoPresenter.clearInstantApp()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.clear_instant_app_data))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(onClick = { openConfirmDialog = false }) {
|
||||||
|
Text(stringResource(R.string.cancel))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title = {
|
||||||
|
Text(stringResource(R.string.clear_instant_app_data))
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
Text(stringResource(R.string.clear_instant_app_confirmation))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@@ -55,7 +55,7 @@ class AppDisableButton(
|
|||||||
|
|
||||||
fun getActionButton(packageInfo: PackageInfo): ActionButton? {
|
fun getActionButton(packageInfo: PackageInfo): ActionButton? {
|
||||||
val app = packageInfo.applicationInfo
|
val app = packageInfo.applicationInfo
|
||||||
if (!app.hasFlag(ApplicationInfo.FLAG_SYSTEM)) return null
|
if (!app.isSystemApp) return null
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
app.enabled && !app.isDisabledUntilUsed -> {
|
app.enabled && !app.isDisabledUntilUsed -> {
|
||||||
|
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.appsettings
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ApplicationInfo
|
||||||
|
import android.content.pm.PackageInfo
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.FileDownload
|
||||||
|
import com.android.settings.R
|
||||||
|
import com.android.settings.applications.AppStoreUtil
|
||||||
|
import com.android.settingslib.spa.widget.button.ActionButton
|
||||||
|
import com.android.settingslib.spaprivileged.model.app.userHandle
|
||||||
|
|
||||||
|
class AppInstallButton(private val packageInfoPresenter: PackageInfoPresenter) {
|
||||||
|
private val context = packageInfoPresenter.context
|
||||||
|
|
||||||
|
fun getActionButton(packageInfo: PackageInfo): ActionButton? {
|
||||||
|
val app = packageInfo.applicationInfo
|
||||||
|
if (!app.isInstantApp) return null
|
||||||
|
|
||||||
|
return AppStoreUtil.getAppStoreLink(packageInfoPresenter.contextAsUser, app.packageName)
|
||||||
|
?.let { intent -> installButton(intent, app) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun installButton(intent: Intent, app: ApplicationInfo) = ActionButton(
|
||||||
|
text = context.getString(R.string.install_text),
|
||||||
|
imageVector = Icons.Outlined.FileDownload,
|
||||||
|
) {
|
||||||
|
context.startActivityAsUser(intent, app.userHandle)
|
||||||
|
}
|
||||||
|
}
|
@@ -46,7 +46,7 @@ class AppUninstallButton(private val packageInfoPresenter: PackageInfoPresenter)
|
|||||||
|
|
||||||
fun getActionButton(packageInfo: PackageInfo): ActionButton? {
|
fun getActionButton(packageInfo: PackageInfo): ActionButton? {
|
||||||
val app = packageInfo.applicationInfo
|
val app = packageInfo.applicationInfo
|
||||||
if (app.hasFlag(ApplicationInfo.FLAG_SYSTEM)) return null
|
if (app.isSystemApp || app.isInstantApp) return null
|
||||||
return uninstallButton(app = app, enabled = isUninstallButtonEnabled(app))
|
return uninstallButton(app = app, enabled = isUninstallButtonEnabled(app))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,9 +48,8 @@ class PackageInfoPresenter(
|
|||||||
private val coroutineScope: CoroutineScope,
|
private val coroutineScope: CoroutineScope,
|
||||||
) {
|
) {
|
||||||
private val metricsFeatureProvider = FeatureFactory.getFactory(context).metricsFeatureProvider
|
private val metricsFeatureProvider = FeatureFactory.getFactory(context).metricsFeatureProvider
|
||||||
val packageManagerAsUser: PackageManager by lazy {
|
val contextAsUser by lazy { context.createContextAsUser(UserHandle.of(userId), 0) }
|
||||||
context.createContextAsUser(UserHandle.of(userId), 0).packageManager
|
val packageManagerAsUser: PackageManager by lazy { contextAsUser.packageManager }
|
||||||
}
|
|
||||||
private val _flow: MutableStateFlow<PackageInfo?> = MutableStateFlow(null)
|
private val _flow: MutableStateFlow<PackageInfo?> = MutableStateFlow(null)
|
||||||
|
|
||||||
val flow: StateFlow<PackageInfo?> = _flow
|
val flow: StateFlow<PackageInfo?> = _flow
|
||||||
@@ -103,6 +102,15 @@ class PackageInfoPresenter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Clears this instant app. */
|
||||||
|
fun clearInstantApp() {
|
||||||
|
logAction(SettingsEnums.ACTION_SETTINGS_CLEAR_INSTANT_APP)
|
||||||
|
coroutineScope.launch(Dispatchers.IO) {
|
||||||
|
packageManagerAsUser.deletePackageAsUser(packageName, null, 0, userId)
|
||||||
|
notifyChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Force stops this package. */
|
/** Force stops this package. */
|
||||||
fun forceStop() {
|
fun forceStop() {
|
||||||
logAction(SettingsEnums.ACTION_APP_FORCE_STOP)
|
logAction(SettingsEnums.ACTION_APP_FORCE_STOP)
|
||||||
|
Reference in New Issue
Block a user