Merge "Use a separated flag for archiving feature in Settings" into main

This commit is contained in:
Mark Kim
2024-02-05 10:55:37 +00:00
committed by Android (Google) Code Review
7 changed files with 42 additions and 18 deletions

View File

@@ -13,3 +13,10 @@ flag {
description: "Enabling will provide an explicit package name for Intent to update mainline modules" description: "Enabling will provide an explicit package name for Intent to update mainline modules"
bug: "278987474" bug: "278987474"
} }
flag {
name: "app_archiving"
namespace: "android_settings"
description: "Feature flag to enable the archiving feature."
bug: "323164382"
}

View File

@@ -22,12 +22,15 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.ApplicationInfoFlags; import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.UserInfo; import android.content.pm.UserInfo;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.SystemProperties;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.android.settings.flags.Flags;
import java.util.List; import java.util.List;
public abstract class AppCounter extends AsyncTask<Void, Void, Integer> { public abstract class AppCounter extends AsyncTask<Void, Void, Integer> {
@@ -54,7 +57,7 @@ public abstract class AppCounter extends AsyncTask<Void, Void, Integer> {
for (UserInfo user : mUm.getProfiles(UserHandle.myUserId())) { for (UserInfo user : mUm.getProfiles(UserHandle.myUserId())) {
long flags = PackageManager.GET_DISABLED_COMPONENTS long flags = PackageManager.GET_DISABLED_COMPONENTS
| PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS
| (mFf.archiving() ? PackageManager.MATCH_ARCHIVED_PACKAGES : 0) | (isArchivingEnabled() ? PackageManager.MATCH_ARCHIVED_PACKAGES : 0)
| (user.isAdmin() ? PackageManager.MATCH_ANY_USER : 0); | (user.isAdmin() ? PackageManager.MATCH_ANY_USER : 0);
ApplicationInfoFlags infoFlags = ApplicationInfoFlags.of(flags); ApplicationInfoFlags infoFlags = ApplicationInfoFlags.of(flags);
final List<ApplicationInfo> list = final List<ApplicationInfo> list =
@@ -68,6 +71,11 @@ public abstract class AppCounter extends AsyncTask<Void, Void, Integer> {
return count; return count;
} }
private boolean isArchivingEnabled() {
return mFf.archiving() || SystemProperties.getBoolean("pm.archiving.enabled", false)
|| Flags.appArchiving();
}
@Override @Override
protected void onPostExecute(Integer count) { protected void onPostExecute(Integer count) {
onCountComplete(count); onCountComplete(count);

View File

@@ -17,8 +17,8 @@
package com.android.settings.spa.app.appinfo package com.android.settings.spa.app.appinfo
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.FeatureFlags import android.content.pm.FeatureFlags as PmFeatureFlags
import android.content.pm.FeatureFlagsImpl import android.content.pm.FeatureFlagsImpl as PmFeatureFlagsImpl
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
fun AppButtons( fun AppButtons(
packageInfoPresenter: PackageInfoPresenter, packageInfoPresenter: PackageInfoPresenter,
isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>, isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>,
featureFlags: FeatureFlags = FeatureFlagsImpl() featureFlags: PmFeatureFlags = PmFeatureFlagsImpl()
) { ) {
if (remember(packageInfoPresenter) { packageInfoPresenter.isMainlineModule() }) return if (remember(packageInfoPresenter) { packageInfoPresenter.isMainlineModule() }) return
val presenter = remember { val presenter = remember {
@@ -53,7 +53,7 @@ private fun PackageInfoPresenter.isMainlineModule(): Boolean =
private class AppButtonsPresenter( private class AppButtonsPresenter(
private val packageInfoPresenter: PackageInfoPresenter, private val packageInfoPresenter: PackageInfoPresenter,
isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>, isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>,
private val featureFlags: FeatureFlags private val featureFlags: PmFeatureFlags
) { ) {
private val appLaunchButton = AppLaunchButton(packageInfoPresenter) private val appLaunchButton = AppLaunchButton(packageInfoPresenter)
private val appInstallButton = AppInstallButton(packageInfoPresenter) private val appInstallButton = AppInstallButton(packageInfoPresenter)

View File

@@ -18,9 +18,8 @@ package com.android.settings.spa.app.appinfo
import android.app.settings.SettingsEnums import android.app.settings.SettingsEnums
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.FeatureFlags
import android.content.pm.FeatureFlagsImpl
import android.os.Bundle import android.os.Bundle
import android.os.SystemProperties
import android.os.UserHandle import android.os.UserHandle
import android.util.FeatureFlagUtils import android.util.FeatureFlagUtils
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -51,6 +50,8 @@ import com.android.settingslib.spa.widget.ui.Category
import com.android.settingslib.spaprivileged.model.app.toRoute import com.android.settingslib.spaprivileged.model.app.toRoute
import com.android.settingslib.spaprivileged.template.app.AppInfoProvider import com.android.settingslib.spaprivileged.template.app.AppInfoProvider
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import android.content.pm.FeatureFlags as PmFeatureFlags
import android.content.pm.FeatureFlagsImpl as PmFeatureFlagsImpl
private const val PACKAGE_NAME = "packageName" private const val PACKAGE_NAME = "packageName"
private const val USER_ID = "userId" private const val USER_ID = "userId"
@@ -121,7 +122,7 @@ object AppInfoSettingsProvider : SettingsPageProvider {
@Composable @Composable
private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) { private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) {
val packageInfoState = packageInfoPresenter.flow.collectAsStateWithLifecycle() val packageInfoState = packageInfoPresenter.flow.collectAsStateWithLifecycle()
val featureFlags: FeatureFlags = FeatureFlagsImpl() val featureFlags: PmFeatureFlags = PmFeatureFlagsImpl()
RegularScaffold( RegularScaffold(
title = stringResource(R.string.application_info_label), title = stringResource(R.string.application_info_label),
actions = { actions = {
@@ -177,5 +178,6 @@ private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) {
} }
} }
fun isArchivingEnabled(featureFlags: FeatureFlags) = fun isArchivingEnabled(featureFlags: PmFeatureFlags) =
featureFlags.archiving() || "true" == System.getProperty("pm.archiving.enabled") featureFlags.archiving() || SystemProperties.getBoolean("pm.archiving.enabled", false)
|| Flags.appArchiving()

View File

@@ -22,8 +22,9 @@ import android.app.AppOpsManager.MODE_IGNORED
import android.app.AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED import android.app.AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
import android.content.Context import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.Flags import android.content.pm.Flags as PmFlags
import android.os.Build import android.os.Build
import android.os.SystemProperties
import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_EXEMPT_BY_SYSTEM import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_EXEMPT_BY_SYSTEM
import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_UNKNOWN import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_UNKNOWN
import android.provider.DeviceConfig import android.provider.DeviceConfig
@@ -36,6 +37,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R import com.android.settings.R
import com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED import com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED
import com.android.settings.Utils.PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS import com.android.settings.Utils.PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS
import com.android.settings.flags.Flags
import com.android.settingslib.spa.framework.compose.OverridableFlow import com.android.settingslib.spa.framework.compose.OverridableFlow
import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreference
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
@@ -91,7 +93,8 @@ fun HibernationSwitchPreference(
} }
private fun isArchivingEnabled() = private fun isArchivingEnabled() =
Flags.archiving() || "true" == System.getProperty("pm.archiving.enabled") PmFlags.archiving() || SystemProperties.getBoolean("pm.archiving.enabled", false)
|| Flags.appArchiving()
private class HibernationSwitchPresenter(context: Context, private val app: ApplicationInfo) { private class HibernationSwitchPresenter(context: Context, private val app: ApplicationInfo) {
private val appOpsManager = context.appOpsManager private val appOpsManager = context.appOpsManager

View File

@@ -20,14 +20,16 @@ import android.app.settings.SettingsEnums
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.content.pm.FeatureFlags import android.content.pm.FeatureFlags as PmFeatureFlags
import android.content.pm.FeatureFlagsImpl import android.content.pm.FeatureFlagsImpl as PmFeatureFlagsImpl
import android.content.pm.PackageInfo import android.content.pm.PackageInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.UserHandle import android.os.UserHandle
import android.util.Log import android.util.Log
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import com.android.settings.flags.FeatureFlags
import com.android.settings.flags.FeatureFlagsImpl
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
import com.android.settings.spa.app.startUninstallActivity import com.android.settings.spa.app.startUninstallActivity
import com.android.settingslib.spa.framework.compose.LocalNavController import com.android.settingslib.spa.framework.compose.LocalNavController
@@ -60,7 +62,7 @@ class PackageInfoPresenter(
val userId: Int, val userId: Int,
private val coroutineScope: CoroutineScope, private val coroutineScope: CoroutineScope,
private val packageManagers: IPackageManagers = PackageManagers, private val packageManagers: IPackageManagers = PackageManagers,
private val featureFlags: FeatureFlags = FeatureFlagsImpl(), private val featureFlags: PmFeatureFlags = PmFeatureFlagsImpl(),
) { ) {
private val metricsFeatureProvider = featureFactory.metricsFeatureProvider private val metricsFeatureProvider = featureFactory.metricsFeatureProvider
private val userHandle = UserHandle.of(userId) private val userHandle = UserHandle.of(userId)

View File

@@ -24,8 +24,9 @@ import android.app.AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
import android.apphibernation.AppHibernationManager import android.apphibernation.AppHibernationManager
import android.content.Context import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.Flags import android.content.pm.Flags as PmFlags
import android.os.Build import android.os.Build
import android.os.SystemProperties
import android.permission.PermissionControllerManager import android.permission.PermissionControllerManager
import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_ELIGIBLE import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_ELIGIBLE
import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_EXEMPT_BY_SYSTEM import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_EXEMPT_BY_SYSTEM
@@ -48,6 +49,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R import com.android.settings.R
import com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED import com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED
import com.android.settings.Utils.PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS import com.android.settings.Utils.PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS
import com.android.settings.flags.Flags
import com.android.settings.testutils.TestDeviceConfig import com.android.settings.testutils.TestDeviceConfig
import com.android.settings.testutils.mockAsUser import com.android.settings.testutils.mockAsUser
import com.android.settingslib.spaprivileged.framework.common.appHibernationManager import com.android.settingslib.spaprivileged.framework.common.appHibernationManager
@@ -161,8 +163,8 @@ class HibernationSwitchPreferenceTest {
} }
private fun isArchivingEnabled() = private fun isArchivingEnabled() =
Flags.archiving() || "true" == System.getProperty("pm.archiving.enabled") PmFlags.archiving() || SystemProperties.getBoolean("pm.archiving.enabled", false)
|| Flags.appArchiving()
@Test @Test
fun `An app targets Q with ops mode default when hibernation targets pre S - not exempted`() { fun `An app targets Q with ops mode default when hibernation targets pre S - not exempted`() {
mockOpsMode(MODE_DEFAULT) mockOpsMode(MODE_DEFAULT)