1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.app; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertNull; 23 import static org.junit.Assert.assertTrue; 24 25 import android.app.GameManager; 26 import android.content.Context; 27 import android.platform.test.annotations.Presubmit; 28 import android.util.AtomicFile; 29 import android.util.Log; 30 31 import androidx.test.InstrumentationRegistry; 32 import androidx.test.filters.SmallTest; 33 import androidx.test.runner.AndroidJUnit4; 34 35 import com.android.server.app.GameManagerService.GamePackageConfiguration; 36 import com.android.server.app.GameManagerService.GamePackageConfiguration.GameModeConfiguration; 37 38 import org.junit.After; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.io.File; 43 import java.io.FileOutputStream; 44 import java.io.IOException; 45 46 @RunWith(AndroidJUnit4.class) 47 @SmallTest 48 @Presubmit 49 public class GameManagerServiceSettingsTests { 50 51 private static final String TAG = "GameServiceSettingsTests"; 52 private static final String PACKAGE_NAME_1 = "com.android.app1"; 53 private static final String PACKAGE_NAME_2 = "com.android.app2"; 54 private static final String PACKAGE_NAME_3 = "com.android.app3"; 55 private static final String PACKAGE_NAME_4 = "com.android.app4"; 56 57 writeFile(File file, byte[] data)58 private void writeFile(File file, byte[] data) { 59 file.mkdirs(); 60 try { 61 AtomicFile aFile = new AtomicFile(file); 62 FileOutputStream fos = aFile.startWrite(); 63 fos.write(data); 64 aFile.finishWrite(fos); 65 } catch (IOException ioe) { 66 Log.e(TAG, "Cannot write file " + file.getPath()); 67 } 68 } 69 writeGameServiceXml()70 private void writeGameServiceXml() { 71 writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), 72 "system/game-manager-service.xml"), 73 ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" 74 + "<packages>" 75 + "\n" // app1: no package config setting 76 + "\n" // app2: performance mode is selected with override 77 + " <package name=\"com.android.app2\" gameMode=\"2\">\n" 78 + " <gameModeConfig gameMode=\"2\" scaling=\"0.99\" " 79 + "useAngle=\"true\" fps=\"90\" loadingBoost=\"123\"></gameModeConfig>\n" 80 + " <gameModeConfig gameMode=\"3\"></gameModeConfig>\n" 81 + " </package>" 82 + "\n" // app3: only battery mode is selected 83 + " <package name=\"com.android.app3\" gameMode=\"3\">\n" 84 + " </package>" 85 + "\n" // app4: no game mode selected but custom game mode config 86 + " <package name=\"com.android.app4\">\n" 87 + " <gameModeConfig gameMode=\"4\" scaling=\"0.4\" " 88 + "fps=\"30\"></gameModeConfig>\n" 89 + " </package>" 90 + "\n" 91 + "</packages>\n").getBytes()); 92 } 93 deleteSystemFolder()94 private void deleteSystemFolder() { 95 File systemFolder = new File(InstrumentationRegistry.getContext().getFilesDir(), "system"); 96 deleteFolder(systemFolder); 97 } 98 deleteFolder(File folder)99 private static void deleteFolder(File folder) { 100 File[] files = folder.listFiles(); 101 if (files != null) { 102 for (File file : files) { 103 deleteFolder(file); 104 } 105 } 106 folder.delete(); 107 } 108 writeOldFiles()109 private void writeOldFiles() { 110 deleteSystemFolder(); 111 writeGameServiceXml(); 112 } 113 114 @After tearDown()115 public void tearDown() throws Exception { 116 deleteFolder(InstrumentationRegistry.getTargetContext().getFilesDir()); 117 } 118 119 @Test testReadGameServiceSettings()120 public void testReadGameServiceSettings() { 121 writeOldFiles(); 122 final Context context = InstrumentationRegistry.getContext(); 123 GameManagerSettings settings = new GameManagerSettings(context.getFilesDir()); 124 assertTrue(settings.readPersistentDataLocked()); 125 126 // test game modes 127 assertEquals(GameManager.GAME_MODE_STANDARD, settings.getGameModeLocked(PACKAGE_NAME_1)); 128 assertEquals(GameManager.GAME_MODE_PERFORMANCE, settings.getGameModeLocked(PACKAGE_NAME_2)); 129 assertEquals(GameManager.GAME_MODE_BATTERY, settings.getGameModeLocked(PACKAGE_NAME_3)); 130 assertEquals(GameManager.GAME_MODE_STANDARD, settings.getGameModeLocked(PACKAGE_NAME_4)); 131 132 // test game mode configs 133 assertNull(settings.getConfigOverride(PACKAGE_NAME_1)); 134 assertNull(settings.getConfigOverride(PACKAGE_NAME_3)); 135 GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_2); 136 assertNotNull(config); 137 138 assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_STANDARD)); 139 final GameModeConfiguration performanceConfig = config.getGameModeConfiguration( 140 GameManager.GAME_MODE_PERFORMANCE); 141 assertNotNull(performanceConfig); 142 assertEquals(performanceConfig.getScaling(), 0.99, 0.01f); 143 assertEquals(performanceConfig.getLoadingBoostDuration(), 123); 144 assertEquals(performanceConfig.getFpsStr(), "90"); 145 assertTrue(performanceConfig.getUseAngle()); 146 final GameModeConfiguration batteryConfig = config.getGameModeConfiguration( 147 GameManager.GAME_MODE_BATTERY); 148 assertNotNull(batteryConfig); 149 assertEquals(batteryConfig.getScaling(), GameModeConfiguration.DEFAULT_SCALING, 0.01f); 150 assertEquals(batteryConfig.getLoadingBoostDuration(), 151 GameModeConfiguration.DEFAULT_LOADING_BOOST_DURATION); 152 assertEquals(batteryConfig.getFpsStr(), GameModeConfiguration.DEFAULT_FPS); 153 assertFalse(batteryConfig.getUseAngle()); 154 155 config = settings.getConfigOverride(PACKAGE_NAME_4); 156 assertNotNull(config); 157 GameModeConfiguration customConfig = config.getGameModeConfiguration( 158 GameManager.GAME_MODE_CUSTOM); 159 assertNotNull(customConfig); 160 assertEquals(customConfig.getScaling(), 0.4f, 0.1f); 161 assertEquals(customConfig.getFps(), 30); 162 } 163 164 @Test testReadGameServiceSettings_invalidConfigAttributes()165 public void testReadGameServiceSettings_invalidConfigAttributes() { 166 writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), 167 "system/game-manager-service.xml"), 168 ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" 169 + "<packages>\n" 170 + " <package name=\"com.android.app1\" gameMode=\"1\">\n" 171 + " <gameModeConfig gameMode=\"3\" scaling=\"invalid\" " 172 + "useAngle=\"invalid\" fps=\"invalid\" " 173 + "loadingBoost=\"invalid\"></gameModeConfig>\n" 174 + " </package>\n" 175 + "</packages>\n").getBytes()); 176 final Context context = InstrumentationRegistry.getContext(); 177 GameManagerSettings settings = new GameManagerSettings(context.getFilesDir()); 178 assertTrue(settings.readPersistentDataLocked()); 179 180 final GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_1); 181 assertNotNull(config); 182 final GameModeConfiguration batteryConfig = config.getGameModeConfiguration( 183 GameManager.GAME_MODE_BATTERY); 184 assertNotNull(batteryConfig); 185 assertEquals(batteryConfig.getScaling(), GameModeConfiguration.DEFAULT_SCALING, 0.01f); 186 assertEquals(batteryConfig.getLoadingBoostDuration(), 187 GameModeConfiguration.DEFAULT_LOADING_BOOST_DURATION); 188 assertEquals(batteryConfig.getFpsStr(), "invalid"); 189 assertFalse(batteryConfig.getUseAngle()); 190 } 191 192 @Test testReadGameServiceSettings_invalidTags()193 public void testReadGameServiceSettings_invalidTags() { 194 writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), 195 "system/game-manager-service.xml"), 196 ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" 197 + "<packages>" 198 + "\n" // missing package name 199 + " <package gameMode=\"1\">\n" 200 + " </package>" 201 + "\n" // app2 with unknown sub element 202 + " <package name=\"com.android.app2\" gameMode=\"2\">\n" 203 + " <unknown></unknown>" 204 + " <gameModeConfig gameMode=\"3\" fps=\"90\"></gameModeConfig>\n" 205 + " foo bar" 206 + " </package>" 207 + "\n" // unknown package element 208 + " <unknownTag></unknownTag>\n" 209 + " foo bar" 210 + "\n" // app3 after unknown element 211 + " <package name=\"com.android.app3\" gameMode=\"3\">\n" 212 + " </package>\n" 213 + "</packages>\n").getBytes()); 214 final Context context = InstrumentationRegistry.getContext(); 215 GameManagerSettings settings = new GameManagerSettings(context.getFilesDir()); 216 assertTrue(settings.readPersistentDataLocked()); 217 assertEquals(1, settings.getGameModeLocked(PACKAGE_NAME_1)); 218 assertEquals(2, settings.getGameModeLocked(PACKAGE_NAME_2)); 219 assertEquals(3, settings.getGameModeLocked(PACKAGE_NAME_3)); 220 221 final GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_2); 222 assertNotNull(config); 223 final GameModeConfiguration batteryConfig = config.getGameModeConfiguration( 224 GameManager.GAME_MODE_BATTERY); 225 assertNotNull(batteryConfig); 226 assertEquals(batteryConfig.getFpsStr(), "90"); 227 } 228 229 230 @Test testWriteGameServiceSettings()231 public void testWriteGameServiceSettings() { 232 final Context context = InstrumentationRegistry.getContext(); 233 GameManagerSettings settings = new GameManagerSettings(context.getFilesDir()); 234 235 // set package settings and write out to file 236 settings.setGameModeLocked(PACKAGE_NAME_1, GameManager.GAME_MODE_BATTERY); 237 settings.setGameModeLocked(PACKAGE_NAME_2, GameManager.GAME_MODE_PERFORMANCE); 238 settings.setGameModeLocked(PACKAGE_NAME_3, GameManager.GAME_MODE_STANDARD); 239 240 // set config for app2 241 GamePackageConfiguration config = new GamePackageConfiguration(PACKAGE_NAME_2); 242 GameModeConfiguration performanceConfig = config.getOrAddDefaultGameModeConfiguration( 243 GameManager.GAME_MODE_PERFORMANCE); 244 performanceConfig.setLoadingBoostDuration(321); 245 performanceConfig.setScaling(0.66f); 246 performanceConfig.setUseAngle(true); 247 performanceConfig.setFpsStr("60"); 248 GameModeConfiguration batteryConfig = config.getOrAddDefaultGameModeConfiguration( 249 GameManager.GAME_MODE_BATTERY); 250 batteryConfig.setScaling(0.77f); 251 settings.setConfigOverride(PACKAGE_NAME_2, config); 252 253 // set config for app4 254 config = new GamePackageConfiguration(PACKAGE_NAME_4); 255 GameModeConfiguration customConfig = config.getOrAddDefaultGameModeConfiguration( 256 GameManager.GAME_MODE_CUSTOM); 257 customConfig.setScaling(0.4f); 258 customConfig.setFpsStr("30"); 259 settings.setConfigOverride(PACKAGE_NAME_4, config); 260 261 settings.writePersistentDataLocked(); 262 263 // clear the settings in memory 264 settings.removeGame(PACKAGE_NAME_1); 265 settings.removeGame(PACKAGE_NAME_2); 266 settings.removeGame(PACKAGE_NAME_3); 267 settings.removeGame(PACKAGE_NAME_4); 268 269 // read back in and verify 270 assertTrue(settings.readPersistentDataLocked()); 271 assertEquals(3, settings.getGameModeLocked(PACKAGE_NAME_1)); 272 assertEquals(2, settings.getGameModeLocked(PACKAGE_NAME_2)); 273 assertEquals(1, settings.getGameModeLocked(PACKAGE_NAME_3)); 274 assertEquals(1, settings.getGameModeLocked(PACKAGE_NAME_4)); 275 276 config = settings.getConfigOverride(PACKAGE_NAME_1); 277 assertNull(config); 278 config = settings.getConfigOverride(PACKAGE_NAME_2); 279 assertNotNull(config); 280 batteryConfig = config.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY); 281 assertNotNull(batteryConfig); 282 assertEquals(batteryConfig.getScaling(), 0.77f, 0.01f); 283 assertEquals(batteryConfig.getLoadingBoostDuration(), 284 GameModeConfiguration.DEFAULT_LOADING_BOOST_DURATION); 285 assertEquals(batteryConfig.getFpsStr(), GameModeConfiguration.DEFAULT_FPS); 286 assertFalse(batteryConfig.getUseAngle()); 287 288 performanceConfig = config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE); 289 assertNotNull(performanceConfig); 290 assertEquals(performanceConfig.getScaling(), 0.66f, 0.01f); 291 assertEquals(performanceConfig.getLoadingBoostDuration(), 321); 292 assertEquals(performanceConfig.getFpsStr(), "60"); 293 assertTrue(performanceConfig.getUseAngle()); 294 295 config = settings.getConfigOverride(PACKAGE_NAME_4); 296 assertNotNull(config); 297 customConfig = config.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM); 298 assertNotNull(customConfig); 299 assertEquals(customConfig.getScaling(), 0.4f, 0.1f); 300 assertEquals(customConfig.getFps(), 30); 301 assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE)); 302 assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY)); 303 } 304 } 305