Loading services/core/java/com/android/server/app/GameManagerService.java +79 −28 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.app.GameManager.GameMode; import android.app.GameModeInfo; import android.app.GameState; import android.app.IGameManagerService; import android.app.IUidObserver; import android.app.compat.PackageOverride; import android.content.BroadcastReceiver; import android.content.Context; Loading Loading @@ -118,6 +119,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * Service to manage game related features. Loading Loading @@ -171,40 +173,19 @@ public final class GameManagerService extends IGameManagerService.Stub { private final ArrayMap<String, GamePackageConfiguration> mOverrideConfigs = new ArrayMap<>(); @Nullable private final GameServiceController mGameServiceController; private final Object mUidObserverLock = new Object(); @VisibleForTesting @Nullable final UidObserver mUidObserver; @GuardedBy("mUidObserverLock") private final Set<Integer> mForegroundGameUids = new HashSet<>(); public GameManagerService(Context context) { this(context, createServiceThread().getLooper()); } GameManagerService(Context context, Looper looper) { mContext = context; mHandler = new SettingsHandler(looper); mPackageManager = mContext.getPackageManager(); mUserManager = mContext.getSystemService(UserManager.class); mPlatformCompat = IPlatformCompat.Stub.asInterface( ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); mSystemDir = new File(Environment.getDataDirectory(), "system"); mSystemDir.mkdirs(); FileUtils.setPermissions(mSystemDir.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH, -1, -1); mGameModeInterventionListFile = new AtomicFile(new File(mSystemDir, GAME_MODE_INTERVENTION_LIST_FILE_NAME)); FileUtils.setPermissions(mGameModeInterventionListFile.getBaseFile().getAbsolutePath(), FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP, -1, -1); if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_GAME_SERVICE)) { mGameServiceController = new GameServiceController( context, BackgroundThread.getExecutor(), new GameServiceProviderSelectorImpl( context.getResources(), context.getPackageManager()), new GameServiceProviderInstanceFactoryImpl(context)); } else { mGameServiceController = null; } this(context, looper, Environment.getDataDirectory()); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) Loading Loading @@ -237,6 +218,14 @@ public final class GameManagerService extends IGameManagerService.Stub { } else { mGameServiceController = null; } mUidObserver = new UidObserver(); try { ActivityManager.getService().registerUidObserver(mUidObserver, ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE, ActivityManager.PROCESS_STATE_UNKNOWN, null); } catch (RemoteException e) { Slog.w(TAG, "Could not register UidObserver"); } } @Override Loading Loading @@ -1874,4 +1863,66 @@ public final class GameManagerService extends IGameManagerService.Stub { * load dynamic library for frame rate overriding JNI calls */ private static native void nativeSetOverrideFrameRate(int uid, float frameRate); final class UidObserver extends IUidObserver.Stub { @Override public void onUidIdle(int uid, boolean disabled) {} @Override public void onUidGone(int uid, boolean disabled) { synchronized (mUidObserverLock) { disableGameMode(uid); } } @Override public void onUidActive(int uid) {} @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { synchronized (mUidObserverLock) { if (ActivityManager.isProcStateBackground(procState)) { disableGameMode(uid); return; } final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); if (packages == null || packages.length == 0) { return; } final int userId = mContext.getUserId(); if (!Arrays.stream(packages).anyMatch(p -> isPackageGame(p, userId))) { return; } if (mForegroundGameUids.isEmpty()) { Slog.v(TAG, "Game power mode ON (process state was changed to foreground)"); mPowerManagerInternal.setPowerMode(Mode.GAME, true); } mForegroundGameUids.add(uid); } } private void disableGameMode(int uid) { synchronized (mUidObserverLock) { if (!mForegroundGameUids.contains(uid)) { return; } mForegroundGameUids.remove(uid); if (!mForegroundGameUids.isEmpty()) { return; } Slog.v(TAG, "Game power mode OFF (process remomved or state changed to background)"); mPowerManagerInternal.setPowerMode(Mode.GAME, false); } } @Override public void onUidCachedChanged(int uid, boolean cached) {} @Override public void onUidProcAdjChanged(int uid) {} } } services/tests/mockingservicestests/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ <!-- needed by TrustManagerServiceTest to access LockSettings' secure storage --> <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" /> <!-- needed by GameManagerServiceTest because GameManager creates a UidObserver --> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> <application android:testOnly="true" android:debuggable="true"> <uses-library android:name="android.test.runner" /> Loading services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java +129 −0 Original line number Diff line number Diff line Loading @@ -29,13 +29,16 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.Manifest; import android.app.ActivityManager; import android.app.GameManager; import android.app.GameModeInfo; import android.app.GameState; Loading Loading @@ -203,6 +206,23 @@ public class GameManagerServiceTests { LocalServices.addService(PowerManagerInternal.class, mMockPowerManager); } private void mockAppCategory(String packageName, @ApplicationInfo.Category int category) throws Exception { reset(mMockPackageManager); final ApplicationInfo gameApplicationInfo = new ApplicationInfo(); gameApplicationInfo.category = category; gameApplicationInfo.packageName = packageName; final PackageInfo pi = new PackageInfo(); pi.packageName = packageName; pi.applicationInfo = gameApplicationInfo; final List<PackageInfo> packages = new ArrayList<>(); packages.add(pi); when(mMockPackageManager.getInstalledPackagesAsUser(anyInt(), anyInt())) .thenReturn(packages); when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(gameApplicationInfo); } @After public void tearDown() throws Exception { LocalServices.removeServiceForTest(PowerManagerInternal.class); Loading Loading @@ -1597,4 +1617,113 @@ public class GameManagerServiceTests { ArgumentMatchers.eq(DEFAULT_PACKAGE_UID), ArgumentMatchers.eq(0.0f)); } private GameManagerService createServiceAndStartUser(int userId) { GameManagerService gameManagerService = new GameManagerService(mMockContext, mTestLooper.getLooper()); startUser(gameManagerService, userId); return gameManagerService; } @Test public void testGamePowerMode_gamePackage() throws Exception { GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages = {mPackageName}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, true); } @Test public void testGamePowerMode_twoGames() throws Exception { GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages1 = {mPackageName}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages1); String someGamePkg = "some.game"; String[] packages2 = {someGamePkg}; int somePackageId = DEFAULT_PACKAGE_UID + 1; when(mMockPackageManager.getPackagesForUid(somePackageId)).thenReturn(packages2); HashMap<Integer, Boolean> powerState = new HashMap<>(); doAnswer(inv -> powerState.put(inv.getArgument(0), inv.getArgument(1))) .when(mMockPowerManager).setPowerMode(anyInt(), anyBoolean()); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); assertTrue(powerState.get(Mode.GAME)); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( somePackageId, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); assertTrue(powerState.get(Mode.GAME)); gameManagerService.mUidObserver.onUidStateChanged( somePackageId, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); assertFalse(powerState.get(Mode.GAME)); } @Test public void testGamePowerMode_twoGamesOverlap() throws Exception { GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages1 = {mPackageName}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages1); String someGamePkg = "some.game"; String[] packages2 = {someGamePkg}; int somePackageId = DEFAULT_PACKAGE_UID + 1; when(mMockPackageManager.getPackagesForUid(somePackageId)).thenReturn(packages2); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( somePackageId, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( somePackageId, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, true); verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, false); } @Test public void testGamePowerMode_released() throws Exception { GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages = {mPackageName}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, false); } @Test public void testGamePowerMode_noPackage() throws Exception { GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages = {}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); verify(mMockPowerManager, times(0)).setPowerMode(Mode.GAME, true); } @Test public void testGamePowerMode_notAGamePackage() throws Exception { mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_IMAGE); GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages = {"someapp"}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); verify(mMockPowerManager, times(0)).setPowerMode(Mode.GAME, true); } @Test public void testGamePowerMode_notAGamePackageNotReleased() throws Exception { mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_IMAGE); GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages = {"someapp"}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); verify(mMockPowerManager, times(0)).setPowerMode(Mode.GAME, false); } } Loading
services/core/java/com/android/server/app/GameManagerService.java +79 −28 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.app.GameManager.GameMode; import android.app.GameModeInfo; import android.app.GameState; import android.app.IGameManagerService; import android.app.IUidObserver; import android.app.compat.PackageOverride; import android.content.BroadcastReceiver; import android.content.Context; Loading Loading @@ -118,6 +119,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * Service to manage game related features. Loading Loading @@ -171,40 +173,19 @@ public final class GameManagerService extends IGameManagerService.Stub { private final ArrayMap<String, GamePackageConfiguration> mOverrideConfigs = new ArrayMap<>(); @Nullable private final GameServiceController mGameServiceController; private final Object mUidObserverLock = new Object(); @VisibleForTesting @Nullable final UidObserver mUidObserver; @GuardedBy("mUidObserverLock") private final Set<Integer> mForegroundGameUids = new HashSet<>(); public GameManagerService(Context context) { this(context, createServiceThread().getLooper()); } GameManagerService(Context context, Looper looper) { mContext = context; mHandler = new SettingsHandler(looper); mPackageManager = mContext.getPackageManager(); mUserManager = mContext.getSystemService(UserManager.class); mPlatformCompat = IPlatformCompat.Stub.asInterface( ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); mSystemDir = new File(Environment.getDataDirectory(), "system"); mSystemDir.mkdirs(); FileUtils.setPermissions(mSystemDir.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH, -1, -1); mGameModeInterventionListFile = new AtomicFile(new File(mSystemDir, GAME_MODE_INTERVENTION_LIST_FILE_NAME)); FileUtils.setPermissions(mGameModeInterventionListFile.getBaseFile().getAbsolutePath(), FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP, -1, -1); if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_GAME_SERVICE)) { mGameServiceController = new GameServiceController( context, BackgroundThread.getExecutor(), new GameServiceProviderSelectorImpl( context.getResources(), context.getPackageManager()), new GameServiceProviderInstanceFactoryImpl(context)); } else { mGameServiceController = null; } this(context, looper, Environment.getDataDirectory()); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) Loading Loading @@ -237,6 +218,14 @@ public final class GameManagerService extends IGameManagerService.Stub { } else { mGameServiceController = null; } mUidObserver = new UidObserver(); try { ActivityManager.getService().registerUidObserver(mUidObserver, ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE, ActivityManager.PROCESS_STATE_UNKNOWN, null); } catch (RemoteException e) { Slog.w(TAG, "Could not register UidObserver"); } } @Override Loading Loading @@ -1874,4 +1863,66 @@ public final class GameManagerService extends IGameManagerService.Stub { * load dynamic library for frame rate overriding JNI calls */ private static native void nativeSetOverrideFrameRate(int uid, float frameRate); final class UidObserver extends IUidObserver.Stub { @Override public void onUidIdle(int uid, boolean disabled) {} @Override public void onUidGone(int uid, boolean disabled) { synchronized (mUidObserverLock) { disableGameMode(uid); } } @Override public void onUidActive(int uid) {} @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { synchronized (mUidObserverLock) { if (ActivityManager.isProcStateBackground(procState)) { disableGameMode(uid); return; } final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); if (packages == null || packages.length == 0) { return; } final int userId = mContext.getUserId(); if (!Arrays.stream(packages).anyMatch(p -> isPackageGame(p, userId))) { return; } if (mForegroundGameUids.isEmpty()) { Slog.v(TAG, "Game power mode ON (process state was changed to foreground)"); mPowerManagerInternal.setPowerMode(Mode.GAME, true); } mForegroundGameUids.add(uid); } } private void disableGameMode(int uid) { synchronized (mUidObserverLock) { if (!mForegroundGameUids.contains(uid)) { return; } mForegroundGameUids.remove(uid); if (!mForegroundGameUids.isEmpty()) { return; } Slog.v(TAG, "Game power mode OFF (process remomved or state changed to background)"); mPowerManagerInternal.setPowerMode(Mode.GAME, false); } } @Override public void onUidCachedChanged(int uid, boolean cached) {} @Override public void onUidProcAdjChanged(int uid) {} } }
services/tests/mockingservicestests/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ <!-- needed by TrustManagerServiceTest to access LockSettings' secure storage --> <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" /> <!-- needed by GameManagerServiceTest because GameManager creates a UidObserver --> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> <application android:testOnly="true" android:debuggable="true"> <uses-library android:name="android.test.runner" /> Loading
services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java +129 −0 Original line number Diff line number Diff line Loading @@ -29,13 +29,16 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.Manifest; import android.app.ActivityManager; import android.app.GameManager; import android.app.GameModeInfo; import android.app.GameState; Loading Loading @@ -203,6 +206,23 @@ public class GameManagerServiceTests { LocalServices.addService(PowerManagerInternal.class, mMockPowerManager); } private void mockAppCategory(String packageName, @ApplicationInfo.Category int category) throws Exception { reset(mMockPackageManager); final ApplicationInfo gameApplicationInfo = new ApplicationInfo(); gameApplicationInfo.category = category; gameApplicationInfo.packageName = packageName; final PackageInfo pi = new PackageInfo(); pi.packageName = packageName; pi.applicationInfo = gameApplicationInfo; final List<PackageInfo> packages = new ArrayList<>(); packages.add(pi); when(mMockPackageManager.getInstalledPackagesAsUser(anyInt(), anyInt())) .thenReturn(packages); when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(gameApplicationInfo); } @After public void tearDown() throws Exception { LocalServices.removeServiceForTest(PowerManagerInternal.class); Loading Loading @@ -1597,4 +1617,113 @@ public class GameManagerServiceTests { ArgumentMatchers.eq(DEFAULT_PACKAGE_UID), ArgumentMatchers.eq(0.0f)); } private GameManagerService createServiceAndStartUser(int userId) { GameManagerService gameManagerService = new GameManagerService(mMockContext, mTestLooper.getLooper()); startUser(gameManagerService, userId); return gameManagerService; } @Test public void testGamePowerMode_gamePackage() throws Exception { GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages = {mPackageName}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, true); } @Test public void testGamePowerMode_twoGames() throws Exception { GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages1 = {mPackageName}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages1); String someGamePkg = "some.game"; String[] packages2 = {someGamePkg}; int somePackageId = DEFAULT_PACKAGE_UID + 1; when(mMockPackageManager.getPackagesForUid(somePackageId)).thenReturn(packages2); HashMap<Integer, Boolean> powerState = new HashMap<>(); doAnswer(inv -> powerState.put(inv.getArgument(0), inv.getArgument(1))) .when(mMockPowerManager).setPowerMode(anyInt(), anyBoolean()); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); assertTrue(powerState.get(Mode.GAME)); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( somePackageId, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); assertTrue(powerState.get(Mode.GAME)); gameManagerService.mUidObserver.onUidStateChanged( somePackageId, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); assertFalse(powerState.get(Mode.GAME)); } @Test public void testGamePowerMode_twoGamesOverlap() throws Exception { GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages1 = {mPackageName}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages1); String someGamePkg = "some.game"; String[] packages2 = {someGamePkg}; int somePackageId = DEFAULT_PACKAGE_UID + 1; when(mMockPackageManager.getPackagesForUid(somePackageId)).thenReturn(packages2); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( somePackageId, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( somePackageId, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, true); verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, false); } @Test public void testGamePowerMode_released() throws Exception { GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages = {mPackageName}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME, false); } @Test public void testGamePowerMode_noPackage() throws Exception { GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages = {}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); verify(mMockPowerManager, times(0)).setPowerMode(Mode.GAME, true); } @Test public void testGamePowerMode_notAGamePackage() throws Exception { mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_IMAGE); GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages = {"someapp"}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); verify(mMockPowerManager, times(0)).setPowerMode(Mode.GAME, true); } @Test public void testGamePowerMode_notAGamePackageNotReleased() throws Exception { mockAppCategory(mPackageName, ApplicationInfo.CATEGORY_IMAGE); GameManagerService gameManagerService = createServiceAndStartUser(USER_ID_1); String[] packages = {"someapp"}; when(mMockPackageManager.getPackagesForUid(DEFAULT_PACKAGE_UID)).thenReturn(packages); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0, 0); gameManagerService.mUidObserver.onUidStateChanged( DEFAULT_PACKAGE_UID, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0); verify(mMockPowerManager, times(0)).setPowerMode(Mode.GAME, false); } }