Follow config overlay's order of aspect ratio options

Fix flaky UserAspectRatioAppsPageProviderTest by using advanceUntilIdle
to make sure all coroutines are finished before asserting.

Bug: 325911424
Test: atest UserAspectRatioDetailsTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:32815ad699448c5c5b1f38df6d2d2a881d4251c1)
Merged-In: I83e9a7f31536c1a006789722b0310f3364d14337
Change-Id: I83e9a7f31536c1a006789722b0310f3364d14337
This commit is contained in:
Graciela Wissen Putri
2024-02-29 17:55:52 +00:00
committed by Cherrypicker Worker
parent a6f283382a
commit a0f573a35e
6 changed files with 79 additions and 22 deletions

View File

@@ -28,7 +28,8 @@
settings:searchable="false"/> settings:searchable="false"/>
<com.android.settingslib.widget.ActionButtonsPreference <com.android.settingslib.widget.ActionButtonsPreference
android:key="header_view" /> android:key="header_view"
android:order="-999"/>
<com.android.settings.applications.appcompat.RadioWithImagePreference <com.android.settings.applications.appcompat.RadioWithImagePreference
android:key="app_default_pref" android:key="app_default_pref"

View File

@@ -66,7 +66,8 @@ public class UserAspectRatioDetails extends AppInfoBase implements
private static final String TAG = UserAspectRatioDetails.class.getSimpleName(); private static final String TAG = UserAspectRatioDetails.class.getSimpleName();
private static final String KEY_HEADER_SUMMARY = "app_aspect_ratio_summary"; private static final String KEY_HEADER_SUMMARY = "app_aspect_ratio_summary";
private static final String KEY_HEADER_BUTTONS = "header_view"; @VisibleForTesting
static final String KEY_HEADER_BUTTONS = "header_view";
private static final String KEY_PREF_HALF_SCREEN = "half_screen_pref"; private static final String KEY_PREF_HALF_SCREEN = "half_screen_pref";
private static final String KEY_PREF_DISPLAY_SIZE = "display_size_pref"; private static final String KEY_PREF_DISPLAY_SIZE = "display_size_pref";
@@ -237,6 +238,7 @@ public class UserAspectRatioDetails extends AppInfoBase implements
return; return;
} }
pref.setTitle(mUserAspectRatioManager.getAccessibleEntry(aspectRatio, mPackageName)); pref.setTitle(mUserAspectRatioManager.getAccessibleEntry(aspectRatio, mPackageName));
pref.setOrder(getAspectRatioManager().getUserMinAspectRatioOrder(aspectRatio));
pref.setOnClickListener(this); pref.setOnClickListener(this);
mKeyToAspectRatioMap.put(key, aspectRatio); mKeyToAspectRatioMap.put(key, aspectRatio);
mAspectRatioPreferences.add(pref); mAspectRatioPreferences.add(pref);

View File

@@ -44,6 +44,7 @@ import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.SparseIntArray;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -76,6 +77,7 @@ public class UserAspectRatioManager {
/** Apps that have launcher entry defined in manifest */ /** Apps that have launcher entry defined in manifest */
private final Map<Integer, String> mUserAspectRatioMap; private final Map<Integer, String> mUserAspectRatioMap;
private final Map<Integer, CharSequence> mUserAspectRatioA11yMap; private final Map<Integer, CharSequence> mUserAspectRatioA11yMap;
private final SparseIntArray mUserAspectRatioOrder;
public UserAspectRatioManager(@NonNull Context context) { public UserAspectRatioManager(@NonNull Context context) {
this(context, AppGlobals.getPackageManager()); this(context, AppGlobals.getPackageManager());
@@ -86,6 +88,7 @@ public class UserAspectRatioManager {
mContext = context; mContext = context;
mIPm = pm; mIPm = pm;
mUserAspectRatioA11yMap = new ArrayMap<>(); mUserAspectRatioA11yMap = new ArrayMap<>();
mUserAspectRatioOrder = new SparseIntArray();
mUserAspectRatioMap = getUserMinAspectRatioMapping(); mUserAspectRatioMap = getUserMinAspectRatioMapping();
} }
@@ -152,6 +155,14 @@ public class UserAspectRatioManager {
return getUserMinAspectRatioEntry(aspectRatio, packageName, userId); return getUserMinAspectRatioEntry(aspectRatio, packageName, userId);
} }
/**
* @return the order of the aspect ratio option corresponding to
* config_userAspectRatioOverrideValues
*/
int getUserMinAspectRatioOrder(@PackageManager.UserMinAspectRatio int option) {
return mUserAspectRatioOrder.get(option);
}
/** /**
* Whether user aspect ratio option is specified in * Whether user aspect ratio option is specified in
* {@link R.array.config_userAspectRatioOverrideValues} * {@link R.array.config_userAspectRatioOverrideValues}
@@ -224,7 +235,6 @@ public class UserAspectRatioManager {
&& isFullscreenCompatChangeEnabled(pkgName, userId); && isFullscreenCompatChangeEnabled(pkgName, userId);
} }
@VisibleForTesting
boolean isFullscreenCompatChangeEnabled(String pkgName, int userId) { boolean isFullscreenCompatChangeEnabled(String pkgName, int userId) {
return CompatChanges.isChangeEnabled( return CompatChanges.isChangeEnabled(
OVERRIDE_ANY_ORIENTATION_TO_USER, pkgName, UserHandle.of(userId)); OVERRIDE_ANY_ORIENTATION_TO_USER, pkgName, UserHandle.of(userId));
@@ -281,6 +291,7 @@ public class UserAspectRatioManager {
mUserAspectRatioA11yMap.put(aspectRatioVal, accessibleSequence); mUserAspectRatioA11yMap.put(aspectRatioVal, accessibleSequence);
} }
userMinAspectRatioMap.put(aspectRatioVal, aspectRatioString); userMinAspectRatioMap.put(aspectRatioVal, aspectRatioString);
mUserAspectRatioOrder.put(aspectRatioVal, i);
} }
} }
if (!userMinAspectRatioMap.containsKey(USER_MIN_ASPECT_RATIO_UNSET)) { if (!userMinAspectRatioMap.containsKey(USER_MIN_ASPECT_RATIO_UNSET)) {
@@ -290,6 +301,8 @@ public class UserAspectRatioManager {
if (mIsUserMinAspectRatioAppDefaultFlagEnabled) { if (mIsUserMinAspectRatioAppDefaultFlagEnabled) {
userMinAspectRatioMap.put(USER_MIN_ASPECT_RATIO_APP_DEFAULT, userMinAspectRatioMap.put(USER_MIN_ASPECT_RATIO_APP_DEFAULT,
userMinAspectRatioMap.get(USER_MIN_ASPECT_RATIO_UNSET)); userMinAspectRatioMap.get(USER_MIN_ASPECT_RATIO_UNSET));
mUserAspectRatioOrder.put(USER_MIN_ASPECT_RATIO_APP_DEFAULT,
mUserAspectRatioOrder.get(USER_MIN_ASPECT_RATIO_UNSET));
if (mUserAspectRatioA11yMap.containsKey(USER_MIN_ASPECT_RATIO_UNSET)) { if (mUserAspectRatioA11yMap.containsKey(USER_MIN_ASPECT_RATIO_UNSET)) {
mUserAspectRatioA11yMap.put(USER_MIN_ASPECT_RATIO_APP_DEFAULT, mUserAspectRatioA11yMap.put(USER_MIN_ASPECT_RATIO_APP_DEFAULT,
mUserAspectRatioA11yMap.get(USER_MIN_ASPECT_RATIO_UNSET)); mUserAspectRatioA11yMap.get(USER_MIN_ASPECT_RATIO_UNSET));

View File

@@ -62,6 +62,7 @@ import com.android.settingslib.spaprivileged.template.app.AppListItem
import com.android.settingslib.spaprivileged.template.app.AppListItemModel import com.android.settingslib.spaprivileged.template.app.AppListItemModel
import com.android.settingslib.spaprivileged.template.app.AppListPage import com.android.settingslib.spaprivileged.template.app.AppListPage
import com.google.common.annotations.VisibleForTesting import com.google.common.annotations.VisibleForTesting
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
@@ -130,8 +131,10 @@ data class UserAspectRatioAppListItemModel(
val canDisplay: Boolean, val canDisplay: Boolean,
) : AppRecord ) : AppRecord
class UserAspectRatioAppListModel(private val context: Context) class UserAspectRatioAppListModel(
: AppListModel<UserAspectRatioAppListItemModel> { private val context: Context,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) : AppListModel<UserAspectRatioAppListItemModel> {
private val packageManager = context.packageManager private val packageManager = context.packageManager
private val userAspectRatioManager = UserAspectRatioManager(context) private val userAspectRatioManager = UserAspectRatioManager(context)
@@ -203,7 +206,7 @@ class UserAspectRatioAppListModel(private val context: Context)
flow { flow {
emit(userAspectRatioManager.getUserMinAspectRatioEntry(record.userOverride, emit(userAspectRatioManager.getUserMinAspectRatioEntry(record.userOverride,
record.app.packageName, record.app.userId)) record.app.packageName, record.app.userId))
}.flowOn(Dispatchers.IO) }.flowOn(ioDispatcher)
}.collectAsStateWithLifecycle(initialValue = stringResource(R.string.summary_placeholder)) }.collectAsStateWithLifecycle(initialValue = stringResource(R.string.summary_placeholder))
return { summary } return { summary }
} }

View File

@@ -16,16 +16,19 @@
package com.android.settings.applications.appcompat; package com.android.settings.applications.appcompat;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_APP_DEFAULT; import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_APP_DEFAULT;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN; import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET; import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
import static com.android.settings.applications.AppInfoBase.ARG_PACKAGE_NAME; import static com.android.settings.applications.AppInfoBase.ARG_PACKAGE_NAME;
import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_HEADER_BUTTONS;
import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_PREF_3_2; import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_PREF_3_2;
import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_PREF_DEFAULT; import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_PREF_DEFAULT;
import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_PREF_FULLSCREEN; import static com.android.settings.applications.appcompat.UserAspectRatioDetails.KEY_PREF_FULLSCREEN;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
@@ -98,6 +101,31 @@ public class UserAspectRatioDetailsTest {
mMetricsFeatureProvider = featureFactory.metricsFeatureProvider; mMetricsFeatureProvider = featureFactory.metricsFeatureProvider;
} }
@Test
public void testOrderOfOptionsFollowsConfig() {
doReturn(true).when(mUserAspectRatioManager)
.hasAspectRatioOption(anyInt(), anyString());
doReturn(0).when(mUserAspectRatioManager)
.getUserMinAspectRatioOrder(USER_MIN_ASPECT_RATIO_3_2);
doReturn(1).when(mUserAspectRatioManager)
.getUserMinAspectRatioOrder(USER_MIN_ASPECT_RATIO_FULLSCREEN);
doReturn(2).when(mUserAspectRatioManager)
.getUserMinAspectRatioOrder(USER_MIN_ASPECT_RATIO_UNSET);
rule.getScenario().onActivity(a -> doReturn(a).when(mFragment).getActivity());
final Bundle args = new Bundle();
args.putString(ARG_PACKAGE_NAME, anyString());
mFragment.setArguments(args);
mFragment.onCreate(Bundle.EMPTY);
final int topOfList = mFragment.findPreference(KEY_HEADER_BUTTONS).getOrder();
assertTrue(topOfList < mFragment.findPreference(KEY_PREF_3_2).getOrder());
assertTrue(mFragment.findPreference(KEY_PREF_3_2).getOrder()
< mFragment.findPreference(KEY_PREF_FULLSCREEN).getOrder());
assertTrue(mFragment.findPreference(KEY_PREF_FULLSCREEN).getOrder()
< mFragment.findPreference(KEY_PREF_DEFAULT).getOrder());
}
@Test @Test
public void onRadioButtonClicked_prefChange_shouldStopActivity() throws RemoteException { public void onRadioButtonClicked_prefChange_shouldStopActivity() throws RemoteException {
doReturn(USER_MIN_ASPECT_RATIO_UNSET).when(mFragment) doReturn(USER_MIN_ASPECT_RATIO_UNSET).when(mFragment)

View File

@@ -32,7 +32,11 @@ import com.android.settingslib.spa.testutils.FakeNavControllerWrapper
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
import com.android.settingslib.spaprivileged.template.app.AppListItemModel import com.android.settingslib.spaprivileged.template.app.AppListItemModel
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@@ -45,6 +49,8 @@ import org.junit.runner.RunWith
class UserAspectRatioAppsPageProviderTest { class UserAspectRatioAppsPageProviderTest {
@get:Rule @get:Rule
val composeTestRule = createComposeRule() val composeTestRule = createComposeRule()
private val testDispatcher = StandardTestDispatcher()
private val testScope = TestScope(testDispatcher)
private val context: Context = ApplicationProvider.getApplicationContext() private val context: Context = ApplicationProvider.getApplicationContext()
private val fakeNavControllerWrapper = FakeNavControllerWrapper() private val fakeNavControllerWrapper = FakeNavControllerWrapper()
@@ -137,33 +143,37 @@ class UserAspectRatioAppsPageProviderTest {
} }
} }
@OptIn(ExperimentalCoroutinesApi::class)
@Test @Test
fun aspectRatioAppListModel_getSummaryDefault() { fun aspectRatioAppListModel_getSummaryDefault() = testScope.runTest {
val summary = getSummary(USER_MIN_ASPECT_RATIO_UNSET) val summary = setSummary(USER_MIN_ASPECT_RATIO_UNSET)
advanceUntilIdle()
assertThat(summary).isEqualTo(context.getString(R.string.user_aspect_ratio_app_default)) assertThat(summary()).isEqualTo(context.getString(R.string.user_aspect_ratio_app_default))
} }
@OptIn(ExperimentalCoroutinesApi::class)
@Test @Test
fun aspectRatioAppListModel_getSummaryWhenSplitScreen() { fun aspectRatioAppListModel_getSummaryWhenSplitScreen() = testScope.runTest {
val summary = getSummary(USER_MIN_ASPECT_RATIO_SPLIT_SCREEN) val summary = setSummary(USER_MIN_ASPECT_RATIO_SPLIT_SCREEN)
advanceUntilIdle()
assertThat(summary).isEqualTo(context.getString(R.string.user_aspect_ratio_half_screen)) assertThat(summary()).isEqualTo(context.getString(R.string.user_aspect_ratio_half_screen))
} }
private fun getSummary(userOverride: Int): String { private fun setSummary(userOverride: Int): () -> String {
val listModel = UserAspectRatioAppListModel(context) val listModel = UserAspectRatioAppListModel(context, testDispatcher)
val record = UserAspectRatioAppListItemModel(
app = APP,
userOverride = userOverride,
suggested = false,
canDisplay = true,
)
lateinit var summary: () -> String lateinit var summary: () -> String
composeTestRule.setContent { composeTestRule.setContent {
summary = listModel.getSummary(option = 0, summary = listModel.getSummary(option = 0, record = record)
record = UserAspectRatioAppListItemModel(
app = APP,
userOverride = userOverride,
suggested = false,
canDisplay = true,
))
} }
return summary() return summary
} }