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

Commit a63c370e authored by Pawan Wagh's avatar Pawan Wagh
Browse files

Stop app when toggling backcompat setting

- Add method to stop package
- Backcompat setting takes two launches right now to take effect.
stop application when backcompat setting is toggled.

Test: m Settings && adb install -r $ANDROID_PRODUCT_OUT/system_ext/priv-app/Settings/Settings.apk
Bug: 389696304
Flag: EXEMPT bug_fix
Change-Id: Iadc8030fe34f66e7eaf854513b14aeb78a556308
parent 165f4ea7
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -13097,7 +13097,11 @@
    <string name="page_agnostic_notification_action">Read more</string>
    <string name= "enable_16k_app_compat_title">Run app with page size compat mode</string>
    <string name= "enable_16k_app_compat_details">App will be run in page size compatibility mode on 16 KB device when toggled.</string>
    <string name= "enable_16k_app_compat_details">App will be forced stopped and run in page size compatibility mode on 16 KB device when toggled.</string>
    <string name="stop_app_dlg_title">Stop app?</string>
    <!-- [CHAR LIMIT=200] Manage applications, text for dialog when killing persistent apps-->
    <string name="stop_app_dlg_text">Application will be stopped to apply page size compat setting.</string>
    <!-- DSU Loader. Do not translate. -->
+1 −1
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) {
            InteractAcrossProfilesDetailsPreference(app)
            AlarmsAndRemindersAppListProvider.InfoPageEntryItem(app)
            WriteSystemPreferencesAppListProvider.InfoPageEntryItem(app)
            Enable16KbAppCompatPreference(app)
            Enable16KbAppCompatPreference(app, packageInfoPresenter)
        }

        Category(title = stringResource(R.string.app_install_details_group_title)) {
+52 −5
Original line number Diff line number Diff line
@@ -16,8 +16,12 @@

package com.android.settings.spa.app.appinfo

import android.app.AlertDialog
import android.app.settings.SettingsEnums
import android.content.Context
import android.content.DialogInterface
import android.content.pm.ApplicationInfo
import android.os.UserManager
import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@@ -26,17 +30,23 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R
import com.android.settings.development.Enable16kUtils
import com.android.settings.flags.Flags
import com.android.settingslib.RestrictedLockUtils
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.spa.framework.compose.OverridableFlow
import com.android.settingslib.spa.widget.dialog.AlertDialogButton
import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter
import com.android.settingslib.spa.widget.preference.SwitchPreference
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import com.android.settingslib.spaprivileged.model.app.userId
import kotlinx.coroutines.flow.flow

@Composable
fun Enable16KbAppCompatPreference(
    app: ApplicationInfo
    app: ApplicationInfo,
    packageInfoPresenter: PackageInfoPresenter
) {
    val context = LocalContext.current
    val presenter = remember(app) { Enable16KbAppCompatSwitchPresenter(context, app) }
    val presenter = remember(app) { Enable16KbAppCompatSwitchPresenter(context, app, packageInfoPresenter) }
    if (!presenter.isAvailable()) return

    val isCheckedState = presenter.isCheckedFlow.collectAsStateWithLifecycle(initialValue = null)
@@ -58,7 +68,9 @@ fun Enable16KbAppCompatPreference(
    })
}

private class Enable16KbAppCompatSwitchPresenter(context: Context, private val app: ApplicationInfo) {

private class Enable16KbAppCompatSwitchPresenter(private val context: Context, private val app: ApplicationInfo,
                                                 private val packageInfoPresenter: PackageInfoPresenter) {
    private val packageManager = context.packageManager
    fun isAvailable(): Boolean {
        return Enable16kUtils.isUsing16kbPages() && Flags.pageSizeAppCompatSetting()
@@ -69,13 +81,48 @@ private class Enable16KbAppCompatSwitchPresenter(context: Context, private val a
    })

    val isCheckedFlow = isChecked.flow

    fun onCheckedChange(newChecked: Boolean) {
        try {
            packageManager.setPageSizeAppCompatFlagsSettingsOverride(app.packageName, newChecked)
            isChecked.override(newChecked)
            getForceStopRestriction(app)?.let { admin ->
                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin)
                return
            }
            showDialog(newChecked)
        } catch (e: RuntimeException) {
            Log.e("Enable16KbAppCompat", "Failed to set" +
                    "setPageSizeAppCompatModeSettingsOverride", e);
        }
    }

    fun updatePageSizeCompat(newChecked: Boolean) {
        packageManager.setPageSizeAppCompatFlagsSettingsOverride(app.packageName, newChecked)
        isChecked.override(newChecked)
        packageInfoPresenter.stopPackage()
    }

    fun getForceStopRestriction(app: ApplicationInfo): RestrictedLockUtils.EnforcedAdmin? = when {
        packageManager.isPackageStateProtected(app.packageName, app.userId) -> {
            RestrictedLockUtilsInternal.getDeviceOwner(context) ?: RestrictedLockUtils.EnforcedAdmin()
        }

        else -> RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
                context, UserManager.DISALLOW_APPS_CONTROL, app.userId
        )
    }

    fun showDialog(newChecked: Boolean) {
        // Uses the same string from 'Force Stop' action button.
        val builder =
                AlertDialog.Builder(context)
                        .setTitle(R.string.stop_app_dlg_title)
                        .setMessage(R.string.stop_app_dlg_text)
                        .setNegativeButton(R.string.cancel, null)
                        .setPositiveButton(R.string.okay,  DialogInterface.OnClickListener { dialog, _ ->
                                updatePageSizeCompat(newChecked)
                                dialog.dismiss()
                            })
                        .create();
        builder.show();
    }
}
+10 −0
Original line number Diff line number Diff line
@@ -185,6 +185,16 @@ class PackageInfoPresenter(
        }
    }

    /* stops application without durable effects of the full-scale "forec stop" */
    fun stopPackage() {
        requireAuthAndExecute {
            coroutineScope.launch(Dispatchers.Default) {
                Log.d(TAG, "Stopping package $packageName for user")
                context.activityManager.stopPackageForUser(packageName)
            }
        }
    }

    fun logAction(category: Int) {
        metricsFeatureProvider.action(context, category, packageName)
    }