diff --git a/aconfig/settings_development_flag_declarations.aconfig b/aconfig/settings_development_flag_declarations.aconfig index 318f862eff8..f2452e55ec0 100644 --- a/aconfig/settings_development_flag_declarations.aconfig +++ b/aconfig/settings_development_flag_declarations.aconfig @@ -19,3 +19,10 @@ flag { description: "Shows hdr/sdr dev opton on the development options page from aconfig" bug: "291863102" } + +flag { + name: "page_size_app_compat_setting" + namespace: "devoptions_settings" + description: "Flag to enable page size app compat mode from Settings." + bug: "371049373" +} diff --git a/res/values/strings.xml b/res/values/strings.xml index 170e4b63afa..e4f7d608cfa 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -12779,6 +12779,9 @@ 16KB Page-agnostic Mode Read more + Run app with page size compat mode + App will be run in page size compatibility mode on 16 KB device toggled. + DSU Loader diff --git a/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt b/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt index ddddd8c1406..78fb8df123b 100644 --- a/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt +++ b/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt @@ -34,6 +34,7 @@ import androidx.navigation.navArgument import com.android.settings.R import com.android.settings.applications.AppInfoBase import com.android.settings.applications.appinfo.AppInfoDashboardFragment +import com.android.settings.development.Enable16kUtils import com.android.settings.flags.Flags import com.android.settings.spa.SpaActivity.Companion.startSpaActivity import com.android.settings.spa.app.appcompat.UserAspectRatioAppPreference @@ -169,6 +170,7 @@ private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) { InteractAcrossProfilesDetailsPreference(app) AlarmsAndRemindersAppListProvider.InfoPageEntryItem(app) WriteSystemPreferencesAppListProvider.InfoPageEntryItem(app) + Enable16KbAppCompatPreference(app) } Category(title = stringResource(R.string.app_install_details_group_title)) { diff --git a/src/com/android/settings/spa/app/appinfo/Enable16KbAppCompatPreference.kt b/src/com/android/settings/spa/app/appinfo/Enable16KbAppCompatPreference.kt new file mode 100644 index 00000000000..b6606cf881a --- /dev/null +++ b/src/com/android/settings/spa/app/appinfo/Enable16KbAppCompatPreference.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2024 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.appinfo + +import android.content.Context +import android.content.pm.ApplicationInfo +import android.util.Log +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.platform.LocalContext +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.spa.framework.compose.OverridableFlow +import com.android.settingslib.spa.widget.preference.SwitchPreference +import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel +import kotlinx.coroutines.flow.flow + +@Composable +fun Enable16KbAppCompatPreference( + app: ApplicationInfo +) { + val context = LocalContext.current + val presenter = remember(app) { Enable16KbAppCompatSwitchPresenter(context, app) } + if (!presenter.isAvailable()) return + + val isCheckedState = presenter.isCheckedFlow.collectAsStateWithLifecycle(initialValue = null) + SwitchPreference(remember { + object : SwitchPreferenceModel { + override val title = + context.getString(R.string.enable_16k_app_compat_title) + + override val summary = { + context.getString(R.string.enable_16k_app_compat_details) + } + + override val checked = { + isCheckedState.value + } + + override val onCheckedChange = presenter::onCheckedChange + } + }) +} + +private class Enable16KbAppCompatSwitchPresenter(context: Context, private val app: ApplicationInfo) { + private val packageManager = context.packageManager + fun isAvailable(): Boolean { + return Enable16kUtils.isUsing16kbPages() && Flags.pageSizeAppCompatSetting() + } + + private val isChecked = OverridableFlow(flow { + emit(packageManager.isPageSizeCompatEnabled(app.packageName)) + }) + + val isCheckedFlow = isChecked.flow + fun onCheckedChange(newChecked: Boolean) { + try { + packageManager.setPageSizeAppCompatFlagsSettingsOverride(app.packageName, newChecked) + isChecked.override(newChecked) + } catch (e: RuntimeException) { + Log.e("Enable16KbAppCompat", "Failed to set" + + "setPageSizeAppCompatModeSettingsOverride", e); + } + } +}