Merge "Add device config tests to GameManagerServiceTests" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4b280f2955
@@ -199,13 +199,12 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
@Override
|
||||
public void onPropertiesChanged(Properties properties) {
|
||||
synchronized (mDeviceConfigLock) {
|
||||
for (String key : properties.getKeyset()) {
|
||||
for (final String packageName : properties.getKeyset()) {
|
||||
try {
|
||||
// Check if the package is installed before caching it.
|
||||
final String packageName = keyToPackageName(key);
|
||||
mPackageManager.getPackageInfo(packageName, 0);
|
||||
final GamePackageConfiguration config =
|
||||
GamePackageConfiguration.fromProperties(key, properties);
|
||||
GamePackageConfiguration.fromProperties(packageName, properties);
|
||||
if (config.isValid()) {
|
||||
putConfig(config);
|
||||
} else {
|
||||
@@ -290,8 +289,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
private final String mPackageName;
|
||||
private final ArrayMap<Integer, GameModeConfiguration> mModeConfigs;
|
||||
|
||||
private GamePackageConfiguration(String keyName) {
|
||||
mPackageName = keyToPackageName(keyName);
|
||||
private GamePackageConfiguration(String packageName) {
|
||||
mPackageName = packageName;
|
||||
mModeConfigs = new ArrayMap<>();
|
||||
}
|
||||
|
||||
@@ -563,9 +562,9 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void loadDeviceConfigLocked() {
|
||||
void loadDeviceConfigLocked() {
|
||||
final List<PackageInfo> packages = mPackageManager.getInstalledPackages(0);
|
||||
final String[] packageNames = packages.stream().map(e -> packageNameToKey(e.packageName))
|
||||
final String[] packageNames = packages.stream().map(e -> e.packageName)
|
||||
.toArray(String[]::new);
|
||||
synchronized (mDeviceConfigLock) {
|
||||
final Properties properties = DeviceConfig.getProperties(
|
||||
@@ -680,8 +679,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
case ACTION_PACKAGE_CHANGED:
|
||||
synchronized (mDeviceConfigLock) {
|
||||
Properties properties = DeviceConfig.getProperties(
|
||||
DeviceConfig.NAMESPACE_GAME_OVERLAY,
|
||||
packageNameToKey(packageName));
|
||||
DeviceConfig.NAMESPACE_GAME_OVERLAY, packageName);
|
||||
for (String key : properties.getKeyset()) {
|
||||
GamePackageConfiguration config =
|
||||
GamePackageConfiguration.fromProperties(key,
|
||||
@@ -692,7 +690,9 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
break;
|
||||
case ACTION_PACKAGE_REMOVED:
|
||||
disableCompatScale(packageName);
|
||||
mConfigs.remove(packageName);
|
||||
synchronized (mDeviceConfigLock) {
|
||||
mConfigs.remove(packageName);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
@@ -710,23 +710,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
mDeviceConfigListener = new DeviceConfigListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid package name characters are [a-zA-Z0-9_] with a '.' delimiter. Policy keys can only use
|
||||
* [a-zA-Z0-9_] so we must handle periods. We do this by appending a '_' to any existing
|
||||
* sequence of '_', then we replace all '.' chars with '_';
|
||||
*/
|
||||
private static String packageNameToKey(String name) {
|
||||
return name.replaceAll("(_+)", "_$1").replaceAll("\\.", "_");
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the last '_' in a sequence with '.' (this can be one or more chars), then replace the
|
||||
* resulting special case '_.' with just '_' to get the original package name.
|
||||
*/
|
||||
private static String keyToPackageName(String key) {
|
||||
return key.replaceAll("(_)(?!\\1)", ".").replaceAll("_\\.", "_");
|
||||
}
|
||||
|
||||
private String dumpDeviceConfigs() {
|
||||
StringBuilder out = new StringBuilder();
|
||||
for (String key : mConfigs.keySet()) {
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
<uses-permission android:name="android.permission.MANAGE_APPOPS"/>
|
||||
<uses-permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG"/>
|
||||
<uses-permission
|
||||
android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
|
||||
|
||||
<!-- needed by MasterClearReceiverTest to display a system dialog -->
|
||||
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
|
||||
|
||||
@@ -16,51 +16,66 @@
|
||||
|
||||
package com.android.server.app;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.GameManager;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.DeviceConfig;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoSession;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
public class GameManagerServiceTests {
|
||||
|
||||
@Mock MockContext mMockContext;
|
||||
private static final String TAG = "GameServiceTests";
|
||||
private static final String PACKAGE_NAME_INVALID = "com.android.app";
|
||||
private static final int USER_ID_1 = 1001;
|
||||
private static final int USER_ID_2 = 1002;
|
||||
|
||||
private MockitoSession mMockingSession;
|
||||
private String mPackageName;
|
||||
@Mock
|
||||
private PackageManager mMockPackageManager;
|
||||
|
||||
// Stolen from ConnectivityServiceTest.MockContext
|
||||
static class MockContext extends ContextWrapper {
|
||||
class MockContext extends ContextWrapper {
|
||||
private static final String TAG = "MockContext";
|
||||
|
||||
// Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
|
||||
private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
|
||||
|
||||
@Mock
|
||||
private final MockPackageManager mMockPackageManager;
|
||||
|
||||
MockContext(Context base) {
|
||||
super(base);
|
||||
mMockPackageManager = new MockPackageManager();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,15 +127,31 @@ public class GameManagerServiceTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Mock
|
||||
private MockContext mMockContext;
|
||||
|
||||
private String mPackageName;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mMockingSession = mockitoSession()
|
||||
.initMocks(this)
|
||||
.mockStatic(DeviceConfig.class)
|
||||
.strictness(Strictness.WARN)
|
||||
.startMocking();
|
||||
mMockContext = new MockContext(InstrumentationRegistry.getContext());
|
||||
mPackageName = mMockContext.getPackageName();
|
||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.category = ApplicationInfo.CATEGORY_GAME;
|
||||
final PackageInfo pi = new PackageInfo();
|
||||
pi.packageName = mPackageName;
|
||||
final List<PackageInfo> packages = new ArrayList<>();
|
||||
packages.add(pi);
|
||||
when(mMockPackageManager.getInstalledPackages(anyInt())).thenReturn(packages);
|
||||
when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
|
||||
.thenReturn(applicationInfo);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (mMockingSession != null) {
|
||||
mMockingSession.finishMocking();
|
||||
}
|
||||
}
|
||||
|
||||
private void mockModifyGameModeGranted() {
|
||||
@@ -133,6 +164,60 @@ public class GameManagerServiceTests {
|
||||
PackageManager.PERMISSION_DENIED);
|
||||
}
|
||||
|
||||
private void mockDeviceConfigDefault() {
|
||||
DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
|
||||
DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, "").build();
|
||||
when(DeviceConfig.getProperties(anyString(), anyString()))
|
||||
.thenReturn(properties);
|
||||
}
|
||||
|
||||
private void mockDeviceConfigNone() {
|
||||
DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
|
||||
DeviceConfig.NAMESPACE_GAME_OVERLAY).build();
|
||||
when(DeviceConfig.getProperties(anyString(), anyString()))
|
||||
.thenReturn(properties);
|
||||
}
|
||||
|
||||
private void mockDeviceConfigPerformance() {
|
||||
String configString = "mode=2,downscaleFactor=0.5";
|
||||
DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
|
||||
DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
|
||||
when(DeviceConfig.getProperties(anyString(), anyString()))
|
||||
.thenReturn(properties);
|
||||
}
|
||||
|
||||
private void mockDeviceConfigBattery() {
|
||||
String configString = "mode=3,downscaleFactor=0.7";
|
||||
DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
|
||||
DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
|
||||
when(DeviceConfig.getProperties(anyString(), anyString()))
|
||||
.thenReturn(properties);
|
||||
}
|
||||
|
||||
private void mockDeviceConfigAll() {
|
||||
String configString = "mode=3,downscaleFactor=0.7:mode=2,downscaleFactor=0.5";
|
||||
DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
|
||||
DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
|
||||
when(DeviceConfig.getProperties(anyString(), anyString()))
|
||||
.thenReturn(properties);
|
||||
}
|
||||
|
||||
private void mockDeviceConfigInvalid() {
|
||||
String configString = "mode=2,downscaleFactor=0.55";
|
||||
DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
|
||||
DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
|
||||
when(DeviceConfig.getProperties(anyString(), anyString()))
|
||||
.thenReturn(properties);
|
||||
}
|
||||
|
||||
private void mockDeviceConfigMalformed() {
|
||||
String configString = "adsljckv=nin3rn9hn1231245:8795tq=21ewuydg";
|
||||
DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
|
||||
DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
|
||||
when(DeviceConfig.getProperties(anyString(), anyString()))
|
||||
.thenReturn(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* By default game mode is not supported.
|
||||
*/
|
||||
@@ -190,7 +275,6 @@ public class GameManagerServiceTests {
|
||||
public void testGetGameModeInvalidPackageName() {
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
|
||||
try {
|
||||
assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
|
||||
gameManagerService.getGameMode(PACKAGE_NAME_INVALID,
|
||||
@@ -268,4 +352,137 @@ public class GameManagerServiceTests {
|
||||
assertEquals(GameManager.GAME_MODE_PERFORMANCE,
|
||||
gameManagerService.getGameMode(mPackageName, USER_ID_2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Phonesky device config exists, but is only propagating the default value.
|
||||
*/
|
||||
@Test
|
||||
public void testDeviceConfigDefault() {
|
||||
mockDeviceConfigDefault();
|
||||
mockModifyGameModeGranted();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.loadDeviceConfigLocked();
|
||||
|
||||
int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
|
||||
assertEquals(modes.length, 1);
|
||||
assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phonesky device config does not exists.
|
||||
*/
|
||||
@Test
|
||||
public void testDeviceConfigNone() {
|
||||
mockDeviceConfigNone();
|
||||
mockModifyGameModeGranted();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.loadDeviceConfigLocked();
|
||||
|
||||
int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
|
||||
assertEquals(modes.length, 1);
|
||||
assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phonesky device config for performance mode exists and is valid.
|
||||
*/
|
||||
@Test
|
||||
public void testDeviceConfigPerformance() {
|
||||
mockDeviceConfigPerformance();
|
||||
mockModifyGameModeGranted();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.loadDeviceConfigLocked();
|
||||
|
||||
boolean perfModeExists = false;
|
||||
int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
|
||||
for (int mode : modes) {
|
||||
if (mode == GameManager.GAME_MODE_PERFORMANCE) {
|
||||
perfModeExists = true;
|
||||
}
|
||||
}
|
||||
assertEquals(modes.length, 1);
|
||||
assertTrue(perfModeExists);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phonesky device config for battery mode exists and is valid.
|
||||
*/
|
||||
@Test
|
||||
public void testDeviceConfigBattery() {
|
||||
mockDeviceConfigBattery();
|
||||
mockModifyGameModeGranted();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.loadDeviceConfigLocked();
|
||||
|
||||
boolean batteryModeExists = false;
|
||||
int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
|
||||
for (int mode : modes) {
|
||||
if (mode == GameManager.GAME_MODE_BATTERY) {
|
||||
batteryModeExists = true;
|
||||
}
|
||||
}
|
||||
assertEquals(modes.length, 1);
|
||||
assertTrue(batteryModeExists);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phonesky device configs for both battery and performance modes exists and are valid.
|
||||
*/
|
||||
@Test
|
||||
public void testDeviceConfigAll() {
|
||||
mockDeviceConfigAll();
|
||||
mockModifyGameModeGranted();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.loadDeviceConfigLocked();
|
||||
|
||||
boolean batteryModeExists = false;
|
||||
boolean perfModeExists = false;
|
||||
int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
|
||||
for (int mode : modes) {
|
||||
if (mode == GameManager.GAME_MODE_BATTERY) {
|
||||
batteryModeExists = true;
|
||||
} else if (mode == GameManager.GAME_MODE_PERFORMANCE) {
|
||||
perfModeExists = true;
|
||||
}
|
||||
}
|
||||
assertTrue(batteryModeExists);
|
||||
assertTrue(perfModeExists);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phonesky device config contains values that parse correctly but are not valid in game mode.
|
||||
*/
|
||||
@Test
|
||||
public void testDeviceConfigInvalid() {
|
||||
mockDeviceConfigInvalid();
|
||||
mockModifyGameModeGranted();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.loadDeviceConfigLocked();
|
||||
|
||||
int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
|
||||
assertEquals(modes.length, 1);
|
||||
assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phonesky device config is garbage.
|
||||
*/
|
||||
@Test
|
||||
public void testDeviceConfigMalformed() {
|
||||
mockDeviceConfigMalformed();
|
||||
mockModifyGameModeGranted();
|
||||
GameManagerService gameManagerService = new GameManagerService(mMockContext);
|
||||
gameManagerService.onUserStarting(USER_ID_1);
|
||||
gameManagerService.loadDeviceConfigLocked();
|
||||
|
||||
int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
|
||||
assertEquals(modes.length, 1);
|
||||
assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user