Merge "GameManagerService: Restrict get/set Game Mode to Games" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f9c119884a
@@ -19,7 +19,7 @@
|
||||
package="com.android.app.gamemanagertests"
|
||||
android:sharedUserId="android.uid.system" >
|
||||
|
||||
<application>
|
||||
<application android:appCategory="game">
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
|
||||
|
||||
@@ -37,9 +37,6 @@ import org.junit.runner.RunWith;
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
public final class GameManagerTests {
|
||||
private static final String PACKAGE_NAME_0 = "com.android.app0";
|
||||
private static final String PACKAGE_NAME_1 = "com.android.app1";
|
||||
|
||||
protected Context mContext;
|
||||
private GameManager mGameManager;
|
||||
private String mPackageName;
|
||||
@@ -52,8 +49,6 @@ public final class GameManagerTests {
|
||||
|
||||
// Reset the Game Mode for the test app, since it persists across invocations.
|
||||
mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_UNSUPPORTED);
|
||||
mGameManager.setGameMode(PACKAGE_NAME_0, GameManager.GAME_MODE_UNSUPPORTED);
|
||||
mGameManager.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_UNSUPPORTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -73,14 +68,14 @@ public final class GameManagerTests {
|
||||
@Test
|
||||
public void testPrivilegedGameModeGetterSetter() {
|
||||
assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
|
||||
mGameManager.getGameMode(PACKAGE_NAME_0));
|
||||
mGameManager.getGameMode(mPackageName));
|
||||
|
||||
mGameManager.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_STANDARD);
|
||||
mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD);
|
||||
assertEquals(GameManager.GAME_MODE_STANDARD,
|
||||
mGameManager.getGameMode(PACKAGE_NAME_1));
|
||||
mGameManager.getGameMode(mPackageName));
|
||||
|
||||
mGameManager.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_PERFORMANCE);
|
||||
mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE);
|
||||
assertEquals(GameManager.GAME_MODE_PERFORMANCE,
|
||||
mGameManager.getGameMode(PACKAGE_NAME_1));
|
||||
mGameManager.getGameMode(mPackageName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.app.GameManager;
|
||||
import android.app.GameManager.GameMode;
|
||||
import android.app.IGameManagerService;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Binder;
|
||||
import android.os.Environment;
|
||||
@@ -58,6 +59,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
static final int WRITE_SETTINGS_DELAY = 10 * 1000; // 10 seconds
|
||||
|
||||
private final Context mContext;
|
||||
private final PackageManager mPackageManager;
|
||||
private final Object mLock = new Object();
|
||||
private final Handler mHandler;
|
||||
@GuardedBy("mLock")
|
||||
@@ -70,6 +72,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
GameManagerService(Context context, Looper looper) {
|
||||
mContext = context;
|
||||
mHandler = new SettingsHandler(looper);
|
||||
mPackageManager = context.getPackageManager();
|
||||
}
|
||||
|
||||
class SettingsHandler extends Handler {
|
||||
@@ -171,9 +174,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
|
||||
private boolean isValidPackageName(String packageName) {
|
||||
final PackageManager pm = mContext.getPackageManager();
|
||||
try {
|
||||
return pm.getPackageUid(packageName, 0) == Binder.getCallingUid();
|
||||
return mPackageManager.getPackageUid(packageName, 0) == Binder.getCallingUid();
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
@@ -208,16 +210,36 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
@Override
|
||||
public @GameMode int getGameMode(String packageName, int userId)
|
||||
throws SecurityException {
|
||||
// TODO(b/178860939): Restrict to games only.
|
||||
|
||||
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
|
||||
Binder.getCallingUid(), userId, false, true, "getGameMode",
|
||||
"com.android.server.app.GameManagerService");
|
||||
|
||||
// Restrict to games only.
|
||||
try {
|
||||
final ApplicationInfo applicationInfo = mPackageManager
|
||||
.getApplicationInfoAsUser(packageName, PackageManager.MATCH_ALL, userId);
|
||||
if (applicationInfo.category != ApplicationInfo.CATEGORY_GAME) {
|
||||
Log.e(TAG, "Ignoring attempt to get the Game Mode for '" + packageName
|
||||
+ "' which is not categorized as a game: applicationInfo.flags = "
|
||||
+ applicationInfo.flags + ", category = " + applicationInfo.category);
|
||||
return GameManager.GAME_MODE_UNSUPPORTED;
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return GameManager.GAME_MODE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// This function handles two types of queries:
|
||||
// 1.) A normal, non-privileged app querying its own Game Mode.
|
||||
// 2.) A privileged system service querying the Game Mode of another package.
|
||||
// The least privileged case is a normal app performing a query, so check that first and
|
||||
// return a value if the package name is valid. Next, check if the caller has the necessary
|
||||
// permission and return a value. Do this check last, since it can throw an exception.
|
||||
if (isValidPackageName(packageName)) {
|
||||
return getGameModeFromSettings(packageName, userId);
|
||||
}
|
||||
|
||||
// Since the package name doesn't match, check the caller has the necessary permission.
|
||||
checkPermission(Manifest.permission.MANAGE_GAME_MODE);
|
||||
return getGameModeFromSettings(packageName, userId);
|
||||
}
|
||||
@@ -230,15 +252,28 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
@RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
|
||||
public void setGameMode(String packageName, @GameMode int gameMode, int userId)
|
||||
throws SecurityException {
|
||||
// TODO(b/178860939): Restrict to games only.
|
||||
|
||||
checkPermission(Manifest.permission.MANAGE_GAME_MODE);
|
||||
|
||||
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
|
||||
Binder.getCallingUid(), userId, false, true, "setGameMode",
|
||||
"com.android.server.app.GameManagerService");
|
||||
// Restrict to games only.
|
||||
try {
|
||||
final ApplicationInfo applicationInfo = mPackageManager
|
||||
.getApplicationInfoAsUser(packageName, PackageManager.MATCH_ALL, userId);
|
||||
if (applicationInfo.category != ApplicationInfo.CATEGORY_GAME) {
|
||||
Log.e(TAG, "Ignoring attempt to set the Game Mode for '" + packageName
|
||||
+ "' which is not categorized as a game: applicationInfo.flags = "
|
||||
+ applicationInfo.flags + ", category = " + applicationInfo.category);
|
||||
return;
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
|
||||
Binder.getCallingUid(), userId, false, true, "setGameMode",
|
||||
"com.android.server.app.GameManagerService");
|
||||
|
||||
if (!mSettings.containsKey(userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -49,14 +49,18 @@ public class GameManagerServiceTests {
|
||||
private static final int USER_ID_2 = 1002;
|
||||
|
||||
// Stolen from ConnectivityServiceTest.MockContext
|
||||
class MockContext extends ContextWrapper {
|
||||
static class MockContext extends ContextWrapper {
|
||||
private static final String TAG = "MockContext";
|
||||
|
||||
// Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
|
||||
private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
|
||||
|
||||
@Mock
|
||||
private final MockPackageManager mMockPackageManager;
|
||||
|
||||
MockContext(Context base) {
|
||||
super(base);
|
||||
mMockPackageManager = new MockPackageManager();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,6 +105,11 @@ public class GameManagerServiceTests {
|
||||
throw new SecurityException("[Test] permission denied: " + permission);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackageManager getPackageManager() {
|
||||
return mMockPackageManager;
|
||||
}
|
||||
}
|
||||
|
||||
@Mock
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user