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 com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
20 import static com.android.server.app.GameManagerService.CANCEL_GAME_LOADING_MODE;
21 import static com.android.server.app.GameManagerService.LOADING_BOOST_MAX_DURATION;
22 import static com.android.server.app.GameManagerService.SET_GAME_STATE;
23 import static com.android.server.app.GameManagerService.WRITE_DELAY_MILLIS;
24 import static com.android.server.app.GameManagerService.WRITE_GAME_MODE_INTERVENTION_LIST_FILE;
25 import static com.android.server.app.GameManagerService.WRITE_SETTINGS;
26 
27 import static org.junit.Assert.assertArrayEquals;
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertFalse;
30 import static org.junit.Assert.assertNotNull;
31 import static org.junit.Assert.assertNull;
32 import static org.junit.Assert.assertThrows;
33 import static org.junit.Assert.assertTrue;
34 import static org.junit.Assert.fail;
35 import static org.mockito.ArgumentMatchers.anyBoolean;
36 import static org.mockito.ArgumentMatchers.anyInt;
37 import static org.mockito.ArgumentMatchers.anyString;
38 import static org.mockito.Mockito.any;
39 import static org.mockito.Mockito.doAnswer;
40 import static org.mockito.Mockito.eq;
41 import static org.mockito.Mockito.never;
42 import static org.mockito.Mockito.reset;
43 import static org.mockito.Mockito.times;
44 import static org.mockito.Mockito.verify;
45 import static org.mockito.Mockito.when;
46 
47 import android.Manifest;
48 import android.annotation.Nullable;
49 import android.app.ActivityManager;
50 import android.app.GameManager;
51 import android.app.GameModeConfiguration;
52 import android.app.GameModeInfo;
53 import android.app.GameState;
54 import android.app.IGameModeListener;
55 import android.app.IGameStateListener;
56 import android.content.BroadcastReceiver;
57 import android.content.Context;
58 import android.content.ContextWrapper;
59 import android.content.Intent;
60 import android.content.IntentFilter;
61 import android.content.pm.ApplicationInfo;
62 import android.content.pm.PackageInfo;
63 import android.content.pm.PackageManager;
64 import android.content.pm.UserInfo;
65 import android.content.res.AssetManager;
66 import android.content.res.Resources;
67 import android.content.res.XmlResourceParser;
68 import android.hardware.power.Mode;
69 import android.os.Binder;
70 import android.os.Bundle;
71 import android.os.IBinder;
72 import android.os.PowerManagerInternal;
73 import android.os.RemoteException;
74 import android.os.UserManager;
75 import android.os.test.TestLooper;
76 import android.platform.test.annotations.Presubmit;
77 import android.provider.DeviceConfig;
78 
79 import androidx.test.InstrumentationRegistry;
80 import androidx.test.filters.SmallTest;
81 import androidx.test.runner.AndroidJUnit4;
82 
83 import com.android.server.LocalServices;
84 import com.android.server.SystemService;
85 
86 import org.junit.After;
87 import org.junit.Before;
88 import org.junit.Test;
89 import org.junit.runner.RunWith;
90 import org.mockito.ArgumentCaptor;
91 import org.mockito.ArgumentMatchers;
92 import org.mockito.Captor;
93 import org.mockito.Mock;
94 import org.mockito.Mockito;
95 import org.mockito.MockitoSession;
96 import org.mockito.quality.Strictness;
97 
98 import java.io.File;
99 import java.nio.file.Files;
100 import java.util.ArrayList;
101 import java.util.Arrays;
102 import java.util.HashMap;
103 import java.util.List;
104 import java.util.function.Supplier;
105 
106 @RunWith(AndroidJUnit4.class)
107 @SmallTest
108 @Presubmit
109 public class GameManagerServiceTests {
110     @Mock MockContext mMockContext;
111     private static final String TAG = "GameManagerServiceTests";
112     private static final String PACKAGE_NAME_INVALID = "com.android.app";
113     private static final int USER_ID_1 = 1001;
114     private static final int USER_ID_2 = 1002;
115     // to pass the valid package check in some of the server methods
116     private static final int DEFAULT_PACKAGE_UID = Binder.getCallingUid();
117 
118     private MockitoSession mMockingSession;
119     private String mPackageName;
120     private TestLooper mTestLooper;
121     @Mock
122     private PackageManager mMockPackageManager;
123     @Mock
124     private PowerManagerInternal mMockPowerManager;
125     @Mock
126     private UserManager mMockUserManager;
127     private BroadcastReceiver mShutDownActionReceiver;
128 
129     @Captor
130     ArgumentCaptor<IBinder.DeathRecipient> mDeathRecipientCaptor;
131 
132     // Stolen from ConnectivityServiceTest.MockContext
133     class MockContext extends ContextWrapper {
134         private static final String TAG = "MockContext";
135 
136         // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
137         private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
138 
MockContext(Context base)139         MockContext(Context base) {
140             super(base);
141         }
142 
143         /**
144          * Mock checks for the specified permission, and have them behave as per {@code granted}.
145          *
146          * <p>Passing null reverts to default behavior, which does a real permission check on the
147          * test package.
148          *
149          * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or
150          *                {@link PackageManager#PERMISSION_DENIED}.
151          */
setPermission(String permission, Integer granted)152         public void setPermission(String permission, Integer granted) {
153             mMockedPermissions.put(permission, granted);
154         }
155 
checkMockedPermission(String permission, Supplier<Integer> ifAbsent)156         private int checkMockedPermission(String permission, Supplier<Integer> ifAbsent) {
157             final Integer granted = mMockedPermissions.get(permission);
158             return granted != null ? granted : ifAbsent.get();
159         }
160 
161         @Override
checkPermission(String permission, int pid, int uid)162         public int checkPermission(String permission, int pid, int uid) {
163             return checkMockedPermission(
164                     permission, () -> super.checkPermission(permission, pid, uid));
165         }
166 
167         @Override
checkCallingOrSelfPermission(String permission)168         public int checkCallingOrSelfPermission(String permission) {
169             return checkMockedPermission(
170                     permission, () -> super.checkCallingOrSelfPermission(permission));
171         }
172 
173         @Override
enforceCallingOrSelfPermission(String permission, String message)174         public void enforceCallingOrSelfPermission(String permission, String message) {
175             final Integer granted = mMockedPermissions.get(permission);
176             if (granted == null) {
177                 super.enforceCallingOrSelfPermission(permission, message);
178                 return;
179             }
180 
181             if (!granted.equals(PackageManager.PERMISSION_GRANTED)) {
182                 throw new SecurityException("[Test] permission denied: " + permission);
183             }
184         }
185 
186         @Override
getPackageManager()187         public PackageManager getPackageManager() {
188             return mMockPackageManager;
189         }
190 
191         @Override
getSystemService(String name)192         public Object getSystemService(String name) {
193             switch (name) {
194                 case Context.USER_SERVICE:
195                     return mMockUserManager;
196             }
197             throw new UnsupportedOperationException("Couldn't find system service: " + name);
198         }
199 
200         @Override
registerReceiver(@ullable BroadcastReceiver receiver, IntentFilter filter)201         public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
202             mShutDownActionReceiver = receiver;
203             return null;
204         }
205     }
206 
207     @Before
setUp()208     public void setUp() throws Exception {
209         mTestLooper = new TestLooper();
210         mMockingSession = mockitoSession()
211                 .initMocks(this)
212                 .mockStatic(DeviceConfig.class)
213                 .strictness(Strictness.WARN)
214                 .startMocking();
215         mMockContext = new MockContext(InstrumentationRegistry.getContext());
216         mPackageName = mMockContext.getPackageName();
217         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_GAME);
218         final Resources resources =
219                 InstrumentationRegistry.getInstrumentation().getContext().getResources();
220         when(mMockPackageManager.getResourcesForApplication(anyString()))
221                 .thenReturn(resources);
222         when(mMockPackageManager.getPackageUidAsUser(mPackageName, USER_ID_1)).thenReturn(
223                 DEFAULT_PACKAGE_UID);
224         LocalServices.addService(PowerManagerInternal.class, mMockPowerManager);
225     }
226 
mockAppCategory(String packageName, @ApplicationInfo.Category int category)227     private void mockAppCategory(String packageName, @ApplicationInfo.Category int category)
228             throws Exception {
229         reset(mMockPackageManager);
230         final ApplicationInfo gameApplicationInfo = new ApplicationInfo();
231         gameApplicationInfo.category = category;
232         gameApplicationInfo.packageName = packageName;
233         final PackageInfo pi = new PackageInfo();
234         pi.packageName = packageName;
235         pi.applicationInfo = gameApplicationInfo;
236         final List<PackageInfo> packages = new ArrayList<>();
237         packages.add(pi);
238         when(mMockPackageManager.getInstalledPackagesAsUser(anyInt(), anyInt()))
239                 .thenReturn(packages);
240         when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
241                 .thenReturn(gameApplicationInfo);
242     }
243 
244     @After
tearDown()245     public void tearDown() throws Exception {
246         LocalServices.removeServiceForTest(PowerManagerInternal.class);
247         if (mMockingSession != null) {
248             mMockingSession.finishMocking();
249         }
250         deleteFolder(InstrumentationRegistry.getTargetContext().getFilesDir());
251     }
252 
startUser(GameManagerService gameManagerService, int userId)253     private void startUser(GameManagerService gameManagerService, int userId) {
254         UserInfo userInfo = new UserInfo(userId, "name", 0);
255         gameManagerService.onUserStarting(new SystemService.TargetUser(userInfo),
256                 InstrumentationRegistry.getContext().getFilesDir());
257         mTestLooper.dispatchAll();
258     }
259 
switchUser(GameManagerService gameManagerService, int from, int to)260     private void switchUser(GameManagerService gameManagerService, int from, int to) {
261         UserInfo userInfoFrom = new UserInfo(from, "name", 0);
262         UserInfo userInfoTo = new UserInfo(to, "name", 0);
263         gameManagerService.onUserSwitching(/* from */ new SystemService.TargetUser(userInfoFrom),
264                 /* to */ new SystemService.TargetUser(userInfoTo));
265         mTestLooper.dispatchAll();
266     }
267 
mockQueryAllPackageGranted()268     private void mockQueryAllPackageGranted() {
269         mMockContext.setPermission(Manifest.permission.QUERY_ALL_PACKAGES,
270                 PackageManager.PERMISSION_GRANTED);
271     }
272 
mockQueryAllPackageDenied()273     private void mockQueryAllPackageDenied() {
274         mMockContext.setPermission(Manifest.permission.QUERY_ALL_PACKAGES,
275                 PackageManager.PERMISSION_DENIED);
276     }
277 
mockManageUsersGranted()278     private void mockManageUsersGranted() {
279         mMockContext.setPermission(Manifest.permission.MANAGE_USERS,
280                 PackageManager.PERMISSION_GRANTED);
281     }
282 
mockModifyGameModeGranted()283     private void mockModifyGameModeGranted() {
284         mMockContext.setPermission(Manifest.permission.MANAGE_GAME_MODE,
285                 PackageManager.PERMISSION_GRANTED);
286     }
287 
mockModifyGameModeDenied()288     private void mockModifyGameModeDenied() {
289         mMockContext.setPermission(Manifest.permission.MANAGE_GAME_MODE,
290                 PackageManager.PERMISSION_DENIED);
291     }
292 
mockDeviceConfigDefault()293     private void mockDeviceConfigDefault() {
294         when(DeviceConfig.getProperty(anyString(), anyString()))
295                 .thenReturn("");
296     }
297 
mockDeviceConfigNone()298     private void mockDeviceConfigNone() {
299         when(DeviceConfig.getProperty(anyString(), anyString()))
300                 .thenReturn(null);
301     }
302 
mockDeviceConfigPerformance()303     private void mockDeviceConfigPerformance() {
304         String configString = "mode=2,downscaleFactor=0.5,useAngle=false,fps=90";
305         when(DeviceConfig.getProperty(anyString(), anyString()))
306                 .thenReturn(configString);
307     }
308 
309     // ANGLE will be disabled for most apps, so treat enabling ANGLE as a special case.
mockDeviceConfigPerformanceEnableAngle()310     private void mockDeviceConfigPerformanceEnableAngle() {
311         String configString = "mode=2,downscaleFactor=0.5,useAngle=true";
312         when(DeviceConfig.getProperty(anyString(), anyString()))
313                 .thenReturn(configString);
314     }
315 
316     // Loading boost will be disabled for most apps, so treat enabling loading boost as a special
317     // case.
mockDeviceConfigPerformanceEnableLoadingBoost()318     private void mockDeviceConfigPerformanceEnableLoadingBoost() {
319         String configString = "mode=2,downscaleFactor=0.5,loadingBoost=0";
320         when(DeviceConfig.getProperty(anyString(), anyString()))
321                 .thenReturn(configString);
322     }
323 
mockDeviceConfigBattery()324     private void mockDeviceConfigBattery() {
325         String configString = "mode=3,downscaleFactor=0.7,fps=30";
326         when(DeviceConfig.getProperty(anyString(), anyString()))
327                 .thenReturn(configString);
328     }
329 
mockDeviceConfigAll()330     private void mockDeviceConfigAll() {
331         String configString = "mode=3,downscaleFactor=0.7,fps=30:mode=2,downscaleFactor=0.5,fps=90";
332         when(DeviceConfig.getProperty(anyString(), anyString()))
333                 .thenReturn(configString);
334     }
335 
mockDeviceConfigInvalid()336     private void mockDeviceConfigInvalid() {
337         String configString = "";
338         when(DeviceConfig.getProperty(anyString(), anyString()))
339                 .thenReturn(configString);
340     }
341 
mockDeviceConfigMalformed()342     private void mockDeviceConfigMalformed() {
343         String configString = "adsljckv=nin3rn9hn1231245:8795tq=21ewuydg";
344         when(DeviceConfig.getProperty(anyString(), anyString()))
345                 .thenReturn(configString);
346     }
347 
mockGameModeOptInAll()348     private void mockGameModeOptInAll() throws Exception {
349         final ApplicationInfo applicationInfo = mMockPackageManager.getApplicationInfoAsUser(
350                 mPackageName, PackageManager.GET_META_DATA, USER_ID_1);
351         Bundle metaDataBundle = new Bundle();
352         metaDataBundle.putBoolean(
353                 GameManagerService.GamePackageConfiguration.METADATA_PERFORMANCE_MODE_ENABLE, true);
354         metaDataBundle.putBoolean(
355                 GameManagerService.GamePackageConfiguration.METADATA_BATTERY_MODE_ENABLE, true);
356         applicationInfo.metaData = metaDataBundle;
357         when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
358                 .thenReturn(applicationInfo);
359     }
360 
mockGameModeOptInPerformance()361     private void mockGameModeOptInPerformance() throws Exception {
362         final ApplicationInfo applicationInfo = mMockPackageManager.getApplicationInfoAsUser(
363                 mPackageName, PackageManager.GET_META_DATA, USER_ID_1);
364         Bundle metaDataBundle = new Bundle();
365         metaDataBundle.putBoolean(
366                 GameManagerService.GamePackageConfiguration.METADATA_PERFORMANCE_MODE_ENABLE, true);
367         applicationInfo.metaData = metaDataBundle;
368         when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
369                 .thenReturn(applicationInfo);
370     }
371 
mockGameModeOptInBattery()372     private void mockGameModeOptInBattery() throws Exception {
373         final ApplicationInfo applicationInfo = mMockPackageManager.getApplicationInfoAsUser(
374                 mPackageName, PackageManager.GET_META_DATA, USER_ID_1);
375         Bundle metaDataBundle = new Bundle();
376         metaDataBundle.putBoolean(
377                 GameManagerService.GamePackageConfiguration.METADATA_BATTERY_MODE_ENABLE, true);
378         applicationInfo.metaData = metaDataBundle;
379         when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
380                 .thenReturn(applicationInfo);
381     }
382 
mockInterventionAllowDownscaleTrue()383     private void mockInterventionAllowDownscaleTrue() throws Exception {
384         final ApplicationInfo applicationInfo = mMockPackageManager.getApplicationInfoAsUser(
385                 mPackageName, PackageManager.GET_META_DATA, USER_ID_1);
386         Bundle metaDataBundle = new Bundle();
387         metaDataBundle.putBoolean(
388                 GameManagerService.GamePackageConfiguration.METADATA_WM_ALLOW_DOWNSCALE, true);
389         applicationInfo.metaData = metaDataBundle;
390         when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
391                 .thenReturn(applicationInfo);
392     }
393 
mockInterventionAllowDownscaleFalse()394     private void mockInterventionAllowDownscaleFalse() throws Exception {
395         final ApplicationInfo applicationInfo = mMockPackageManager.getApplicationInfoAsUser(
396                 mPackageName, PackageManager.GET_META_DATA, USER_ID_1);
397         Bundle metaDataBundle = new Bundle();
398         metaDataBundle.putBoolean(
399                 GameManagerService.GamePackageConfiguration.METADATA_WM_ALLOW_DOWNSCALE, false);
400         applicationInfo.metaData = metaDataBundle;
401         when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
402                 .thenReturn(applicationInfo);
403     }
404 
mockInterventionAllowAngleTrue()405     private void mockInterventionAllowAngleTrue() throws Exception {
406         final ApplicationInfo applicationInfo = mMockPackageManager.getApplicationInfoAsUser(
407                 mPackageName, PackageManager.GET_META_DATA, USER_ID_1);
408         Bundle metaDataBundle = new Bundle();
409         metaDataBundle.putBoolean(
410                 GameManagerService.GamePackageConfiguration.METADATA_ANGLE_ALLOW_ANGLE, true);
411         when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
412                 .thenReturn(applicationInfo);
413     }
414 
mockInterventionAllowAngleFalse()415     private void mockInterventionAllowAngleFalse() throws Exception {
416         final ApplicationInfo applicationInfo = mMockPackageManager.getApplicationInfoAsUser(
417                 mPackageName, PackageManager.GET_META_DATA, USER_ID_1);
418         Bundle metaDataBundle = new Bundle();
419         metaDataBundle.putBoolean(
420                 GameManagerService.GamePackageConfiguration.METADATA_ANGLE_ALLOW_ANGLE, false);
421         applicationInfo.metaData = metaDataBundle;
422         when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
423                 .thenReturn(applicationInfo);
424     }
425 
mockInterventionsEnabledBatteryOptInFromXml()426     private void mockInterventionsEnabledBatteryOptInFromXml() throws Exception {
427         seedGameManagerServiceMetaDataFromFile(mPackageName, 123, "res/xml/"
428                 + "game_manager_service_metadata_config_interventions_enabled_battery_opt_in.xml");
429     }
430 
mockInterventionsEnabledPerformanceOptInFromXml()431     private void mockInterventionsEnabledPerformanceOptInFromXml() throws Exception {
432         seedGameManagerServiceMetaDataFromFile(mPackageName, 123, "res/xml/"
433                 + "game_manager_service_metadata_config_interventions_enabled_performance_opt_in"
434                 + ".xml");
435     }
436 
mockInterventionsEnabledNoOptInFromXml()437     private void mockInterventionsEnabledNoOptInFromXml() throws Exception {
438         seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
439                 "res/xml/game_manager_service_metadata_config_interventions_enabled_no_opt_in.xml");
440     }
441 
mockInterventionsEnabledAllOptInFromXml()442     private void mockInterventionsEnabledAllOptInFromXml() throws Exception {
443         seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
444                 "res/xml/game_manager_service_metadata_config_interventions_enabled_all_opt_in"
445                         + ".xml");
446     }
447 
mockInterventionsDisabledNoOptInFromXml()448     private void mockInterventionsDisabledNoOptInFromXml() throws Exception {
449         seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
450                 "res/xml/game_manager_service_metadata_config_interventions_disabled_no_opt_in"
451                         + ".xml");
452     }
453 
mockInterventionsDisabledAllOptInFromXml()454     private void mockInterventionsDisabledAllOptInFromXml() throws Exception {
455         seedGameManagerServiceMetaDataFromFile(mPackageName, 123,
456                 "res/xml/game_manager_service_metadata_config_interventions_disabled_all_opt_in"
457                         + ".xml");
458     }
459 
460 
seedGameManagerServiceMetaDataFromFile(String packageName, int resId, String fileName)461     private void seedGameManagerServiceMetaDataFromFile(String packageName, int resId,
462             String fileName)
463             throws Exception {
464         final ApplicationInfo applicationInfo = mMockPackageManager.getApplicationInfoAsUser(
465                 mPackageName, PackageManager.GET_META_DATA, USER_ID_1);
466         Bundle metaDataBundle = new Bundle();
467         metaDataBundle.putInt(
468                 GameManagerService.GamePackageConfiguration.METADATA_GAME_MODE_CONFIG, resId);
469         applicationInfo.metaData = metaDataBundle;
470         when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
471                 .thenReturn(applicationInfo);
472         AssetManager assetManager =
473                 InstrumentationRegistry.getInstrumentation().getContext().getAssets();
474         XmlResourceParser xmlResourceParser =
475                 assetManager.openXmlResourceParser(fileName);
476         when(mMockPackageManager.getXml(eq(packageName), eq(resId), any()))
477                 .thenReturn(xmlResourceParser);
478     }
479 
480     /**
481      * By default game mode is set to STANDARD
482      */
483     @Test
testGetGameMode_defaultValue()484     public void testGetGameMode_defaultValue() {
485         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
486         mockModifyGameModeGranted();
487         assertEquals(GameManager.GAME_MODE_STANDARD,
488                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
489     }
490 
491     @Test
testGetGameMode_nonGame()492     public void testGetGameMode_nonGame() throws Exception {
493         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_AUDIO);
494         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
495         mockModifyGameModeGranted();
496         assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
497                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
498     }
499 
500     /**
501      * Test the default behaviour for a nonexistent user.
502      */
503     @Test
testDefaultValueForNonexistentUser()504     public void testDefaultValueForNonexistentUser() {
505         GameManagerService gameManagerService =
506                 new GameManagerService(mMockContext, mTestLooper.getLooper());
507 
508         startUser(gameManagerService, USER_ID_1);
509         mockModifyGameModeGranted();
510 
511         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_2);
512         assertEquals(GameManager.GAME_MODE_STANDARD,
513                 gameManagerService.getGameMode(mPackageName, USER_ID_2));
514     }
515 
516     /**
517      * Test getter and setter of game modes.
518      */
519     @Test
testGameMode()520     public void testGameMode() {
521         GameManagerService gameManagerService =
522                 new GameManagerService(mMockContext, mTestLooper.getLooper());
523 
524 
525         startUser(gameManagerService, USER_ID_1);
526         gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
527         mockModifyGameModeGranted();
528         assertEquals(GameManager.GAME_MODE_STANDARD,
529                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
530         // We need to make sure the mode is supported before setting it.
531         mockDeviceConfigAll();
532         gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
533         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
534         assertEquals(GameManager.GAME_MODE_STANDARD,
535                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
536         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
537                 USER_ID_1);
538         assertEquals(GameManager.GAME_MODE_PERFORMANCE,
539                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
540     }
541 
542     /**
543      * Test invalid package name is queried
544      */
545     @Test
testGetGameModeInvalidPackageName()546     public void testGetGameModeInvalidPackageName() {
547         GameManagerService gameManagerService =
548                 new GameManagerService(mMockContext, mTestLooper.getLooper());
549 
550         startUser(gameManagerService, USER_ID_1);
551         try {
552             when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
553                     .thenThrow(new PackageManager.NameNotFoundException());
554             assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
555                     gameManagerService.getGameMode(PACKAGE_NAME_INVALID,
556                             USER_ID_1));
557         } catch (PackageManager.NameNotFoundException e) {
558             // should never get here as isPackageGame() catches this exception
559             // fail this test if we ever get here
560             fail("Unexpected NameNotFoundException caught.");
561         }
562     }
563 
564     /**
565      * Test permission.MANAGE_GAME_MODE is checked
566      */
567     @Test
testSetGameModePermissionDenied()568     public void testSetGameModePermissionDenied() {
569         mockModifyGameModeGranted();
570         mockDeviceConfigAll();
571         GameManagerService gameManagerService =
572                 new GameManagerService(mMockContext, mTestLooper.getLooper());
573         startUser(gameManagerService, USER_ID_1);
574 
575         // Update the game mode so we can read back something valid.
576         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
577         assertEquals(GameManager.GAME_MODE_STANDARD,
578                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
579 
580         // Deny permission.MANAGE_GAME_MODE and verify the game mode is not updated.
581         mockModifyGameModeDenied();
582         try {
583             gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
584                     USER_ID_1);
585 
586             fail("GameManagerService failed to generate SecurityException when "
587                     + "permission.MANAGE_GAME_MODE is denied.");
588         } catch (SecurityException ignored) {
589         }
590 
591         // The test should throw an exception, so the test is passing if we get here.
592         mockModifyGameModeGranted();
593         // Verify that the Game Mode value wasn't updated.
594         assertEquals(GameManager.GAME_MODE_STANDARD,
595                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
596     }
597 
598     /**
599      * Test game modes are user-specific.
600      */
601     @Test
testGameModeMultipleUsers()602     public void testGameModeMultipleUsers() {
603         mockModifyGameModeGranted();
604         mockDeviceConfigAll();
605         GameManagerService gameManagerService =
606                 new GameManagerService(mMockContext, mTestLooper.getLooper());
607 
608         startUser(gameManagerService, USER_ID_1);
609         startUser(gameManagerService, USER_ID_2);
610         gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
611         gameManagerService.updateConfigsForUser(USER_ID_2, true, mPackageName);
612 
613         // Set User 1 to Standard
614         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
615         assertEquals(GameManager.GAME_MODE_STANDARD,
616                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
617 
618         // Set User 2 to Performance and verify User 1 is still Standard
619         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
620                 USER_ID_2);
621         assertEquals(GameManager.GAME_MODE_PERFORMANCE,
622                 gameManagerService.getGameMode(mPackageName, USER_ID_2));
623         assertEquals(GameManager.GAME_MODE_STANDARD,
624                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
625 
626         // Set User 1 to Battery and verify User 2 is still Performance
627         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY,
628                 USER_ID_1);
629         assertEquals(GameManager.GAME_MODE_BATTERY,
630                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
631         assertEquals(GameManager.GAME_MODE_PERFORMANCE,
632                 gameManagerService.getGameMode(mPackageName, USER_ID_2));
633     }
634 
createServiceAndStartUser(int userId)635     private GameManagerService createServiceAndStartUser(int userId) {
636         GameManagerService gameManagerService = new GameManagerService(mMockContext,
637                 mTestLooper.getLooper());
638         startUser(gameManagerService, userId);
639         return gameManagerService;
640     }
641 
checkReportedAvailableGameModes(GameManagerService gameManagerService, int... requiredAvailableModes)642     private void checkReportedAvailableGameModes(GameManagerService gameManagerService,
643             int... requiredAvailableModes) {
644         Arrays.sort(requiredAvailableModes);
645         // check getAvailableGameModes
646         int[] reportedAvailableModes = gameManagerService.getAvailableGameModes(mPackageName,
647                 USER_ID_1);
648         Arrays.sort(reportedAvailableModes);
649         assertArrayEquals(requiredAvailableModes, reportedAvailableModes);
650 
651         // check GetModeInfo.getAvailableGameModes
652         GameModeInfo info = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
653         if (requiredAvailableModes.length == 0) {
654             assertNull(info);
655         } else {
656             assertNotNull(info);
657             reportedAvailableModes = info.getAvailableGameModes();
658             Arrays.sort(reportedAvailableModes);
659             assertArrayEquals(requiredAvailableModes, reportedAvailableModes);
660         }
661     }
662 
checkReportedOverriddenGameModes(GameManagerService gameManagerService, int... requiredOverriddenModes)663     private void checkReportedOverriddenGameModes(GameManagerService gameManagerService,
664             int... requiredOverriddenModes) {
665         Arrays.sort(requiredOverriddenModes);
666         // check GetModeInfo.getOverriddenGameModes
667         GameModeInfo info = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
668         assertNotNull(info);
669         int[] overriddenModes = info.getOverriddenGameModes();
670         Arrays.sort(overriddenModes);
671         assertArrayEquals(requiredOverriddenModes, overriddenModes);
672     }
673 
checkDownscaling(GameManagerService gameManagerService, int gameMode, float scaling)674     private void checkDownscaling(GameManagerService gameManagerService,
675             int gameMode, float scaling) {
676         GameManagerService.GamePackageConfiguration config =
677                 gameManagerService.getConfig(mPackageName, USER_ID_1);
678         assertEquals(scaling, config.getGameModeConfiguration(gameMode).getScaling(), 0.01f);
679     }
680 
checkAngleEnabled(GameManagerService gameManagerService, int gameMode, boolean angleEnabled)681     private void checkAngleEnabled(GameManagerService gameManagerService, int gameMode,
682             boolean angleEnabled) {
683         gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
684 
685         // Validate GamePackageConfiguration returns the correct value.
686         GameManagerService.GamePackageConfiguration config =
687                 gameManagerService.getConfig(mPackageName, USER_ID_1);
688         assertEquals(config.getGameModeConfiguration(gameMode).getUseAngle(), angleEnabled);
689 
690         // Validate GameManagerService.isAngleEnabled() returns the correct value.
691         assertEquals(gameManagerService.isAngleEnabled(mPackageName, USER_ID_1), angleEnabled);
692     }
693 
checkLoadingBoost(GameManagerService gameManagerService, int gameMode, int loadingBoost)694     private void checkLoadingBoost(GameManagerService gameManagerService, int gameMode,
695             int loadingBoost) {
696         // Validate GamePackageConfiguration returns the correct value.
697         GameManagerService.GamePackageConfiguration config =
698                 gameManagerService.getConfig(mPackageName, USER_ID_1);
699         assertEquals(
700                 loadingBoost, config.getGameModeConfiguration(gameMode).getLoadingBoostDuration());
701 
702         // Validate GameManagerService.getLoadingBoostDuration() returns the correct value.
703         assertEquals(
704                 loadingBoost, gameManagerService.getLoadingBoostDuration(mPackageName, USER_ID_1));
705     }
706 
checkFps(GameManagerService gameManagerService, int gameMode, int fps)707     private void checkFps(GameManagerService gameManagerService, int gameMode, int fps) {
708         GameManagerService.GamePackageConfiguration config =
709                 gameManagerService.getConfig(mPackageName, USER_ID_1);
710         assertEquals(fps, config.getGameModeConfiguration(gameMode).getFps());
711     }
712 
checkOverridden(GameManagerService gameManagerService, int gameMode)713     private boolean checkOverridden(GameManagerService gameManagerService, int gameMode) {
714         GameManagerService.GamePackageConfiguration config =
715                 gameManagerService.getConfig(mPackageName, USER_ID_1);
716         return config.willGamePerformOptimizations(gameMode);
717     }
718 
719     /**
720      * Phenotype device config exists, but is only propagating the default value.
721      */
722     @Test
testDeviceConfigDefault()723     public void testDeviceConfigDefault() {
724         mockDeviceConfigDefault();
725         mockModifyGameModeGranted();
726         checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
727                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
728     }
729 
730     /**
731      * Phenotype device config does not exists.
732      */
733     @Test
testDeviceConfigNone()734     public void testDeviceConfigNone() {
735         mockDeviceConfigNone();
736         mockModifyGameModeGranted();
737         checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
738                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
739     }
740 
741     /**
742      * Phenotype device config contains values that parse correctly but are not valid in game mode.
743      */
744     @Test
testDeviceConfigInvalid()745     public void testDeviceConfigInvalid() {
746         mockDeviceConfigInvalid();
747         mockModifyGameModeGranted();
748         checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
749                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
750     }
751 
752     /**
753      * Phenotype device config is garbage.
754      */
755     @Test
testDeviceConfigMalformed()756     public void testDeviceConfigMalformed() {
757         mockDeviceConfigMalformed();
758         mockModifyGameModeGranted();
759         checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
760                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
761     }
762 
763     @Test
testDeviceConfig_nonGame()764     public void testDeviceConfig_nonGame() throws Exception {
765         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_AUDIO);
766         mockDeviceConfigAll();
767         mockModifyGameModeGranted();
768         checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1));
769     }
770 
771     /**
772      * Override device config for performance mode exists and is valid.
773      */
774     @Test
testSetDeviceConfigOverridePerformance()775     public void testSetDeviceConfigOverridePerformance() {
776         mockDeviceConfigPerformance();
777         mockModifyGameModeGranted();
778 
779         GameManagerService gameManagerService = new GameManagerService(
780                 mMockContext, mTestLooper.getLooper());
781         startUser(gameManagerService, USER_ID_1);
782         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
783                 GameManager.GAME_MODE_PERFORMANCE, "120", "0.3");
784 
785         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
786                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
787         checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.3f);
788         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 120);
789     }
790 
791     /**
792      * Override device config for battery mode exists and is valid.
793      */
794     @Test
testSetDeviceConfigOverrideBattery()795     public void testSetDeviceConfigOverrideBattery() {
796         mockDeviceConfigBattery();
797         mockModifyGameModeGranted();
798 
799         GameManagerService gameManagerService = new GameManagerService(
800                 mMockContext, mTestLooper.getLooper());
801         startUser(gameManagerService, USER_ID_1);
802         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
803                 GameManager.GAME_MODE_BATTERY, "60", "0.5");
804 
805         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_BATTERY,
806                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
807         checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.5f);
808         checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 60);
809     }
810 
811     /**
812      * Override device configs for both battery and performance modes exists and are valid.
813      */
814     @Test
testSetDeviceConfigOverrideAll()815     public void testSetDeviceConfigOverrideAll() {
816         mockDeviceConfigAll();
817         mockModifyGameModeGranted();
818 
819         GameManagerService gameManagerService = new GameManagerService(
820                 mMockContext, mTestLooper.getLooper());
821         startUser(gameManagerService, USER_ID_1);
822         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
823                 GameManager.GAME_MODE_PERFORMANCE, "120", "0.3");
824         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
825                 GameManager.GAME_MODE_BATTERY, "60", "0.5");
826 
827         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
828                 GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
829                 GameManager.GAME_MODE_CUSTOM);
830         checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.3f);
831         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 120);
832         checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.5f);
833         checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 60);
834     }
835 
836     @Test
testSetBatteryModeConfigOverride_thenUpdateAllDeviceConfig()837     public void testSetBatteryModeConfigOverride_thenUpdateAllDeviceConfig() throws Exception {
838         mockModifyGameModeGranted();
839         String configStringBefore =
840                 "mode=2,downscaleFactor=1.0,fps=90:mode=3,downscaleFactor=0.1,fps=30";
841         when(DeviceConfig.getProperty(anyString(), anyString()))
842                 .thenReturn(configStringBefore);
843         mockInterventionsEnabledNoOptInFromXml();
844         GameManagerService gameManagerService = new GameManagerService(mMockContext,
845                 mTestLooper.getLooper());
846         startUser(gameManagerService, USER_ID_1);
847 
848         checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 1.0f);
849         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
850         checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.1f);
851         checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 30);
852 
853         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1, 3, "40",
854                 "0.2");
855 
856         checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 40);
857         checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.2f);
858 
859         String configStringAfter =
860                 "mode=2,downscaleFactor=0.9,fps=60:mode=3,downscaleFactor=0.3,fps=50";
861         when(DeviceConfig.getProperty(anyString(), anyString()))
862                 .thenReturn(configStringAfter);
863         gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
864 
865         // performance mode was not overridden thus it should be updated
866         checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.9f);
867         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 60);
868 
869         // battery mode was overridden thus it should be the same as the override
870         checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.2f);
871         checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 40);
872     }
873 
874     @Test
testSetBatteryModeConfigOverride_thenOptInBatteryMode()875     public void testSetBatteryModeConfigOverride_thenOptInBatteryMode() throws Exception {
876         mockModifyGameModeGranted();
877         String configStringBefore =
878                 "mode=2,downscaleFactor=1.0,fps=90:mode=3,downscaleFactor=0.1,fps=30";
879         when(DeviceConfig.getProperty(anyString(), anyString()))
880                 .thenReturn(configStringBefore);
881         mockInterventionsDisabledNoOptInFromXml();
882         GameManagerService gameManagerService = new GameManagerService(mMockContext,
883                 mTestLooper.getLooper());
884         startUser(gameManagerService, USER_ID_1);
885 
886         assertFalse(checkOverridden(gameManagerService, GameManager.GAME_MODE_PERFORMANCE));
887         assertFalse(checkOverridden(gameManagerService, GameManager.GAME_MODE_BATTERY));
888         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0);
889 
890         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1, 3, "40",
891                 "0.2");
892         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0);
893         // override will enable the interventions
894         checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.2f);
895         checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 40);
896 
897         mockInterventionsDisabledAllOptInFromXml();
898         gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
899 
900         assertTrue(checkOverridden(gameManagerService, GameManager.GAME_MODE_PERFORMANCE));
901         // opt-in is still false for battery mode as override exists
902         assertFalse(checkOverridden(gameManagerService, GameManager.GAME_MODE_BATTERY));
903     }
904 
905     /**
906      * Override device config for performance mode exists and is valid.
907      */
908     @Test
testResetDeviceConfigOverridePerformance()909     public void testResetDeviceConfigOverridePerformance() {
910         mockDeviceConfigPerformance();
911         mockModifyGameModeGranted();
912 
913         GameManagerService gameManagerService = new GameManagerService(
914                 mMockContext, mTestLooper.getLooper());
915         startUser(gameManagerService, USER_ID_1);
916         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
917                 GameManager.GAME_MODE_PERFORMANCE, "120", "0.3");
918 
919         gameManagerService.resetGameModeConfigOverride(mPackageName, USER_ID_1,
920                 GameManager.GAME_MODE_PERFORMANCE);
921 
922         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
923                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
924         checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.5f);
925         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
926     }
927 
928     /**
929      * Override device config for battery mode exists and is valid.
930      */
931     @Test
testResetDeviceConfigOverrideBattery()932     public void testResetDeviceConfigOverrideBattery() {
933         mockDeviceConfigBattery();
934         mockModifyGameModeGranted();
935 
936         GameManagerService gameManagerService = new GameManagerService(
937                 mMockContext, mTestLooper.getLooper());
938         startUser(gameManagerService, USER_ID_1);
939         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
940                 GameManager.GAME_MODE_BATTERY, "60", "0.5");
941 
942         gameManagerService.resetGameModeConfigOverride(mPackageName, USER_ID_1,
943                 GameManager.GAME_MODE_BATTERY);
944 
945         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_BATTERY,
946                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
947         checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.7f);
948         checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 30);
949     }
950 
951     /**
952      * Override device configs for both battery and performance modes exists and are valid.
953      */
954     @Test
testResetDeviceOverrideConfigAll()955     public void testResetDeviceOverrideConfigAll() {
956         mockDeviceConfigAll();
957         mockModifyGameModeGranted();
958 
959         GameManagerService gameManagerService = new GameManagerService(
960                 mMockContext, mTestLooper.getLooper());
961         startUser(gameManagerService, USER_ID_1);
962         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
963                 GameManager.GAME_MODE_PERFORMANCE, "120", "0.3");
964         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
965                 GameManager.GAME_MODE_BATTERY, "60", "0.5");
966 
967         gameManagerService.resetGameModeConfigOverride(mPackageName, USER_ID_1, -1);
968 
969         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
970                 GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
971                 GameManager.GAME_MODE_CUSTOM);
972         checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.5f);
973         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
974         checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.7f);
975         checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 30);
976     }
977 
978     /**
979      * Override device configs for both battery and performance modes exists and are valid.
980      * Only one mode is reset, and the other mode still has overridden config
981      */
982     @Test
testResetDeviceOverrideConfigPartial()983     public void testResetDeviceOverrideConfigPartial() {
984         mockDeviceConfigAll();
985         mockModifyGameModeGranted();
986 
987         GameManagerService gameManagerService = new GameManagerService(
988                 mMockContext, mTestLooper.getLooper());
989         startUser(gameManagerService, USER_ID_1);
990 
991         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
992                 GameManager.GAME_MODE_PERFORMANCE, "120", "0.3");
993         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
994                 GameManager.GAME_MODE_BATTERY, "60", "0.5");
995 
996         gameManagerService.resetGameModeConfigOverride(mPackageName, USER_ID_1,
997                 GameManager.GAME_MODE_BATTERY);
998 
999         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
1000                 GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
1001                 GameManager.GAME_MODE_CUSTOM);
1002         checkDownscaling(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0.3f);
1003         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 120);
1004         checkDownscaling(gameManagerService, GameManager.GAME_MODE_BATTERY, 0.7f);
1005         checkFps(gameManagerService, GameManager.GAME_MODE_BATTERY, 30);
1006     }
1007 
1008     /**
1009      * Game modes are made available only through app manifest opt-in.
1010      */
1011     @Test
testGameModeOptInAll()1012     public void testGameModeOptInAll() throws Exception {
1013         mockGameModeOptInAll();
1014         mockDeviceConfigNone();
1015         mockModifyGameModeGranted();
1016         checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
1017                 GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
1018                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
1019     }
1020 
1021 
1022     /**
1023      * BATTERY game mode is available through the app manifest opt-in.
1024      */
1025     @Test
testGameModeOptInBattery()1026     public void testGameModeOptInBattery() throws Exception {
1027         mockGameModeOptInBattery();
1028         mockDeviceConfigNone();
1029         mockModifyGameModeGranted();
1030         checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
1031                 GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
1032                 GameManager.GAME_MODE_CUSTOM);
1033     }
1034 
1035     /**
1036      * PERFORMANCE game mode is available through the app manifest opt-in.
1037      */
1038     @Test
testGameModeOptInPerformance()1039     public void testGameModeOptInPerformance() throws Exception {
1040         mockGameModeOptInPerformance();
1041         mockDeviceConfigNone();
1042         mockModifyGameModeGranted();
1043         checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
1044                 GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_STANDARD,
1045                 GameManager.GAME_MODE_CUSTOM);
1046     }
1047 
1048     /**
1049      * BATTERY game mode is available through the app manifest opt-in and PERFORMANCE game mode is
1050      * available through Phenotype.
1051      */
1052     @Test
testGameModeOptInBatteryMixed()1053     public void testGameModeOptInBatteryMixed() throws Exception {
1054         mockGameModeOptInBattery();
1055         mockDeviceConfigPerformance();
1056         mockModifyGameModeGranted();
1057         checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
1058                 GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
1059                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
1060     }
1061 
1062     /**
1063      * PERFORMANCE game mode is available through the app manifest opt-in and BATTERY game mode is
1064      * available through Phenotype.
1065      */
1066     @Test
testGameModeOptInPerformanceMixed()1067     public void testGameModeOptInPerformanceMixed() throws Exception {
1068         mockGameModeOptInPerformance();
1069         mockDeviceConfigBattery();
1070         mockModifyGameModeGranted();
1071         checkReportedAvailableGameModes(createServiceAndStartUser(USER_ID_1),
1072                 GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
1073                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
1074     }
1075 
1076     /**
1077      * PERFORMANCE game mode is configured through Phenotype. The app hasn't specified any metadata.
1078      */
1079     @Test
testInterventionAllowScalingDefault()1080     public void testInterventionAllowScalingDefault() throws Exception {
1081         mockDeviceConfigPerformance();
1082         mockModifyGameModeGranted();
1083         checkDownscaling(createServiceAndStartUser(USER_ID_1), GameManager.GAME_MODE_PERFORMANCE,
1084                 0.5f);
1085     }
1086 
1087     /**
1088      * PERFORMANCE game mode is configured through Phenotype. The app has opted-out of scaling.
1089      */
1090     @Test
testInterventionAllowDownscaleFalse()1091     public void testInterventionAllowDownscaleFalse() throws Exception {
1092         mockDeviceConfigPerformance();
1093         mockInterventionAllowDownscaleFalse();
1094         mockModifyGameModeGranted();
1095         checkDownscaling(createServiceAndStartUser(USER_ID_1), GameManager.GAME_MODE_PERFORMANCE,
1096                 -1.0f);
1097     }
1098 
1099     /**
1100      * PERFORMANCE game mode is configured through Phenotype. The app has redundantly specified
1101      * the downscaling metadata default value of "true".
1102      */
1103     @Test
testInterventionAllowDownscaleTrue()1104     public void testInterventionAllowDownscaleTrue() throws Exception {
1105         mockDeviceConfigPerformance();
1106         mockInterventionAllowDownscaleTrue();
1107         mockModifyGameModeGranted();
1108         checkDownscaling(createServiceAndStartUser(USER_ID_1), GameManager.GAME_MODE_PERFORMANCE,
1109                 0.5f);
1110     }
1111 
1112     /**
1113      * PERFORMANCE game mode is configured through Phenotype. The app hasn't specified any metadata.
1114      */
1115     @Test
testInterventionAllowAngleDefault()1116     public void testInterventionAllowAngleDefault() throws Exception {
1117         mockDeviceConfigPerformance();
1118         mockModifyGameModeGranted();
1119         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1120         checkAngleEnabled(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, false);
1121     }
1122 
1123     /**
1124      * PERFORMANCE game mode is configured through Phenotype. The app hasn't specified any
1125      * metadata.
1126      */
1127     @Test
testInterventionAllowLoadingBoostDefault()1128     public void testInterventionAllowLoadingBoostDefault() throws Exception {
1129         mockDeviceConfigPerformance();
1130         mockModifyGameModeGranted();
1131         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1132         checkLoadingBoost(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, -1);
1133     }
1134 
1135     /**
1136      * PERFORMANCE game mode is configured through Phenotype. The app has opted-out of ANGLE.
1137      */
1138     @Test
testInterventionAllowAngleFalse()1139     public void testInterventionAllowAngleFalse() throws Exception {
1140         mockDeviceConfigPerformanceEnableAngle();
1141         mockInterventionAllowAngleFalse();
1142         mockModifyGameModeGranted();
1143         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1144         checkAngleEnabled(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, false);
1145     }
1146 
1147     /**
1148      * PERFORMANCE game mode is configured through Phenotype. The app has redundantly specified
1149      * the ANGLE metadata default value of "true".
1150      */
1151     @Test
testInterventionAllowAngleTrue()1152     public void testInterventionAllowAngleTrue() throws Exception {
1153         mockDeviceConfigPerformanceEnableAngle();
1154         mockInterventionAllowAngleTrue();
1155 
1156         GameManagerService gameManagerService =
1157                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1158         startUser(gameManagerService, USER_ID_1);
1159         mockModifyGameModeGranted();
1160         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
1161         assertEquals(GameManager.GAME_MODE_PERFORMANCE,
1162                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
1163 
1164         checkAngleEnabled(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, true);
1165     }
1166 
1167     /**
1168      * PERFORMANCE game mode is configured through Phenotype. The app has redundantly specified the
1169      * Loading Boost metadata default value of "true".
1170      */
1171     @Test
testInterventionAllowLoadingBoost()1172     public void testInterventionAllowLoadingBoost() throws Exception {
1173         mockDeviceConfigPerformanceEnableLoadingBoost();
1174 
1175         GameManagerService gameManagerService =
1176                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1177         startUser(gameManagerService, USER_ID_1);
1178         mockModifyGameModeGranted();
1179         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
1180         assertEquals(GameManager.GAME_MODE_PERFORMANCE,
1181                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
1182         mockInterventionsEnabledNoOptInFromXml();
1183         checkLoadingBoost(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0);
1184     }
1185 
1186     @Test
testGameModeConfigAllowFpsTrue()1187     public void testGameModeConfigAllowFpsTrue() throws Exception {
1188         mockDeviceConfigAll();
1189         mockModifyGameModeGranted();
1190         mockInterventionsEnabledNoOptInFromXml();
1191         GameManagerService gameManagerService = new GameManagerService(mMockContext,
1192                 mTestLooper.getLooper());
1193         startUser(gameManagerService, USER_ID_1);
1194         GameManagerService.GamePackageConfiguration config =
1195                 gameManagerService.getConfig(mPackageName, USER_ID_1);
1196         assertEquals(90,
1197                 config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE).getFps());
1198         assertEquals(30, config.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY).getFps());
1199     }
1200 
1201     @Test
testGameModeConfigAllowFpsFalse()1202     public void testGameModeConfigAllowFpsFalse() throws Exception {
1203         mockDeviceConfigAll();
1204         mockModifyGameModeGranted();
1205         mockInterventionsDisabledNoOptInFromXml();
1206         GameManagerService gameManagerService = new GameManagerService(mMockContext,
1207                 mTestLooper.getLooper());
1208         startUser(gameManagerService, USER_ID_1);
1209         GameManagerService.GamePackageConfiguration config =
1210                 gameManagerService.getConfig(mPackageName, USER_ID_1);
1211         assertEquals(0,
1212                 config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE).getFps());
1213         assertEquals(0, config.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY).getFps());
1214     }
1215 
1216     @Test
testInterventionFps()1217     public void testInterventionFps() throws Exception {
1218         mockDeviceConfigAll();
1219         mockModifyGameModeGranted();
1220         GameManagerService service = createServiceAndStartUser(USER_ID_1);
1221         checkFps(service, GameManager.GAME_MODE_PERFORMANCE, 90);
1222         checkFps(service, GameManager.GAME_MODE_BATTERY, 30);
1223     }
1224 
1225     /**
1226      * PERFORMANCE game mode is configured through Phenotype, but the app has also opted into the
1227      * same mode. No interventions for this game mode should be available in this case.
1228      */
1229     @Test
testDeviceConfigOptInOverlap()1230     public void testDeviceConfigOptInOverlap() throws Exception {
1231         mockDeviceConfigPerformance();
1232         mockGameModeOptInPerformance();
1233         mockModifyGameModeGranted();
1234         GameManagerService gameManagerService =
1235                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1236         startUser(gameManagerService, USER_ID_1);
1237         gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
1238         GameManagerService.GamePackageConfiguration config =
1239                 gameManagerService.getConfig(mPackageName, USER_ID_1);
1240         assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
1241     }
1242 
1243     /**
1244      * Ensure that, if a game no longer supports any game modes, we set the game mode to
1245      * STANDARD
1246      */
1247     @Test
testUnsetInvalidGameMode()1248     public void testUnsetInvalidGameMode() throws Exception {
1249         mockDeviceConfigNone();
1250         mockModifyGameModeGranted();
1251         GameManagerService gameManagerService =
1252                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1253         startUser(gameManagerService, USER_ID_1);
1254         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
1255         gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
1256         assertEquals(GameManager.GAME_MODE_STANDARD,
1257                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
1258     }
1259 
1260     /**
1261      * Ensure that, if a game no longer supports a specific game mode, but supports STANDARD, we set
1262      * the game mode to STANDARD.
1263      */
1264     @Test
testResetInvalidGameMode()1265     public void testResetInvalidGameMode() throws Exception {
1266         mockDeviceConfigPerformance();
1267         mockModifyGameModeGranted();
1268         GameManagerService gameManagerService =
1269                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1270         startUser(gameManagerService, USER_ID_1);
1271         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
1272         gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
1273         assertEquals(GameManager.GAME_MODE_STANDARD,
1274                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
1275     }
1276 
1277     /**
1278      * Ensure that if a game supports STANDARD, but is currently set to UNSUPPORTED, we set the game
1279      * mode to STANDARD
1280      */
1281     @Test
testSetValidGameMode()1282     public void testSetValidGameMode() throws Exception {
1283         mockDeviceConfigPerformance();
1284         mockModifyGameModeGranted();
1285         GameManagerService gameManagerService =
1286                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1287         startUser(gameManagerService, USER_ID_1);
1288         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_UNSUPPORTED, USER_ID_1);
1289         gameManagerService.updateConfigsForUser(USER_ID_1, true, mPackageName);
1290         assertEquals(GameManager.GAME_MODE_STANDARD,
1291                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
1292     }
1293 
1294     static {
1295         System.loadLibrary("mockingservicestestjni");
1296     }
1297 
1298     @Test
testGetGameModeInfoPermissionDenied()1299     public void testGetGameModeInfoPermissionDenied() {
1300         mockDeviceConfigAll();
1301         GameManagerService gameManagerService =
1302                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1303         startUser(gameManagerService, USER_ID_1);
1304 
1305         // Deny permission.MANAGE_GAME_MODE and verify the game mode is not updated.
1306         mockModifyGameModeDenied();
1307         assertThrows(SecurityException.class,
1308                 () -> gameManagerService.getGameModeInfo(mPackageName, USER_ID_1));
1309     }
1310 
1311     @Test
testGetGameModeInfoWithAllGameModes()1312     public void testGetGameModeInfoWithAllGameModes() {
1313         mockDeviceConfigAll();
1314         mockModifyGameModeGranted();
1315         GameManagerService gameManagerService =
1316                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1317         startUser(gameManagerService, USER_ID_1);
1318         GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
1319         assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
1320         assertTrue(gameModeInfo.isDownscalingAllowed());
1321         assertTrue(gameModeInfo.isFpsOverrideAllowed());
1322 
1323         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
1324                 GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
1325                 GameManager.GAME_MODE_CUSTOM);
1326         checkReportedOverriddenGameModes(gameManagerService);
1327 
1328         assertEquals(new GameModeConfiguration.Builder()
1329                 .setFpsOverride(30)
1330                 .setScalingFactor(0.7f)
1331                 .build(), gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
1332         assertEquals(new GameModeConfiguration.Builder()
1333                 .setFpsOverride(90)
1334                 .setScalingFactor(0.5f)
1335                 .build(), gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
1336     }
1337 
1338     @Test
testGetGameModeInfoWithBatteryMode()1339     public void testGetGameModeInfoWithBatteryMode() {
1340         mockDeviceConfigBattery();
1341         mockModifyGameModeGranted();
1342         GameManagerService gameManagerService =
1343                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1344         startUser(gameManagerService, USER_ID_1);
1345         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
1346         GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
1347 
1348         assertEquals(GameManager.GAME_MODE_BATTERY, gameModeInfo.getActiveGameMode());
1349 
1350         checkReportedAvailableGameModes(gameManagerService,
1351                 GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
1352                 GameManager.GAME_MODE_CUSTOM);
1353         checkReportedOverriddenGameModes(gameManagerService);
1354 
1355         assertNotNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
1356         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
1357     }
1358 
1359     @Test
testGetGameModeInfoWithPerformanceMode()1360     public void testGetGameModeInfoWithPerformanceMode() {
1361         mockDeviceConfigPerformance();
1362         mockModifyGameModeGranted();
1363         GameManagerService gameManagerService =
1364                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1365         startUser(gameManagerService, USER_ID_1);
1366         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
1367         GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
1368 
1369         assertEquals(GameManager.GAME_MODE_PERFORMANCE, gameModeInfo.getActiveGameMode());
1370         checkReportedAvailableGameModes(gameManagerService,
1371                 GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_STANDARD,
1372                 GameManager.GAME_MODE_CUSTOM);
1373         checkReportedOverriddenGameModes(gameManagerService);
1374 
1375         assertNotNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
1376         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
1377     }
1378 
1379     @Test
testGetGameModeInfoWithDefaultGameModes()1380     public void testGetGameModeInfoWithDefaultGameModes() {
1381         mockDeviceConfigNone();
1382         mockModifyGameModeGranted();
1383         GameManagerService gameManagerService =
1384                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1385         startUser(gameManagerService, USER_ID_1);
1386         GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
1387 
1388         assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
1389         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
1390                 GameManager.GAME_MODE_CUSTOM);
1391         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM));
1392         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_STANDARD));
1393         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
1394         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
1395     }
1396 
1397     @Test
testGetGameModeInfoWithAllGameModesOverridden_noDeviceConfig()1398     public void testGetGameModeInfoWithAllGameModesOverridden_noDeviceConfig()
1399             throws Exception {
1400         mockModifyGameModeGranted();
1401         mockInterventionsEnabledAllOptInFromXml();
1402         mockDeviceConfigNone();
1403         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1404         GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
1405         assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
1406         verifyAllModesOverriddenAndInterventionsAvailable(gameManagerService, gameModeInfo);
1407 
1408         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
1409         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
1410     }
1411 
1412     @Test
testGetGameModeInfoWithAllGameModesOverridden_allDeviceConfig()1413     public void testGetGameModeInfoWithAllGameModesOverridden_allDeviceConfig()
1414             throws Exception {
1415         mockModifyGameModeGranted();
1416         mockInterventionsEnabledAllOptInFromXml();
1417         mockDeviceConfigAll();
1418         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1419         GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
1420         assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
1421         verifyAllModesOverriddenAndInterventionsAvailable(gameManagerService, gameModeInfo);
1422 
1423         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
1424         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
1425     }
1426 
verifyAllModesOverriddenAndInterventionsAvailable( GameManagerService gameManagerService, GameModeInfo gameModeInfo)1427     private void verifyAllModesOverriddenAndInterventionsAvailable(
1428             GameManagerService gameManagerService,
1429             GameModeInfo gameModeInfo) {
1430         checkReportedAvailableGameModes(gameManagerService,
1431                 GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
1432                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
1433         checkReportedOverriddenGameModes(gameManagerService,
1434                 GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY);
1435         assertTrue(gameModeInfo.isFpsOverrideAllowed());
1436         assertTrue(gameModeInfo.isDownscalingAllowed());
1437     }
1438 
1439     @Test
testGetGameModeInfoWithBatteryModeOverridden_withBatteryDeviceConfig()1440     public void testGetGameModeInfoWithBatteryModeOverridden_withBatteryDeviceConfig()
1441             throws Exception {
1442         mockModifyGameModeGranted();
1443         mockInterventionsEnabledBatteryOptInFromXml();
1444         mockDeviceConfigBattery();
1445         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1446         GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
1447         assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
1448 
1449         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_BATTERY,
1450                 GameManager.GAME_MODE_STANDARD, GameManager.GAME_MODE_CUSTOM);
1451         checkReportedOverriddenGameModes(gameManagerService, GameManager.GAME_MODE_BATTERY);
1452 
1453         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
1454         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
1455     }
1456 
1457     @Test
testGetGameModeInfoWithPerformanceModeOverridden_withAllDeviceConfig()1458     public void testGetGameModeInfoWithPerformanceModeOverridden_withAllDeviceConfig()
1459             throws Exception {
1460         mockModifyGameModeGranted();
1461         mockInterventionsEnabledPerformanceOptInFromXml();
1462         mockDeviceConfigAll();
1463         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1464         GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
1465         assertEquals(GameManager.GAME_MODE_STANDARD, gameModeInfo.getActiveGameMode());
1466 
1467         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE,
1468                 GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD,
1469                 GameManager.GAME_MODE_CUSTOM);
1470         checkReportedOverriddenGameModes(gameManagerService, GameManager.GAME_MODE_PERFORMANCE);
1471 
1472         assertNotNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY));
1473         assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
1474     }
1475 
1476     @Test
testGetGameModeInfoWithInterventionsDisabled()1477     public void testGetGameModeInfoWithInterventionsDisabled() throws Exception {
1478         mockModifyGameModeGranted();
1479         mockInterventionsDisabledAllOptInFromXml();
1480         mockDeviceConfigAll();
1481         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1482         GameModeInfo gameModeInfo = gameManagerService.getGameModeInfo(mPackageName, USER_ID_1);
1483         assertFalse(gameModeInfo.isFpsOverrideAllowed());
1484         assertFalse(gameModeInfo.isDownscalingAllowed());
1485     }
1486 
1487     @Test
testSetGameState_loadingRequiresPerformanceMode()1488     public void testSetGameState_loadingRequiresPerformanceMode() {
1489         mockDeviceConfigNone();
1490         mockModifyGameModeGranted();
1491         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1492         GameState gameState = new GameState(true, GameState.MODE_NONE);
1493         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
1494         mTestLooper.dispatchAll();
1495         verify(mMockPowerManager, never()).setPowerMode(anyInt(), anyBoolean());
1496     }
1497 
1498     @Test
testSetGameStateLoading_withNoDeviceConfig()1499     public void testSetGameStateLoading_withNoDeviceConfig() {
1500         mockDeviceConfigNone();
1501         mockModifyGameModeGranted();
1502         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1503         gameManagerService.setGameMode(
1504                 mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
1505         assertEquals(gameManagerService.getGameMode(mPackageName, USER_ID_1),
1506                 GameManager.GAME_MODE_PERFORMANCE);
1507         int testMode = GameState.MODE_GAMEPLAY_INTERRUPTIBLE;
1508         int testLabel = 99;
1509         int testQuality = 123;
1510         GameState gameState = new GameState(true, testMode, testLabel, testQuality);
1511         assertEquals(testMode, gameState.getMode());
1512         assertEquals(testLabel, gameState.getLabel());
1513         assertEquals(testQuality, gameState.getQuality());
1514         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
1515         mTestLooper.dispatchAll();
1516         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, true);
1517         reset(mMockPowerManager);
1518         assertTrue(
1519                 gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
1520         verify(mMockPowerManager, never()).setPowerMode(Mode.GAME_LOADING, false);
1521         mTestLooper.moveTimeForward(GameManagerService.LOADING_BOOST_MAX_DURATION);
1522         mTestLooper.dispatchAll();
1523         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, false);
1524     }
1525 
1526     @Test
testSetGameStateLoading_withDeviceConfig()1527     public void testSetGameStateLoading_withDeviceConfig() {
1528         String configString = "mode=2,loadingBoost=2000";
1529         when(DeviceConfig.getProperty(anyString(), anyString()))
1530                 .thenReturn(configString);
1531         mockModifyGameModeGranted();
1532         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1533         gameManagerService.setGameMode(
1534                 mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
1535         GameState gameState = new GameState(true, GameState.MODE_GAMEPLAY_INTERRUPTIBLE, 99, 123);
1536         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
1537         mTestLooper.dispatchAll();
1538         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, true);
1539         verify(mMockPowerManager, never()).setPowerMode(Mode.GAME_LOADING, false);
1540         reset(mMockPowerManager);
1541         assertTrue(
1542                 gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
1543         mTestLooper.moveTimeForward(2000);
1544         mTestLooper.dispatchAll();
1545         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, false);
1546     }
1547 
1548     @Test
testSetGameStateNotLoading()1549     public void testSetGameStateNotLoading() {
1550         mockDeviceConfigNone();
1551         mockModifyGameModeGranted();
1552         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1553         gameManagerService.setGameMode(
1554                 mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
1555         int testMode = GameState.MODE_GAMEPLAY_UNINTERRUPTIBLE;
1556         int testLabel = 99;
1557         int testQuality = 123;
1558         GameState gameState = new GameState(false, testMode, testLabel, testQuality);
1559         assertFalse(gameState.isLoading());
1560         assertEquals(testMode, gameState.getMode());
1561         assertEquals(testLabel, gameState.getLabel());
1562         assertEquals(testQuality, gameState.getQuality());
1563         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
1564         assertTrue(gameManagerService.mHandler.hasEqualMessages(SET_GAME_STATE, gameState));
1565         mTestLooper.dispatchAll();
1566         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, false);
1567         assertFalse(
1568                 gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
1569     }
1570 
1571     @Test
testSetGameState_nonGame()1572     public void testSetGameState_nonGame() throws Exception {
1573         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_AUDIO);
1574         mockDeviceConfigNone();
1575         mockModifyGameModeGranted();
1576         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1577         GameState gameState = new GameState(true, GameState.MODE_NONE);
1578         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
1579         assertFalse(gameManagerService.mHandler.hasMessages(SET_GAME_STATE));
1580     }
1581 
1582     @Test
testAddGameStateListener()1583     public void testAddGameStateListener() throws Exception {
1584         mockModifyGameModeGranted();
1585         GameManagerService gameManagerService =
1586                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1587         mockDeviceConfigAll();
1588         startUser(gameManagerService, USER_ID_1);
1589 
1590         IGameStateListener mockListener = Mockito.mock(IGameStateListener.class);
1591         IBinder binder = Mockito.mock(IBinder.class);
1592         when(mockListener.asBinder()).thenReturn(binder);
1593         gameManagerService.addGameStateListener(mockListener);
1594         verify(binder).linkToDeath(mDeathRecipientCaptor.capture(), anyInt());
1595 
1596         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_AUDIO);
1597         GameState gameState = new GameState(true, GameState.MODE_NONE);
1598         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
1599         assertFalse(gameManagerService.mHandler.hasMessages(SET_GAME_STATE));
1600         mTestLooper.dispatchAll();
1601         verify(mockListener, never()).onGameStateChanged(anyString(), any(), anyInt());
1602 
1603         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_GAME);
1604         gameState = new GameState(true, GameState.MODE_NONE);
1605         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
1606         assertTrue(gameManagerService.mHandler.hasMessages(SET_GAME_STATE));
1607         mTestLooper.dispatchAll();
1608         verify(mockListener).onGameStateChanged(mPackageName, gameState, USER_ID_1);
1609         reset(mockListener);
1610 
1611         gameState = new GameState(false, GameState.MODE_CONTENT);
1612         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
1613         mTestLooper.dispatchAll();
1614         verify(mockListener).onGameStateChanged(mPackageName, gameState, USER_ID_1);
1615         reset(mockListener);
1616 
1617         mDeathRecipientCaptor.getValue().binderDied();
1618         verify(binder).unlinkToDeath(eq(mDeathRecipientCaptor.getValue()), anyInt());
1619         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
1620         assertTrue(gameManagerService.mHandler.hasMessages(SET_GAME_STATE));
1621         mTestLooper.dispatchAll();
1622         verify(mockListener, never()).onGameStateChanged(anyString(), any(), anyInt());
1623     }
1624 
1625     @Test
testRemoveGameStateListener()1626     public void testRemoveGameStateListener() throws Exception {
1627         mockModifyGameModeGranted();
1628         GameManagerService gameManagerService =
1629                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1630         mockDeviceConfigAll();
1631         startUser(gameManagerService, USER_ID_1);
1632 
1633         IGameStateListener mockListener = Mockito.mock(IGameStateListener.class);
1634         IBinder binder = Mockito.mock(IBinder.class);
1635         when(mockListener.asBinder()).thenReturn(binder);
1636 
1637         gameManagerService.addGameStateListener(mockListener);
1638         gameManagerService.removeGameStateListener(mockListener);
1639         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_GAME);
1640         GameState gameState = new GameState(false, GameState.MODE_CONTENT);
1641         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
1642         assertTrue(gameManagerService.mHandler.hasMessages(SET_GAME_STATE));
1643         mTestLooper.dispatchAll();
1644         verify(mockListener, never()).onGameStateChanged(anyString(), any(), anyInt());
1645     }
1646 
readGameModeInterventionList()1647     private List<String> readGameModeInterventionList() throws Exception {
1648         final File interventionFile = new File(InstrumentationRegistry.getContext().getFilesDir(),
1649                 "system/game_mode_intervention.list");
1650         assertNotNull(interventionFile);
1651         List<String> output = Files.readAllLines(interventionFile.toPath());
1652         return output;
1653     }
1654 
mockInterventionListForMultipleUsers()1655     private void mockInterventionListForMultipleUsers() {
1656         final String[] packageNames = new String[]{"com.android.app0",
1657                 "com.android.app1", "com.android.app2"};
1658 
1659         final ApplicationInfo[] applicationInfos = new ApplicationInfo[3];
1660         final PackageInfo[] pis = new PackageInfo[3];
1661         for (int i = 0; i < 3; ++i) {
1662             applicationInfos[i] = new ApplicationInfo();
1663             applicationInfos[i].category = ApplicationInfo.CATEGORY_GAME;
1664             applicationInfos[i].packageName = packageNames[i];
1665 
1666             pis[i] = new PackageInfo();
1667             pis[i].packageName = packageNames[i];
1668             pis[i].applicationInfo = applicationInfos[i];
1669         }
1670 
1671         final List<PackageInfo> userOnePackages = new ArrayList<>();
1672         final List<PackageInfo> userTwoPackages = new ArrayList<>();
1673         userOnePackages.add(pis[1]);
1674         userTwoPackages.add(pis[0]);
1675         userTwoPackages.add(pis[2]);
1676 
1677         final List<UserInfo> userInfos = new ArrayList<>(2);
1678         userInfos.add(new UserInfo());
1679         userInfos.add(new UserInfo());
1680         userInfos.get(0).id = USER_ID_1;
1681         userInfos.get(1).id = USER_ID_2;
1682 
1683         when(mMockPackageManager.getInstalledPackagesAsUser(anyInt(), eq(USER_ID_1)))
1684                 .thenReturn(userOnePackages);
1685         when(mMockPackageManager.getInstalledPackagesAsUser(anyInt(), eq(USER_ID_2)))
1686                 .thenReturn(userTwoPackages);
1687         when(mMockUserManager.getUsers()).thenReturn(userInfos);
1688     }
1689 
1690     @Test
testVerifyInterventionList()1691     public void testVerifyInterventionList() throws Exception {
1692         mockDeviceConfigAll();
1693         mockInterventionListForMultipleUsers();
1694         mockManageUsersGranted();
1695         mockModifyGameModeGranted();
1696         final Context context = InstrumentationRegistry.getContext();
1697         GameManagerService gameManagerService =
1698                 new GameManagerService(mMockContext,
1699                         mTestLooper.getLooper(),
1700                         context.getFilesDir());
1701         startUser(gameManagerService, USER_ID_1);
1702         startUser(gameManagerService, USER_ID_2);
1703 
1704         gameManagerService.setGameModeConfigOverride("com.android.app0", USER_ID_2,
1705                 GameManager.GAME_MODE_PERFORMANCE, "120", "0.6");
1706         gameManagerService.setGameModeConfigOverride("com.android.app2", USER_ID_2,
1707                 GameManager.GAME_MODE_BATTERY, "60", "0.5");
1708         mTestLooper.dispatchAll();
1709 
1710         /* Expected fileOutput (order may vary)
1711          # user 1001:
1712          com.android.app2 <UID>   1   2   angle=0,scaling=0.5,fps=90  3   angle=0,scaling=0.5,fps=60
1713          com.android.app1 <UID>   1   2   angle=0,scaling=0.5,fps=90  3   angle=0,scaling=0.7,fps=30
1714          com.android.app0 <UID>   1   2   angle=0,scaling=0.6,fps=120 3   angle=0,scaling=0.7,fps=30
1715 
1716          # user 1002:
1717          com.android.app2 <UID>   1   2   angle=0,scaling=0.5,fps=90  3   angle=0,scaling=0.7,fps=30
1718          com.android.app1 <UID>   1   2   angle=0,scaling=0.5,fps=90  3   angle=0,scaling=0.7,fps=30
1719          com.android.app0 <UID>   1   2   angle=0,scaling=0.5,fps=90  3   angle=0,scaling=0.7,fps=30
1720          The current game mode would only be set to non-zero if the current user have that game
1721          installed.
1722         */
1723 
1724         List<String> fileOutput = readGameModeInterventionList();
1725         assertEquals(fileOutput.size(), 3);
1726 
1727         String[] splitLine = fileOutput.get(0).split("\\s+");
1728         assertEquals(splitLine[0], "com.android.app2");
1729         assertEquals(splitLine[2], "3");
1730         assertEquals(splitLine[3], "2");
1731         assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
1732         assertEquals(splitLine[5], "3");
1733         assertEquals(splitLine[6], "angle=0,scaling=0.5,fps=60");
1734         splitLine = fileOutput.get(1).split("\\s+");
1735         assertEquals(splitLine[0], "com.android.app1");
1736         assertEquals(splitLine[2], "1");
1737         assertEquals(splitLine[3], "2");
1738         assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
1739         assertEquals(splitLine[5], "3");
1740         assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
1741         splitLine = fileOutput.get(2).split("\\s+");
1742         assertEquals(splitLine[0], "com.android.app0");
1743         assertEquals(splitLine[2], "2");
1744         assertEquals(splitLine[3], "2");
1745         assertEquals(splitLine[4], "angle=0,scaling=0.6,fps=120");
1746         assertEquals(splitLine[5], "3");
1747         assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
1748 
1749         switchUser(gameManagerService, USER_ID_2, USER_ID_1);
1750         gameManagerService.setGameMode("com.android.app1",
1751                 GameManager.GAME_MODE_BATTERY, USER_ID_1);
1752         mTestLooper.dispatchAll();
1753 
1754         fileOutput = readGameModeInterventionList();
1755         assertEquals(fileOutput.size(), 3);
1756 
1757         splitLine = fileOutput.get(0).split("\\s+");
1758         assertEquals(splitLine[0], "com.android.app2");
1759         assertEquals(splitLine[2], "1");
1760         assertEquals(splitLine[3], "2");
1761         assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
1762         assertEquals(splitLine[5], "3");
1763         assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
1764         splitLine = fileOutput.get(1).split("\\s+");
1765         assertEquals(splitLine[0], "com.android.app1");
1766         assertEquals(splitLine[2], "3");
1767         assertEquals(splitLine[3], "2");
1768         assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
1769         assertEquals(splitLine[5], "3");
1770         assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
1771         splitLine = fileOutput.get(2).split("\\s+");
1772         assertEquals(splitLine[0], "com.android.app0");
1773         assertEquals(splitLine[2], "1");
1774         assertEquals(splitLine[3], "2");
1775         assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
1776         assertEquals(splitLine[5], "3");
1777         assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
1778 
1779     }
1780 
1781     @Test
testSwitchUser()1782     public void testSwitchUser() {
1783         mockManageUsersGranted();
1784         mockModifyGameModeGranted();
1785 
1786         mockDeviceConfigBattery();
1787         final Context context = InstrumentationRegistry.getContext();
1788         GameManagerService gameManagerService = new GameManagerService(mMockContext,
1789                 mTestLooper.getLooper(), context.getFilesDir());
1790         startUser(gameManagerService, USER_ID_1);
1791         startUser(gameManagerService, USER_ID_2);
1792         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
1793         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
1794                 GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_CUSTOM);
1795         assertEquals(gameManagerService.getGameMode(mPackageName, USER_ID_1),
1796                 GameManager.GAME_MODE_BATTERY);
1797 
1798         mockDeviceConfigAll();
1799         switchUser(gameManagerService, USER_ID_1, USER_ID_2);
1800         assertEquals(gameManagerService.getGameMode(mPackageName, USER_ID_2),
1801                 GameManager.GAME_MODE_STANDARD);
1802         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
1803                 GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_PERFORMANCE,
1804                 GameManager.GAME_MODE_CUSTOM);
1805 
1806         switchUser(gameManagerService, USER_ID_2, USER_ID_1);
1807         assertEquals(gameManagerService.getGameMode(mPackageName, USER_ID_1),
1808                 GameManager.GAME_MODE_BATTERY);
1809         checkReportedAvailableGameModes(gameManagerService, GameManager.GAME_MODE_STANDARD,
1810                 GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_PERFORMANCE,
1811                 GameManager.GAME_MODE_CUSTOM);
1812     }
1813 
1814     @Test
testUpdateResolutionScalingFactor()1815     public void testUpdateResolutionScalingFactor() {
1816         mockModifyGameModeGranted();
1817         mockDeviceConfigBattery();
1818         GameManagerService gameManagerService =
1819                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1820         startUser(gameManagerService, USER_ID_1);
1821         float scalingFactor = 0.123f;
1822         gameManagerService.updateResolutionScalingFactor(mPackageName,
1823                 GameManager.GAME_MODE_BATTERY, scalingFactor,
1824                 USER_ID_1);
1825         assertEquals(scalingFactor, gameManagerService.getResolutionScalingFactor(mPackageName,
1826                 GameManager.GAME_MODE_BATTERY, USER_ID_1), 0.001f);
1827         scalingFactor = 0.321f;
1828         gameManagerService.updateResolutionScalingFactor(mPackageName,
1829                 GameManager.GAME_MODE_BATTERY, scalingFactor,
1830                 USER_ID_1);
1831         assertEquals(scalingFactor, gameManagerService.getResolutionScalingFactor(mPackageName,
1832                 GameManager.GAME_MODE_BATTERY, USER_ID_1), 0.001f);
1833     }
1834 
1835     @Test
testUpdateResolutionScalingFactor_noDeviceConfig()1836     public void testUpdateResolutionScalingFactor_noDeviceConfig() {
1837         mockModifyGameModeGranted();
1838         GameManagerService gameManagerService =
1839                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1840         startUser(gameManagerService, USER_ID_1);
1841         float scalingFactor = 0.123f;
1842         gameManagerService.updateResolutionScalingFactor(mPackageName,
1843                 GameManager.GAME_MODE_BATTERY, scalingFactor,
1844                 USER_ID_1);
1845         assertEquals(scalingFactor, gameManagerService.getResolutionScalingFactor(mPackageName,
1846                 GameManager.GAME_MODE_BATTERY, USER_ID_1), 0.001f);
1847         scalingFactor = 0.321f;
1848         gameManagerService.updateResolutionScalingFactor(mPackageName,
1849                 GameManager.GAME_MODE_BATTERY, scalingFactor,
1850                 USER_ID_1);
1851         assertEquals(scalingFactor, gameManagerService.getResolutionScalingFactor(mPackageName,
1852                 GameManager.GAME_MODE_BATTERY,
1853                 USER_ID_1), 0.001f);
1854     }
1855 
1856     @Test
testUpdateResolutionScalingFactor_permissionDenied()1857     public void testUpdateResolutionScalingFactor_permissionDenied() {
1858         mockModifyGameModeDenied();
1859         mockDeviceConfigAll();
1860         GameManagerService gameManagerService =
1861                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1862         startUser(gameManagerService, USER_ID_1);
1863         float scalingFactor = 0.123f;
1864         assertThrows(SecurityException.class, () -> {
1865             gameManagerService.updateResolutionScalingFactor(mPackageName,
1866                     GameManager.GAME_MODE_BATTERY, scalingFactor,
1867                     USER_ID_1);
1868         });
1869         mockModifyGameModeGranted();
1870         assertEquals(0.7f, gameManagerService.getResolutionScalingFactor(mPackageName,
1871                 GameManager.GAME_MODE_BATTERY, USER_ID_1), 0.001f);
1872     }
1873 
1874     @Test
testUpdateResolutionScalingFactor_noUserId()1875     public void testUpdateResolutionScalingFactor_noUserId() {
1876         mockModifyGameModeGranted();
1877         GameManagerService gameManagerService =
1878                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1879         startUser(gameManagerService, USER_ID_2);
1880         final float scalingFactor = 0.123f;
1881         assertThrows(IllegalArgumentException.class, () -> {
1882             gameManagerService.updateResolutionScalingFactor(mPackageName,
1883                     GameManager.GAME_MODE_BATTERY, scalingFactor,
1884                     USER_ID_1);
1885         });
1886     }
1887 
1888     @Test
testGetResolutionScalingFactor_permissionDenied()1889     public void testGetResolutionScalingFactor_permissionDenied() {
1890         mockModifyGameModeDenied();
1891         mockDeviceConfigAll();
1892         GameManagerService gameManagerService =
1893                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1894         startUser(gameManagerService, USER_ID_1);
1895         assertThrows(SecurityException.class, () -> {
1896             gameManagerService.getResolutionScalingFactor(mPackageName,
1897                     GameManager.GAME_MODE_BATTERY, USER_ID_1);
1898         });
1899     }
1900 
1901     @Test
testGetResolutionScalingFactor_noUserId()1902     public void testGetResolutionScalingFactor_noUserId() {
1903         mockModifyGameModeGranted();
1904         mockDeviceConfigAll();
1905         GameManagerService gameManagerService =
1906                 new GameManagerService(mMockContext, mTestLooper.getLooper());
1907         startUser(gameManagerService, USER_ID_2);
1908         assertThrows(IllegalArgumentException.class, () -> {
1909             gameManagerService.getResolutionScalingFactor(mPackageName,
1910                     GameManager.GAME_MODE_BATTERY, USER_ID_1);
1911         });
1912     }
1913 
1914     @Test
testUpdateCustomGameModeConfiguration_permissionDenied()1915     public void testUpdateCustomGameModeConfiguration_permissionDenied() {
1916         mockModifyGameModeDenied();
1917         mockDeviceConfigAll();
1918         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1919         assertThrows(SecurityException.class, () -> {
1920             gameManagerService.updateCustomGameModeConfiguration(mPackageName,
1921                     new GameModeConfiguration.Builder().setScalingFactor(0.5f).build(),
1922                     USER_ID_1);
1923         });
1924     }
1925 
1926     @Test
testUpdateCustomGameModeConfiguration_noUserId()1927     public void testUpdateCustomGameModeConfiguration_noUserId() {
1928         mockModifyGameModeGranted();
1929         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_2);
1930         assertThrows(IllegalArgumentException.class, () -> {
1931             gameManagerService.updateCustomGameModeConfiguration(mPackageName,
1932                     new GameModeConfiguration.Builder().setScalingFactor(0.5f).build(),
1933                     USER_ID_1);
1934         });
1935     }
1936 
1937     @Test
testUpdateCustomGameModeConfiguration_nonGame()1938     public void testUpdateCustomGameModeConfiguration_nonGame() throws Exception {
1939         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_IMAGE);
1940         mockModifyGameModeGranted();
1941         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
1942         gameManagerService.updateCustomGameModeConfiguration(mPackageName,
1943                 new GameModeConfiguration.Builder().setScalingFactor(0.35f).setFpsOverride(
1944                         60).build(),
1945                 USER_ID_1);
1946         assertFalse(gameManagerService.mHandler.hasMessages(WRITE_SETTINGS));
1947         GameManagerService.GamePackageConfiguration pkgConfig = gameManagerService.getConfig(
1948                 mPackageName, USER_ID_1);
1949         assertNull(pkgConfig);
1950     }
1951 
1952     @Test
testUpdateCustomGameModeConfiguration()1953     public void testUpdateCustomGameModeConfiguration() throws InterruptedException {
1954         mockModifyGameModeGranted();
1955         GameManagerService gameManagerService = Mockito.spy(createServiceAndStartUser(USER_ID_1));
1956         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_CUSTOM, USER_ID_1);
1957         gameManagerService.updateCustomGameModeConfiguration(mPackageName,
1958                 new GameModeConfiguration.Builder().setScalingFactor(0.35f).setFpsOverride(
1959                         60).build(),
1960                 USER_ID_1);
1961         assertTrue(gameManagerService.mHandler.hasEqualMessages(WRITE_SETTINGS, USER_ID_1));
1962         assertTrue(
1963                 gameManagerService.mHandler.hasEqualMessages(WRITE_GAME_MODE_INTERVENTION_LIST_FILE,
1964                         USER_ID_1));
1965         Mockito.verify(gameManagerService).setOverrideFrameRate(
1966                 ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
1967                 ArgumentMatchers.eq(60.0f));
1968         checkFps(gameManagerService, GameManager.GAME_MODE_CUSTOM, 60);
1969 
1970         GameManagerService.GamePackageConfiguration pkgConfig = gameManagerService.getConfig(
1971                 mPackageName, USER_ID_1);
1972         assertNotNull(pkgConfig);
1973         GameManagerService.GamePackageConfiguration.GameModeConfiguration modeConfig =
1974                 pkgConfig.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM);
1975         assertNotNull(modeConfig);
1976         assertEquals(modeConfig.getScaling(), 0.35f, 0.01f);
1977         assertEquals(modeConfig.getFps(), 60);
1978         // creates a new service to check that no data has been stored
1979         mTestLooper.dispatchAll();
1980         gameManagerService = createServiceAndStartUser(USER_ID_1);
1981         pkgConfig = gameManagerService.getConfig(mPackageName, USER_ID_1);
1982         assertNull(pkgConfig);
1983 
1984         mTestLooper.moveTimeForward(WRITE_DELAY_MILLIS + 500);
1985         mTestLooper.dispatchAll();
1986         // creates a new service to check that data is persisted after delay
1987         gameManagerService = createServiceAndStartUser(USER_ID_1);
1988         assertEquals(GameManager.GAME_MODE_STANDARD,
1989                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
1990         pkgConfig = gameManagerService.getConfig(mPackageName, USER_ID_1);
1991         assertNotNull(pkgConfig);
1992         modeConfig = pkgConfig.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM);
1993         assertNotNull(modeConfig);
1994         assertEquals(modeConfig.getScaling(), 0.35f, 0.01f);
1995         assertEquals(modeConfig.getFps(), 60);
1996     }
1997 
1998     @Test
testWritingSettingFile_onShutdown()1999     public void testWritingSettingFile_onShutdown() throws InterruptedException {
2000         mockModifyGameModeGranted();
2001         mockDeviceConfigAll();
2002         GameManagerService gameManagerService = new GameManagerService(mMockContext);
2003         gameManagerService.onBootCompleted();
2004         startUser(gameManagerService, USER_ID_1);
2005         Thread.sleep(500);
2006         gameManagerService.setGameModeConfigOverride("com.android.app1", USER_ID_1,
2007                 GameManager.GAME_MODE_BATTERY, "60", "0.5");
2008         gameManagerService.setGameMode("com.android.app1", USER_ID_1,
2009                 GameManager.GAME_MODE_PERFORMANCE);
2010         GameManagerSettings settings = new GameManagerSettings(
2011                 InstrumentationRegistry.getContext().getFilesDir());
2012         Thread.sleep(500);
2013         // no data written as delayed messages are queued
2014         assertFalse(settings.readPersistentDataLocked());
2015         assertTrue(gameManagerService.mHandler.hasEqualMessages(WRITE_SETTINGS, USER_ID_1));
2016         Intent shutdown = new Intent();
2017         shutdown.setAction(Intent.ACTION_SHUTDOWN);
2018         mShutDownActionReceiver.onReceive(mMockContext, shutdown);
2019         Thread.sleep(500);
2020         // data is written on processing new message with no delay on shutdown,
2021         // and all queued messages should be removed
2022         assertTrue(settings.readPersistentDataLocked());
2023         assertFalse(gameManagerService.mHandler.hasEqualMessages(WRITE_SETTINGS, USER_ID_1));
2024     }
2025 
2026     @Test
testResetInterventions_onDeviceConfigReset()2027     public void testResetInterventions_onDeviceConfigReset() throws Exception {
2028         mockModifyGameModeGranted();
2029         String configStringBefore =
2030                 "mode=2,downscaleFactor=1.0,fps=90";
2031         when(DeviceConfig.getProperty(anyString(), anyString()))
2032                 .thenReturn(configStringBefore);
2033         mockInterventionsEnabledNoOptInFromXml();
2034         GameManagerService gameManagerService = Mockito.spy(new GameManagerService(mMockContext,
2035                 mTestLooper.getLooper()));
2036         startUser(gameManagerService, USER_ID_1);
2037         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
2038         Mockito.verify(gameManagerService).setOverrideFrameRate(
2039                 ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
2040                 ArgumentMatchers.eq(90.0f));
2041         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
2042 
2043         String configStringAfter = "";
2044         when(DeviceConfig.getProperty(anyString(), anyString()))
2045                 .thenReturn(configStringAfter);
2046         gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
2047         Mockito.verify(gameManagerService).setOverrideFrameRate(
2048                 ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
2049                 ArgumentMatchers.eq(0.0f));
2050     }
2051 
2052     @Test
testResetInterventions_onInterventionsDisabled()2053     public void testResetInterventions_onInterventionsDisabled() throws Exception {
2054         mockModifyGameModeGranted();
2055         String configStringBefore =
2056                 "mode=2,downscaleFactor=1.0,fps=90";
2057         when(DeviceConfig.getProperty(anyString(), anyString()))
2058                 .thenReturn(configStringBefore);
2059         mockInterventionsEnabledNoOptInFromXml();
2060         GameManagerService gameManagerService = Mockito.spy(new GameManagerService(mMockContext,
2061                 mTestLooper.getLooper()));
2062         startUser(gameManagerService, USER_ID_1);
2063         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
2064         Mockito.verify(gameManagerService).setOverrideFrameRate(
2065                 ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
2066                 ArgumentMatchers.eq(90.0f));
2067         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
2068 
2069         mockInterventionsDisabledNoOptInFromXml();
2070         gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
2071         Mockito.verify(gameManagerService).setOverrideFrameRate(
2072                 ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
2073                 ArgumentMatchers.eq(0.0f));
2074         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 0);
2075     }
2076 
2077     @Test
testResetInterventions_onGameModeOverridden()2078     public void testResetInterventions_onGameModeOverridden() throws Exception {
2079         mockModifyGameModeGranted();
2080         String configStringBefore =
2081                 "mode=2,downscaleFactor=1.0,fps=90";
2082         when(DeviceConfig.getProperty(anyString(), anyString()))
2083                 .thenReturn(configStringBefore);
2084         mockInterventionsEnabledNoOptInFromXml();
2085         GameManagerService gameManagerService = Mockito.spy(new GameManagerService(mMockContext,
2086                 mTestLooper.getLooper()));
2087         startUser(gameManagerService, USER_ID_1);
2088 
2089         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
2090         Mockito.verify(gameManagerService).setOverrideFrameRate(
2091                 ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
2092                 ArgumentMatchers.eq(90.0f));
2093         checkFps(gameManagerService, GameManager.GAME_MODE_PERFORMANCE, 90);
2094 
2095         mockInterventionsEnabledAllOptInFromXml();
2096         gameManagerService.updateConfigsForUser(USER_ID_1, false, mPackageName);
2097         Mockito.verify(gameManagerService).setOverrideFrameRate(
2098                 ArgumentMatchers.eq(DEFAULT_PACKAGE_UID),
2099                 ArgumentMatchers.eq(0.0f));
2100     }
2101 
2102     @Test
testAddGameModeListener()2103     public void testAddGameModeListener() throws RemoteException {
2104         GameManagerService gameManagerService =
2105                 new GameManagerService(mMockContext, mTestLooper.getLooper());
2106         mockDeviceConfigAll();
2107         startUser(gameManagerService, USER_ID_1);
2108         mockModifyGameModeGranted();
2109 
2110         IGameModeListener mockListener = Mockito.mock(IGameModeListener.class);
2111         IBinder binder = Mockito.mock(IBinder.class);
2112         when(mockListener.asBinder()).thenReturn(binder);
2113         gameManagerService.addGameModeListener(mockListener);
2114         verify(binder).linkToDeath(mDeathRecipientCaptor.capture(), anyInt());
2115 
2116         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
2117         verify(mockListener).onGameModeChanged(mPackageName, GameManager.GAME_MODE_STANDARD,
2118                 GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
2119         reset(mockListener);
2120         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
2121         verify(mockListener).onGameModeChanged(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
2122                 GameManager.GAME_MODE_BATTERY, USER_ID_1);
2123         reset(mockListener);
2124 
2125         mDeathRecipientCaptor.getValue().binderDied();
2126         verify(binder).unlinkToDeath(eq(mDeathRecipientCaptor.getValue()), anyInt());
2127         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_CUSTOM, USER_ID_1);
2128         verify(mockListener, never()).onGameModeChanged(anyString(), anyInt(), anyInt(), anyInt());
2129     }
2130 
2131     @Test
testRemoveGameModeListener()2132     public void testRemoveGameModeListener() throws RemoteException {
2133         GameManagerService gameManagerService =
2134                 new GameManagerService(mMockContext, mTestLooper.getLooper());
2135         mockDeviceConfigAll();
2136         startUser(gameManagerService, USER_ID_1);
2137         mockModifyGameModeGranted();
2138 
2139         IGameModeListener mockListener = Mockito.mock(IGameModeListener.class);
2140         IBinder binder = Mockito.mock(IBinder.class);
2141         when(mockListener.asBinder()).thenReturn(binder);
2142 
2143         gameManagerService.addGameModeListener(mockListener);
2144         gameManagerService.removeGameModeListener(mockListener);
2145         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
2146         verify(mockListener, never()).onGameModeChanged(anyString(), anyInt(), anyInt(), anyInt());
2147     }
2148 
deleteFolder(File folder)2149     private static void deleteFolder(File folder) {
2150         File[] files = folder.listFiles();
2151         if (files != null) {
2152             for (File file : files) {
2153                 deleteFolder(file);
2154             }
2155         }
2156         folder.delete();
2157     }
2158 
2159     @Test
testResetGamePowerMode()2160     public void testResetGamePowerMode() {
2161         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2162         gameManagerService.onBootCompleted();
2163         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, false);
2164         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, false);
2165     }
2166 
2167     @Test
testNotifyGraphicsEnvironmentSetup()2168     public void testNotifyGraphicsEnvironmentSetup() {
2169         String configString = "mode=2,loadingBoost=2000";
2170         when(DeviceConfig.getProperty(anyString(), anyString()))
2171                 .thenReturn(configString);
2172         mockModifyGameModeGranted();
2173         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2174         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
2175         gameManagerService.notifyGraphicsEnvironmentSetup(mPackageName, USER_ID_1);
2176         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, true);
2177         reset(mMockPowerManager);
2178         assertTrue(gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
2179         mTestLooper.moveTimeForward(2000);
2180         mTestLooper.dispatchAll();
2181         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, false);
2182     }
2183 
2184     @Test
testNotifyGraphicsEnvironmentSetup_outOfBoundBoostValue()2185     public void testNotifyGraphicsEnvironmentSetup_outOfBoundBoostValue() {
2186         String configString = "mode=2,loadingBoost=0:mode=3,loadingBoost=7000";
2187         when(DeviceConfig.getProperty(anyString(), anyString()))
2188                 .thenReturn(configString);
2189         mockModifyGameModeGranted();
2190         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2191         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
2192         gameManagerService.notifyGraphicsEnvironmentSetup(mPackageName, USER_ID_1);
2193         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, true);
2194         reset(mMockPowerManager);
2195         assertTrue(gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
2196         mTestLooper.moveTimeForward(100);
2197         mTestLooper.dispatchAll();
2198         // 0 loading boost value should still trigger max timeout
2199         verify(mMockPowerManager, never()).setPowerMode(anyInt(), anyBoolean());
2200         assertTrue(gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
2201         mTestLooper.moveTimeForward(LOADING_BOOST_MAX_DURATION);
2202         mTestLooper.dispatchAll();
2203         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, false);
2204         reset(mMockPowerManager);
2205         assertFalse(gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
2206 
2207         // 7000 loading boost value should exceed the max timeout of 5s and be bounded
2208         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY, USER_ID_1);
2209         gameManagerService.notifyGraphicsEnvironmentSetup(mPackageName, USER_ID_1);
2210         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, true);
2211         reset(mMockPowerManager);
2212         assertTrue(gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
2213         mTestLooper.moveTimeForward(LOADING_BOOST_MAX_DURATION);
2214         mTestLooper.dispatchAll();
2215         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, false);
2216         assertFalse(gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
2217     }
2218 
2219     @Test
testNotifyGraphicsEnvironmentSetup_noDeviceConfig()2220     public void testNotifyGraphicsEnvironmentSetup_noDeviceConfig() {
2221         mockDeviceConfigNone();
2222         mockModifyGameModeGranted();
2223         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2224         gameManagerService.notifyGraphicsEnvironmentSetup(mPackageName, USER_ID_1);
2225         verify(mMockPowerManager, never()).setPowerMode(anyInt(), anyBoolean());
2226         assertFalse(gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
2227     }
2228 
2229     @Test
testNotifyGraphicsEnvironmentSetup_noLoadingBoostValue()2230     public void testNotifyGraphicsEnvironmentSetup_noLoadingBoostValue() {
2231         mockDeviceConfigAll();
2232         mockModifyGameModeGranted();
2233         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2234         gameManagerService.notifyGraphicsEnvironmentSetup(mPackageName, USER_ID_1);
2235         verify(mMockPowerManager, never()).setPowerMode(anyInt(), anyBoolean());
2236         assertFalse(gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
2237     }
2238 
2239     @Test
testNotifyGraphicsEnvironmentSetup_nonGame()2240     public void testNotifyGraphicsEnvironmentSetup_nonGame() throws Exception {
2241         String configString = "mode=2,loadingBoost=2000";
2242         when(DeviceConfig.getProperty(anyString(), anyString()))
2243                 .thenReturn(configString);
2244         mockModifyGameModeGranted();
2245         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_IMAGE);
2246         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2247         gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
2248         assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
2249                 gameManagerService.getGameMode(mPackageName, USER_ID_1));
2250         gameManagerService.notifyGraphicsEnvironmentSetup(mPackageName, USER_ID_1);
2251         verify(mMockPowerManager, never()).setPowerMode(anyInt(), anyBoolean());
2252         assertFalse(gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
2253     }
2254 
2255     @Test
testNotifyGraphicsEnvironmentSetup_differentApp()2256     public void testNotifyGraphicsEnvironmentSetup_differentApp() throws Exception {
2257         String configString = "mode=2,loadingBoost=2000";
2258         when(DeviceConfig.getProperty(anyString(), anyString()))
2259                 .thenReturn(configString);
2260         mockModifyGameModeGranted();
2261         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2262         String someGamePkg = "some.game";
2263         mockAppCategory(someGamePkg, ApplicationInfo.CATEGORY_GAME);
2264         when(mMockPackageManager.getPackageUidAsUser(someGamePkg, USER_ID_1)).thenReturn(
2265                 DEFAULT_PACKAGE_UID + 1);
2266         gameManagerService.setGameMode(someGamePkg, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
2267         assertEquals(GameManager.GAME_MODE_PERFORMANCE,
2268                 gameManagerService.getGameMode(someGamePkg, USER_ID_1));
2269         gameManagerService.notifyGraphicsEnvironmentSetup(someGamePkg, USER_ID_1);
2270         verify(mMockPowerManager, never()).setPowerMode(anyInt(), anyBoolean());
2271         assertFalse(gameManagerService.mHandler.hasMessages(CANCEL_GAME_LOADING_MODE));
2272     }
2273 
2274     @Test
testGetInterventionList_permissionDenied()2275     public void testGetInterventionList_permissionDenied() throws Exception {
2276         String configString = "mode=2,downscaleFactor=0.5";
2277         when(DeviceConfig.getProperty(anyString(), anyString()))
2278                 .thenReturn(configString);
2279         mockQueryAllPackageDenied();
2280         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2281         assertThrows(SecurityException.class,
2282                 () -> gameManagerService.getInterventionList(mPackageName, USER_ID_1));
2283 
2284         mockQueryAllPackageGranted();
2285         String expectedInterventionListOutput = "\n[Name:" + mPackageName
2286                  + " Modes: {2=[Game Mode:2,Scaling:0.5,Use Angle:false,"
2287                  + "Fps:,Loading Boost Duration:-1]}]";
2288         assertEquals(expectedInterventionListOutput,
2289                 gameManagerService.getInterventionList(mPackageName, USER_ID_1));
2290     }
2291 
2292     @Test
testGamePowerMode_gamePackage()2293     public void testGamePowerMode_gamePackage() throws Exception {
2294         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2295         String[] packages = {mPackageName};
2296         when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages);
2297         gameManagerService.mUidObserver.onUidStateChanged(
2298                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TOP, 0, 0);
2299         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, true);
2300     }
2301 
2302     @Test
testGamePowerMode_twoGames()2303     public void testGamePowerMode_twoGames() throws Exception {
2304         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2305         String[] packages1 = {mPackageName};
2306         when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages1);
2307         String someGamePkg = "some.game";
2308         String[] packages2 = {someGamePkg};
2309         int somePackageId = DEFAULT_PACKAGE_UID + 1;
2310         when(mMockPackageManager.getPackagesForUid(somePackageId)).thenReturn(packages2);
2311         HashMap<Integer, Boolean> powerState = new HashMap<>();
2312         doAnswer(inv -> powerState.put(inv.getArgument(0), inv.getArgument(1)))
2313                 .when(mMockPowerManager).setPowerMode(anyInt(), anyBoolean());
2314         gameManagerService.mUidObserver.onUidStateChanged(
2315                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TOP, 0, 0);
2316         assertTrue(powerState.get(Mode.GAME));
2317         gameManagerService.mUidObserver.onUidStateChanged(
2318                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0);
2319         gameManagerService.mUidObserver.onUidStateChanged(
2320                 somePackageId, ActivityManager.PROCESS_STATE_TOP, 0, 0);
2321         assertTrue(powerState.get(Mode.GAME));
2322         gameManagerService.mUidObserver.onUidStateChanged(
2323                 somePackageId, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0);
2324         assertFalse(powerState.get(Mode.GAME));
2325     }
2326 
2327     @Test
testGamePowerMode_twoGamesOverlap()2328     public void testGamePowerMode_twoGamesOverlap() throws Exception {
2329         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2330         String[] packages1 = {mPackageName};
2331         when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages1);
2332         String someGamePkg = "some.game";
2333         String[] packages2 = {someGamePkg};
2334         int somePackageId = DEFAULT_PACKAGE_UID + 1;
2335         when(mMockPackageManager.getPackagesForUid(somePackageId)).thenReturn(packages2);
2336         gameManagerService.mUidObserver.onUidStateChanged(
2337                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TOP, 0, 0);
2338         gameManagerService.mUidObserver.onUidStateChanged(
2339                 somePackageId, ActivityManager.PROCESS_STATE_TOP, 0, 0);
2340         gameManagerService.mUidObserver.onUidStateChanged(
2341                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0);
2342         gameManagerService.mUidObserver.onUidStateChanged(
2343                 somePackageId, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0);
2344         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, true);
2345         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, false);
2346     }
2347 
2348     @Test
testGamePowerMode_released()2349     public void testGamePowerMode_released() throws Exception {
2350         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2351         String[] packages = {mPackageName};
2352         when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages);
2353         gameManagerService.mUidObserver.onUidStateChanged(
2354                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TOP, 0, 0);
2355         gameManagerService.mUidObserver.onUidStateChanged(
2356                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0);
2357         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, false);
2358     }
2359 
2360     @Test
testGamePowerMode_noPackage()2361     public void testGamePowerMode_noPackage() throws Exception {
2362         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2363         String[] packages = {};
2364         when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages);
2365         gameManagerService.mUidObserver.onUidStateChanged(
2366                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0);
2367         verify(mMockPowerManager, times(0)).setPowerMode(Mode.GAME, true);
2368     }
2369 
2370     @Test
testGamePowerMode_notAGamePackage()2371     public void testGamePowerMode_notAGamePackage() throws Exception {
2372         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_IMAGE);
2373         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2374         String[] packages = {"someapp"};
2375         when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages);
2376         gameManagerService.mUidObserver.onUidStateChanged(
2377                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0);
2378         verify(mMockPowerManager, times(0)).setPowerMode(Mode.GAME, true);
2379     }
2380 
2381     @Test
testGamePowerMode_notAGamePackageNotReleased()2382     public void testGamePowerMode_notAGamePackageNotReleased() throws Exception {
2383         mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_IMAGE);
2384         GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1);
2385         String[] packages = {"someapp"};
2386         when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages);
2387         gameManagerService.mUidObserver.onUidStateChanged(
2388                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0);
2389         gameManagerService.mUidObserver.onUidStateChanged(
2390                 DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0);
2391         verify(mMockPowerManager, times(0)).setPowerMode(Mode.GAME, false);
2392     }
2393 }
2394