Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e35f259 authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Apply restricted by admin to the disable button

Currently, we apply the same device policy for both the uninstallation
and disable button.

Also, not double check whether a package is admin (device owner or
profile owner).

Bug: 236346018
Test: Manual on App Settings page
Change-Id: If081fd8ff5422eeac931076a18f73632132a528c
parent 88f9c8fe
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -22,9 +22,12 @@ import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import com.android.settingslib.RestrictedLockUtils
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.Utils
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
import com.android.settingslib.spaprivileged.model.app.isDisallowControl
import com.android.settingslib.spaprivileged.model.app.userId

class AppButtonRepository(private val context: Context) {
    private val packageManager = context.packageManager
@@ -43,6 +46,16 @@ class AppButtonRepository(private val context: Context) {
        else -> app.isDisallowControl(context)
    }

    /**
     * Checks whether uninstall is blocked by admin.
     */
    fun isUninstallBlockedByAdmin(app: ApplicationInfo): Boolean =
        RestrictedLockUtilsInternal.checkIfUninstallBlocked(context, app.packageName, app.userId)
            ?.let { admin ->
                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin)
                true
            } ?: false

    fun getHomePackageInfo(): HomePackages {
        val homePackages = mutableSetOf<String>()
        val homeActivities = ArrayList<ResolveInfo>()
+9 −7
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.settings.spa.app.appsettings

import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowCircleDown
@@ -34,7 +35,6 @@ import com.android.settings.overlay.FeatureFactory
import com.android.settingslib.spa.widget.button.ActionButton
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
import com.android.settingslib.spaprivileged.framework.common.userManager
import com.android.settingslib.spaprivileged.model.app.isActiveAdmin
import com.android.settingslib.spaprivileged.model.app.isDisabledUntilUsed
import com.android.settingslib.Utils as SettingsLibUtils

@@ -58,7 +58,7 @@ class AppDisableButton(

        return when {
            app.enabled && !app.isDisabledUntilUsed -> {
                disableButton(enabled = isDisableButtonEnabled(packageInfo))
                disableButton(app = app, enabled = isDisableButtonEnabled(packageInfo))
            }

            else -> enableButton()
@@ -82,9 +82,6 @@ class AppDisableButton(
            // signed with the system certificate.
            SettingsLibUtils.isSystemPackage(resources, packageManager, packageInfo) -> false

            // If this is a device admin, it can't be disabled.
            app.isActiveAdmin(context) -> false

            // We don't allow disabling DO/PO on *any* users if it's a system app, because
            // "disabling" is actually "downgrade to the system version + disable", and "downgrade"
            // will clear data on all users.
@@ -99,11 +96,16 @@ class AppDisableButton(
        }
    }

    private fun disableButton(enabled: Boolean) = ActionButton(
    private fun disableButton(app: ApplicationInfo, enabled: Boolean) = ActionButton(
        text = context.getString(R.string.disable_text),
        imageVector = Icons.Outlined.HideSource,
        enabled = enabled,
    ) { openConfirmDialog = true }
    ) {
        // Currently we apply the same device policy for both the uninstallation and disable button.
        if (!appButtonRepository.isUninstallBlockedByAdmin(app)) {
            openConfirmDialog = true
        }
    }

    private fun enableButton() = ActionButton(
        text = context.getString(R.string.enable_text),
+1 −2
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import com.android.settingslib.spa.widget.scaffold.MoreOptionsAction
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
import com.android.settingslib.spaprivileged.framework.common.userManager
import com.android.settingslib.spaprivileged.model.app.PackageManagers
import com.android.settingslib.spaprivileged.model.app.isActiveAdmin
import com.android.settingslib.spaprivileged.model.app.isDisallowControl
import com.android.settingslib.spaprivileged.model.app.userId

@@ -76,7 +75,7 @@ private fun isShowUninstallUpdates(context: Context, app: ApplicationInfo): Bool
        !context.resources.getBoolean(R.bool.config_disable_uninstall_update)

private fun isShowUninstallForAllUsers(context: Context, app: ApplicationInfo): Boolean =
    app.userId == 0 && !app.isSystemApp && !app.isInstantApp && !app.isActiveAdmin(context) &&
    app.userId == 0 && !app.isSystemApp && !app.isInstantApp &&
        isOtherUserHasInstallPackage(context, app)

private fun isOtherUserHasInstallPackage(context: Context, app: ApplicationInfo): Boolean =
+2 −26
Original line number Diff line number Diff line
@@ -16,32 +16,21 @@

package com.android.settings.spa.app.appsettings

import android.app.settings.SettingsEnums
import android.content.ComponentName
import android.content.Intent
import android.content.om.OverlayManager
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.net.Uri
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete
import com.android.settings.R
import com.android.settings.Utils
import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminAdd
import com.android.settingslib.RestrictedLockUtils
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.spa.widget.button.ActionButton
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
import com.android.settingslib.spaprivileged.model.app.hasFlag
import com.android.settingslib.spaprivileged.model.app.isActiveAdmin
import com.android.settingslib.spaprivileged.model.app.userHandle
import com.android.settingslib.spaprivileged.model.app.userId

class AppUninstallButton(private val packageInfoPresenter: PackageInfoPresenter) {
    private val context = packageInfoPresenter.context
    private val appButtonRepository = AppButtonRepository(context)
    private val overlayManager = context.getSystemService(OverlayManager::class.java)!!
    private val devicePolicyManager = context.devicePolicyManager

    fun getActionButton(packageInfo: PackageInfo): ActionButton? {
        val app = packageInfo.applicationInfo
@@ -54,7 +43,7 @@ class AppUninstallButton(private val packageInfoPresenter: PackageInfoPresenter)
        !app.hasFlag(ApplicationInfo.FLAG_INSTALLED) -> false

        // Not allow to uninstall DO/PO.
        Utils.isProfileOrDeviceOwner(devicePolicyManager, app.packageName, app.userId) -> false
        app.isActiveAdmin(context) -> false

        appButtonRepository.isDisallowControl(app) -> false

@@ -99,20 +88,7 @@ class AppUninstallButton(private val packageInfoPresenter: PackageInfoPresenter)
    ) { onUninstallClicked(app) }

    private fun onUninstallClicked(app: ApplicationInfo) {
        if (app.isActiveAdmin(context)) {
            packageInfoPresenter.logAction(SettingsEnums.ACTION_SETTINGS_UNINSTALL_DEVICE_ADMIN)
            val intent = Intent(context, DeviceAdminAdd::class.java).apply {
                putExtra(DeviceAdminAdd.EXTRA_DEVICE_ADMIN_PACKAGE_NAME, app.packageName)
            }
            context.startActivityAsUser(intent, app.userHandle)
            return
        }
        RestrictedLockUtilsInternal.checkIfUninstallBlocked(
            context, app.packageName, app.userId
        )?.let { admin ->
            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin)
            return
        }
        if (appButtonRepository.isUninstallBlockedByAdmin(app)) return
        packageInfoPresenter.startUninstallActivity()
    }
}