blob: 3783b8a945ae77d3d7c505e1b1e1e48b971a1c39 [file] [log] [blame]
/*
* Copyright (C) 2023 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.applications.appcompat;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
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 com.android.settings.applications.appcompat.UserAspectRatioManager.KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN;
import static com.android.settings.applications.appcompat.UserAspectRatioManager.KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.provider.DeviceConfig;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.internal.R;
import com.android.settings.testutils.ResourcesUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
/**
* To run this test: atest SettingsUnitTests:UserAspectRatioManagerTest
*/
@RunWith(AndroidJUnit4.class)
public class UserAspectRatioManagerTest {
private Context mContext;
private Resources mResources;
private UserAspectRatioManager mUtils;
private String mOriginalSettingsFlag;
private String mOriginalFullscreenFlag;
private String mPackageName = "com.test.mypackage";
private LauncherApps mLauncherApps;
private List<LauncherActivityInfo> mLauncherActivities;
@Before
public void setUp() {
mContext = spy(ApplicationProvider.getApplicationContext());
mResources = mock(Resources.class);
mLauncherApps = mock(LauncherApps.class);
mLauncherActivities = mock(List.class);
when(mContext.getResources()).thenReturn(mResources);
when(mContext.getSystemService(LauncherApps.class)).thenReturn(mLauncherApps);
enableAllDefaultAspectRatioOptions();
mUtils = new UserAspectRatioManager(mContext);
doReturn(mLauncherActivities).when(mLauncherApps).getActivityList(anyString(), any());
mOriginalSettingsFlag = DeviceConfig.getProperty(
DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS);
setAspectRatioSettingsBuildTimeFlagEnabled(true);
setAspectRatioSettingsDeviceConfigEnabled("true" /* enabled */, false /* makeDefault */);
mOriginalFullscreenFlag = DeviceConfig.getProperty(
DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN);
setAspectRatioFullscreenBuildTimeFlagEnabled(true);
setAspectRatioFullscreenDeviceConfigEnabled("true" /* enabled */, false /* makeDefault */);
}
@After
public void tearDown() {
setAspectRatioSettingsDeviceConfigEnabled(mOriginalSettingsFlag, true /* makeDefault */);
setAspectRatioFullscreenDeviceConfigEnabled(mOriginalFullscreenFlag,
true /* makeDefault */);
}
@Test
public void testCanDisplayAspectRatioUi() {
final ApplicationInfo canDisplay = new ApplicationInfo();
canDisplay.packageName = "com.app.candisplay";
doReturn(false).when(mLauncherActivities).isEmpty();
assertTrue(mUtils.canDisplayAspectRatioUi(canDisplay));
final ApplicationInfo noLauncherEntry = new ApplicationInfo();
noLauncherEntry.packageName = "com.app.nolauncherentry";
doReturn(true).when(mLauncherActivities).isEmpty();
assertFalse(mUtils.canDisplayAspectRatioUi(noLauncherEntry));
}
@Test
public void testCanDisplayAspectRatioUi_hasLauncher_propertyFalse_returnFalse()
throws PackageManager.NameNotFoundException {
mockProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, false);
doReturn(false).when(mLauncherActivities).isEmpty();
final ApplicationInfo canDisplay = new ApplicationInfo();
canDisplay.packageName = mPackageName;
assertFalse(mUtils.canDisplayAspectRatioUi(canDisplay));
}
@Test
public void testCanDisplayAspectRatioUi_noLauncher_propertyTrue_returnFalse()
throws PackageManager.NameNotFoundException {
mockProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, true);
doReturn(true).when(mLauncherActivities).isEmpty();
final ApplicationInfo noLauncherEntry = new ApplicationInfo();
noLauncherEntry.packageName = mPackageName;
assertFalse(mUtils.canDisplayAspectRatioUi(noLauncherEntry));
}
@Test
public void testIsFeatureEnabled() {
assertTrue(UserAspectRatioManager.isFeatureEnabled(mContext));
}
@Test
public void testIsFeatureEnabled_disabledBuildTimeFlag_returnFalse() {
setAspectRatioSettingsBuildTimeFlagEnabled(false);
assertFalse(UserAspectRatioManager.isFeatureEnabled(mContext));
}
@Test
public void testIsFeatureEnabled_disabledRuntimeFlag_returnFalse() {
setAspectRatioSettingsDeviceConfigEnabled("false" /* enabled */, false /* makeDefault */);
assertFalse(UserAspectRatioManager.isFeatureEnabled(mContext));
}
@Test
public void testIsFullscreenOptionEnabled() {
assertTrue(mUtils.isFullscreenOptionEnabled(mPackageName));
}
@Test
public void testIsFullscreenOptionEnabled_settingsDisabled_returnFalse() {
setAspectRatioFullscreenBuildTimeFlagEnabled(false);
assertFalse(mUtils.isFullscreenOptionEnabled(mPackageName));
}
@Test
public void testIsFullscreenOptionEnabled_disabledBuildTimeFlag_returnFalse() {
setAspectRatioFullscreenBuildTimeFlagEnabled(false);
assertFalse(mUtils.isFullscreenOptionEnabled(mPackageName));
}
@Test
public void testIsFullscreenOptionEnabled_disabledRuntimeFlag_returnFalse() {
setAspectRatioFullscreenDeviceConfigEnabled("false" /* enabled */, false /*makeDefault */);
assertFalse(mUtils.isFullscreenOptionEnabled(mPackageName));
}
@Test
public void testIsFullscreenOptionEnabled_propertyFalse_returnsFalse()
throws PackageManager.NameNotFoundException {
mockProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE, false);
assertFalse(mUtils.isFullscreenOptionEnabled(mPackageName));
}
@Test
public void testIsFullscreenOptionEnabled_propertyTrue_configDisabled_returnsFalse()
throws PackageManager.NameNotFoundException {
mockProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE, true);
setAspectRatioFullscreenDeviceConfigEnabled("false" /* enabled */, false /*makeDefault */);
assertFalse(mUtils.isFullscreenOptionEnabled(mPackageName));
}
@Test
public void testHasAspectRatioOption_fullscreen() {
assertTrue(mUtils.hasAspectRatioOption(USER_MIN_ASPECT_RATIO_FULLSCREEN,
mPackageName));
assertTrue(mUtils.hasAspectRatioOption(USER_MIN_ASPECT_RATIO_SPLIT_SCREEN,
mPackageName));
// Only fullscreen option should be disabled
when(mUtils.isFullscreenOptionEnabled(mPackageName)).thenReturn(false);
assertFalse(mUtils.hasAspectRatioOption(USER_MIN_ASPECT_RATIO_FULLSCREEN,
mPackageName));
assertTrue(mUtils.hasAspectRatioOption(USER_MIN_ASPECT_RATIO_SPLIT_SCREEN,
mPackageName));
}
@Test
public void testGetUserMinAspectRatioEntry() {
final Context context = ApplicationProvider.getApplicationContext();
// R.string.user_aspect_ratio_app_default
final String appDefault = ResourcesUtils.getResourcesString(context,
"user_aspect_ratio_app_default");
assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_UNSET, mPackageName))
.isEqualTo(appDefault);
// should always return default if value does not correspond to anything
assertThat(mUtils.getUserMinAspectRatioEntry(-1, mPackageName))
.isEqualTo(appDefault);
// R.string.user_aspect_ratio_half_screen
assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_SPLIT_SCREEN,
mPackageName)).isEqualTo(ResourcesUtils.getResourcesString(context,
"user_aspect_ratio_half_screen"));
// R.string.user_aspect_ratio_display_size
assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_DISPLAY_SIZE,
mPackageName)).isEqualTo(ResourcesUtils.getResourcesString(context,
"user_aspect_ratio_device_size"));
// R.string.user_aspect_ratio_16_9
assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_16_9, mPackageName))
.isEqualTo(ResourcesUtils.getResourcesString(context, "user_aspect_ratio_16_9"));
// R.string.user_aspect_ratio_4_3
assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_4_3, mPackageName))
.isEqualTo(ResourcesUtils.getResourcesString(context, "user_aspect_ratio_4_3"));
// R.string.user_aspect_ratio_3_2
assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_3_2, mPackageName))
.isEqualTo(ResourcesUtils.getResourcesString(context, "user_aspect_ratio_3_2"));
// R.string.user_aspect_ratio_fullscreen
assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_FULLSCREEN,
mPackageName)).isEqualTo(ResourcesUtils.getResourcesString(context,
"user_aspect_ratio_fullscreen"));
}
@Test
public void testGetUserMinAspectRatioEntry_fullscreenDisabled_shouldReturnDefault() {
setAspectRatioFullscreenBuildTimeFlagEnabled(false);
assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_FULLSCREEN,
mPackageName)).isEqualTo(ResourcesUtils.getResourcesString(
ApplicationProvider.getApplicationContext(),
"user_aspect_ratio_app_default"));
}
@Test
public void testGetUserMinAspectRatioEntry_nonDefaultString_shouldReturnNewString() {
final String newOptionName = "new_option_name";
when(mResources.getIntArray(anyInt())).thenReturn(new int[] {USER_MIN_ASPECT_RATIO_UNSET});
when(mResources.getStringArray(anyInt())).thenReturn(new String[] {newOptionName});
mUtils = new UserAspectRatioManager(mContext);
assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_UNSET, mPackageName))
.isEqualTo(newOptionName);
}
@Test
public void testGetUserMinAspectRatioMapping_noAppDefault_shouldThrowException() {
when(mResources.getIntArray(anyInt())).thenReturn(new int[] {USER_MIN_ASPECT_RATIO_4_3});
when(mResources.getStringArray(anyInt())).thenReturn(new String[] {"4:3"});
assertThrows(RuntimeException.class, () -> new UserAspectRatioManager(mContext));
}
@Test
public void testGetUserMinAspectRatioMapping_configLengthMismatch_shouldThrowException() {
when(mResources.getIntArray(anyInt())).thenReturn(new int[] {
USER_MIN_ASPECT_RATIO_UNSET,
USER_MIN_ASPECT_RATIO_4_3});
when(mResources.getStringArray(anyInt())).thenReturn(new String[] {"4:3"});
assertThrows(RuntimeException.class, () -> new UserAspectRatioManager(mContext));
}
private void enableAllDefaultAspectRatioOptions() {
final int[] aspectRatioOptions = new int[] {
USER_MIN_ASPECT_RATIO_UNSET,
USER_MIN_ASPECT_RATIO_SPLIT_SCREEN,
USER_MIN_ASPECT_RATIO_DISPLAY_SIZE,
USER_MIN_ASPECT_RATIO_4_3,
USER_MIN_ASPECT_RATIO_16_9,
USER_MIN_ASPECT_RATIO_3_2,
USER_MIN_ASPECT_RATIO_FULLSCREEN};
when(mResources.getIntArray(anyInt())).thenReturn(aspectRatioOptions);
// String array config overlay with @null values so default strings should be used
when(mResources.getStringArray(anyInt())).thenReturn(new String[aspectRatioOptions.length]);
final Context context = ApplicationProvider.getApplicationContext();
mockString(context, "user_aspect_ratio_app_default");
mockString(context, "user_aspect_ratio_half_screen");
mockString(context, "user_aspect_ratio_device_size");
mockString(context, "user_aspect_ratio_4_3");
mockString(context, "user_aspect_ratio_16_9");
mockString(context, "user_aspect_ratio_3_2");
mockString(context, "user_aspect_ratio_fullscreen");
}
private void mockString(Context context, String stringResName) {
final int resId = ResourcesUtils.getResourcesId(context, "string", stringResName);
final String string = ResourcesUtils.getResourcesString(context, stringResName);
when(mContext.getString(resId)).thenReturn(string);
}
private void mockProperty(String propertyName, boolean value)
throws PackageManager.NameNotFoundException {
PackageManager.Property prop = new PackageManager.Property(
propertyName, value, mPackageName, "" /* className */);
PackageManager pm = mock(PackageManager.class);
when(mContext.getPackageManager()).thenReturn(pm);
when(pm.getProperty(propertyName, mPackageName)).thenReturn(prop);
}
private void setAspectRatioSettingsBuildTimeFlagEnabled(boolean enabled) {
when(mResources.getBoolean(R.bool.config_appCompatUserAppAspectRatioSettingsIsEnabled))
.thenReturn(enabled);
}
private void setAspectRatioSettingsDeviceConfigEnabled(String enabled, boolean makeDefault) {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS, enabled, makeDefault);
}
private void setAspectRatioFullscreenBuildTimeFlagEnabled(boolean enabled) {
when(mResources.getBoolean(R.bool.config_appCompatUserAppAspectRatioFullscreenIsEnabled))
.thenReturn(enabled);
}
private void setAspectRatioFullscreenDeviceConfigEnabled(String enabled, boolean makeDefault) {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN, enabled, makeDefault);
}
}