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

Commit 08983e8e authored by Graciela Wissen Putri's avatar Graciela Wissen Putri
Browse files

Add opt-out properties for aspect ratio settings

Don't display aspect ratio options if app has opted out. If app has
opted out only for fullscreen, other aspect ratio options should still
be shown.

Bug: 292583399
Test: UserAspectRatioManagerTest
Change-Id: Ia0b223536407f703826d775468c8f8a0b4822e23
parent a277f787
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -201,11 +201,12 @@ public class UserAspectRatioDetails extends AppInfoWithHeader implements
        if (pref == null) {
            return;
        }
        if (!mUserAspectRatioManager.containsAspectRatioOption(aspectRatio)) {
        if (!mUserAspectRatioManager.hasAspectRatioOption(aspectRatio, mPackageName)) {
            pref.setVisible(false);
            return;
        }
        pref.setTitle(mUserAspectRatioManager.getUserMinAspectRatioEntry(aspectRatio));
        pref.setTitle(mUserAspectRatioManager.getUserMinAspectRatioEntry(aspectRatio,
                mPackageName));
        pref.setOnClickListener(this);
        mAspectRatioPreferences.add(pref);
    }
+35 −12
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

package com.android.settings.applications.appcompat;

import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;

import static java.lang.Boolean.FALSE;

import android.app.AppGlobals;
import android.content.Context;
import android.content.Intent;
@@ -63,7 +68,7 @@ public class UserAspectRatioManager {
    public UserAspectRatioManager(@NonNull Context context) {
        mContext = context;
        mIPm = AppGlobals.getPackageManager();
        mInfoHasLauncherEntryList = context.getPackageManager().queryIntentActivities(
        mInfoHasLauncherEntryList = mContext.getPackageManager().queryIntentActivities(
                UserAspectRatioManager.LAUNCHER_ENTRY_INTENT, PackageManager.GET_META_DATA);
        mUserAspectRatioMap = getUserMinAspectRatioMapping();
    }
@@ -85,7 +90,7 @@ public class UserAspectRatioManager {
    public int getUserMinAspectRatioValue(@NonNull String packageName, int uid)
            throws RemoteException {
        final int aspectRatio = mIPm.getUserMinAspectRatio(packageName, uid);
        return containsAspectRatioOption(aspectRatio)
        return hasAspectRatioOption(aspectRatio, packageName)
                ? aspectRatio : PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
    }

@@ -93,8 +98,9 @@ public class UserAspectRatioManager {
     * @return corresponding string for {@link PackageManager.UserMinAspectRatio} value
     */
    @NonNull
    public String getUserMinAspectRatioEntry(@PackageManager.UserMinAspectRatio int aspectRatio) {
        if (!containsAspectRatioOption(aspectRatio))  {
    public String getUserMinAspectRatioEntry(@PackageManager.UserMinAspectRatio int aspectRatio,
            String packageName) {
        if (!hasAspectRatioOption(aspectRatio, packageName))  {
            return mUserAspectRatioMap.get(PackageManager.USER_MIN_ASPECT_RATIO_UNSET);
        }
        return mUserAspectRatioMap.get(aspectRatio);
@@ -107,7 +113,7 @@ public class UserAspectRatioManager {
    public String getUserMinAspectRatioEntry(@NonNull String packageName, int uid)
            throws RemoteException {
        final int aspectRatio = getUserMinAspectRatioValue(packageName, uid);
        return getUserMinAspectRatioEntry(aspectRatio);
        return getUserMinAspectRatioEntry(aspectRatio, packageName);
    }

    /**
@@ -115,9 +121,10 @@ public class UserAspectRatioManager {
     * {@link R.array.config_userAspectRatioOverrideValues}
     * and is enabled by device config
     */
    public boolean containsAspectRatioOption(@PackageManager.UserMinAspectRatio int option) {
    public boolean hasAspectRatioOption(@PackageManager.UserMinAspectRatio int option,
            String packageName) {
        if (option == PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN
                && !isFullscreenOptionEnabled()) {
                && !isFullscreenOptionEnabled(packageName)) {
            return false;
        }
        return mUserAspectRatioMap.containsKey(option);
@@ -136,20 +143,25 @@ public class UserAspectRatioManager {
     * will be overridable.
     */
    public boolean canDisplayAspectRatioUi(@NonNull ApplicationInfo app) {
        Boolean appAllowsUserAspectRatioOverride = readComponentProperty(
                mContext.getPackageManager(), app.packageName,
                PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE);
        boolean hasLauncherEntry = mInfoHasLauncherEntryList.stream()
                .anyMatch(info -> info.activityInfo.packageName.equals(app.packageName));
        return hasLauncherEntry;
        return !FALSE.equals(appAllowsUserAspectRatioOverride) && hasLauncherEntry;
    }

    /**
     * Whether fullscreen option in per-app user aspect ratio settings is enabled
     */
    @VisibleForTesting
    boolean isFullscreenOptionEnabled() {
    boolean isFullscreenOptionEnabled(String packageName) {
        Boolean appAllowsFullscreenOption = readComponentProperty(mContext.getPackageManager(),
                packageName, PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE);
        final boolean isBuildTimeFlagEnabled = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_appCompatUserAppAspectRatioFullscreenIsEnabled);
        return isBuildTimeFlagEnabled && getValueFromDeviceConfig(
                KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN,
        return !FALSE.equals(appAllowsFullscreenOption) && isBuildTimeFlagEnabled
                && getValueFromDeviceConfig(KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN,
                    DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_FULLSCREEN);
    }

@@ -217,6 +229,17 @@ public class UserAspectRatioManager {
        }
    }

    @Nullable
    private static Boolean readComponentProperty(PackageManager pm, String packageName,
            String propertyName) {
        try {
            return pm.getProperty(propertyName, packageName).getBoolean();
        } catch (PackageManager.NameNotFoundException e) {
            // No such property name
        }
        return null;
    }

    @VisibleForTesting
    void addInfoHasLauncherEntry(@NonNull ResolveInfo infoHasLauncherEntry) {
        mInfoHasLauncherEntryList.add(infoHasLauncherEntry);
+7 −6
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ fun UserAspectRatioAppList(

data class UserAspectRatioAppListItemModel(
    override val app: ApplicationInfo,
    val override: Int,
    val userOverride: Int,
    val suggested: Boolean,
    val canDisplay: Boolean,
) : AppRecord
@@ -137,7 +137,7 @@ class UserAspectRatioAppListModel(private val context: Context)
        recordList: List<UserAspectRatioAppListItemModel>
    ): List<SpinnerOption> {
        val hasSuggested = recordList.any { it.suggested }
        val hasOverride = recordList.any { it.override != USER_MIN_ASPECT_RATIO_UNSET }
        val hasOverride = recordList.any { it.userOverride != USER_MIN_ASPECT_RATIO_UNSET }
        val options = mutableListOf(SpinnerItem.All)
        // Add suggested filter first as default
        if (hasSuggested) options.add(0, SpinnerItem.Suggested)
@@ -165,7 +165,7 @@ class UserAspectRatioAppListModel(private val context: Context)
                    app = app,
                    suggested = !app.isSystemApp && getPackageAndActivityInfo(
                                    app)?.isFixedOrientationOrAspectRatio() == true,
                    override = userAspectRatioManager.getUserMinAspectRatioValue(
                    userOverride = userAspectRatioManager.getUserMinAspectRatioValue(
                                    app.packageName, uid),
                    canDisplay = userAspectRatioManager.canDisplayAspectRatioUi(app),
                )
@@ -179,7 +179,7 @@ class UserAspectRatioAppListModel(private val context: Context)
    ): Flow<List<UserAspectRatioAppListItemModel>> = recordListFlow.filterItem(
        when (SpinnerItem.values().getOrNull(option)) {
            SpinnerItem.Suggested -> ({ it.canDisplay && it.suggested })
            SpinnerItem.Overridden -> ({ it.override != USER_MIN_ASPECT_RATIO_UNSET })
            SpinnerItem.Overridden -> ({ it.userOverride != USER_MIN_ASPECT_RATIO_UNSET })
            else -> ({ it.canDisplay })
        }
    )
@@ -187,9 +187,10 @@ class UserAspectRatioAppListModel(private val context: Context)
    @OptIn(ExperimentalLifecycleComposeApi::class)
    @Composable
    override fun getSummary(option: Int, record: UserAspectRatioAppListItemModel) : State<String> =
        remember(record.override) {
        remember(record.userOverride) {
            flow {
                emit(userAspectRatioManager.getUserMinAspectRatioEntry(record.override))
                emit(userAspectRatioManager.getUserMinAspectRatioEntry(record.userOverride,
                    record.app.packageName))
            }.flowOn(Dispatchers.IO)
        }.collectAsStateWithLifecycle(initialValue = stringResource(R.string.summary_placeholder))

+16 −10
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.os.Build
import android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER
import android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.test.assertIsDisplayed
@@ -34,15 +35,13 @@ import androidx.compose.ui.test.performClick
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.dx.mockito.inline.extended.ExtendedMockito
import android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER
import com.android.settings.R
import com.android.settings.applications.appinfo.AppInfoDashboardFragment
import com.android.settings.applications.appcompat.UserAspectRatioDetails
import com.android.settings.applications.appcompat.UserAspectRatioManager
import com.android.settings.applications.appinfo.AppInfoDashboardFragment
import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider
import com.android.settings.testutils.TestDeviceConfig
import com.android.settingslib.spa.testutils.delay
import com.android.settingslib.spa.testutils.waitUntilExists
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -51,8 +50,6 @@ import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.eq
import org.mockito.Mockito.mock
import org.mockito.MockitoSession
import org.mockito.Spy
import org.mockito.quality.Strictness
@@ -77,8 +74,6 @@ class UserAspectRatioAppPreferenceTest {
    private val aspectRatioEnabledConfig =
        TestDeviceConfig(NAMESPACE_WINDOW_MANAGER, "enable_app_compat_user_aspect_ratio_settings")

    private lateinit var userAspectRatioManager: UserAspectRatioManager

    @Mock
    private lateinit var packageManager: PackageManager

@@ -92,7 +87,6 @@ class UserAspectRatioAppPreferenceTest {
            .startMocking()
        whenever(context.resources).thenReturn(resources)
        whenever(context.packageManager).thenReturn(packageManager)
        userAspectRatioManager = mock(UserAspectRatioManager::class.java)
    }

    @After
@@ -130,6 +124,8 @@ class UserAspectRatioAppPreferenceTest {

    @Test
    fun whenCannotDisplayAspectRatioUiAndConfigTrue_notDisplayed() {
        // True is ignored but need this here or getBoolean will complain null object
        mockProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, true)
        setConfig(true)

        setContent()
@@ -139,6 +135,8 @@ class UserAspectRatioAppPreferenceTest {

    @Test
    fun whenCanDisplayAspectRatioUiAndConfigTrue_Displayed() {
        // True is ignored but need this here or getBoolean will complain null object
        mockProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, true)
        setConfig(true)
        whenever(packageManager.queryIntentActivities(any(), anyInt()))
            .thenReturn(listOf(RESOLVE_INFO))
@@ -155,6 +153,8 @@ class UserAspectRatioAppPreferenceTest {

    @Test
    fun onClick_startActivity() {
        // True is ignored but need this here or getBoolean will complain null object
        mockProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, true)
        setConfig(true)
        whenever(packageManager.queryIntentActivities(any(), anyInt()))
            .thenReturn(listOf(RESOLVE_INFO))
@@ -188,8 +188,14 @@ class UserAspectRatioAppPreferenceTest {
        composeTestRule.delay()
    }

    private fun mockProperty(propertyName: String, value: Boolean) {
        val prop = PackageManager.Property(
            propertyName, value, PACKAGE_NAME, "" /* className */)
        whenever(packageManager.getProperty(propertyName, PACKAGE_NAME)).thenReturn(prop)
    }

    private companion object {
        const val PACKAGE_NAME = "package.name"
        const val PACKAGE_NAME = "com.test.mypackage"
        const val UID = 123
        val APP = ApplicationInfo().apply {
            packageName = PACKAGE_NAME
+4 −4
Original line number Diff line number Diff line
@@ -154,14 +154,14 @@ class UserAspectRatioAppsPageProviderTest {
            .isEqualTo(context.getString(R.string.user_aspect_ratio_half_screen))
    }

    private fun setSummaryState(override: Int): State<String> {
    private fun setSummaryState(userOverride: Int): State<String> {
        val listModel = UserAspectRatioAppListModel(context)
        lateinit var summaryState: State<String>
        composeTestRule.setContent {
            summaryState = listModel.getSummary(option = 0,
                record = UserAspectRatioAppListItemModel(
                    app = APP,
                    override = override,
                    userOverride = userOverride,
                    suggested = false,
                    canDisplay = true,
                ))
@@ -182,13 +182,13 @@ class UserAspectRatioAppsPageProviderTest {
        }
        private val APP_RECORD_SUGGESTED = UserAspectRatioAppListItemModel(
            APP,
            override = USER_MIN_ASPECT_RATIO_UNSET,
            userOverride = USER_MIN_ASPECT_RATIO_UNSET,
            suggested = true,
            canDisplay = true
        )
        private val APP_RECORD_NOT_DISPLAYED = UserAspectRatioAppListItemModel(
            APP,
            override = USER_MIN_ASPECT_RATIO_UNSET,
            userOverride = USER_MIN_ASPECT_RATIO_UNSET,
            suggested = true,
            canDisplay = false
        )
Loading