diff --git a/core/api/current.txt b/core/api/current.txt index f9048056b7489..2472eac3d0557 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -5312,6 +5312,14 @@ package android.app { field @Deprecated public static final int TRANSIT_UNSET = -1; // 0xffffffff } + public final class GameManager { + method public int getGameMode(); + field public static final int GAME_MODE_BATTERY = 3; // 0x3 + field public static final int GAME_MODE_PERFORMANCE = 2; // 0x2 + field public static final int GAME_MODE_STANDARD = 1; // 0x1 + field public static final int GAME_MODE_UNSUPPORTED = 0; // 0x0 + } + public class Instrumentation { ctor public Instrumentation(); method public android.os.TestLooperManager acquireLooperManager(android.os.Looper); @@ -10487,6 +10495,7 @@ package android.content { field public static final String EUICC_SERVICE = "euicc"; field public static final String FILE_INTEGRITY_SERVICE = "file_integrity"; field public static final String FINGERPRINT_SERVICE = "fingerprint"; + field public static final String GAME_SERVICE = "game"; field public static final String HARDWARE_PROPERTIES_SERVICE = "hardware_properties"; field public static final String INPUT_METHOD_SERVICE = "input_method"; field public static final String INPUT_SERVICE = "input"; diff --git a/core/api/test-current.txt b/core/api/test-current.txt index b41f9702c7c13..a57d824125377 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -259,6 +259,10 @@ package android.app { method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void stopDream(); } + public final class GameManager { + method @RequiresPermission("android.permission.MANAGE_GAME_MODE") public void setGameMode(@NonNull String, int); + } + public abstract class HomeVisibilityListener { ctor public HomeVisibilityListener(); method public abstract void onHomeVisibilityChanged(boolean); diff --git a/core/java/android/app/GameManager.java b/core/java/android/app/GameManager.java index ac1fa1ec68378..47de04078b457 100644 --- a/core/java/android/app/GameManager.java +++ b/core/java/android/app/GameManager.java @@ -18,8 +18,11 @@ package android.app; import android.Manifest; import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemService; +import android.annotation.TestApi; import android.annotation.UserHandleAware; import android.content.Context; import android.os.Handler; @@ -27,57 +30,87 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; -import com.android.internal.annotations.VisibleForTesting; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * The GameManager allows system apps to modify and query the game mode of apps. - * - * @hide */ -@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @SystemService(Context.GAME_SERVICE) public final class GameManager { private static final String TAG = "GameManager"; - private final Context mContext; + private final @Nullable Context mContext; private final IGameManagerService mService; - @IntDef(flag = false, prefix = { "GAME_MODE_" }, value = { + /** @hide */ + @IntDef(flag = false, prefix = {"GAME_MODE_"}, value = { GAME_MODE_UNSUPPORTED, // 0 GAME_MODE_STANDARD, // 1 GAME_MODE_PERFORMANCE, // 2 GAME_MODE_BATTERY, // 3 }) @Retention(RetentionPolicy.SOURCE) - public @interface GameMode {} + public @interface GameMode { + } + /** + * Game mode is not supported for this application. + */ public static final int GAME_MODE_UNSUPPORTED = 0; + + /** + * Standard game mode means the platform will use the game's default + * performance characteristics. + */ public static final int GAME_MODE_STANDARD = 1; + + /** + * Performance game mode maximizes the game's performance. + *
+ * This game mode is highly likely to increase battery consumption. + */ public static final int GAME_MODE_PERFORMANCE = 2; + + /** + * Battery game mode will save battery and give longer game play time. + */ public static final int GAME_MODE_BATTERY = 3; - public GameManager(Context context, Handler handler) throws ServiceNotFoundException { + GameManager(Context context, Handler handler) throws ServiceNotFoundException { mContext = context; mService = IGameManagerService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.GAME_SERVICE)); } - @VisibleForTesting - public GameManager(Context context, IGameManagerService gameManagerService) { - mContext = context; - mService = gameManagerService; + /** + * Return the user selected game mode for this application. + *
+ * An application can use android:isGame="true" or
+ * android:appCategory="game" to indicate that the application is a game. If an
+ * application is not a game, always return {@link #GAME_MODE_UNSUPPORTED}.
+ *
+ * Developers should call this API every time the application is resumed. + */ + public @GameMode int getGameMode() { + try { + return mService.getGameMode(mContext.getPackageName(), mContext.getUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** - * Returns the game mode for the given package. + * Gets the game mode for the given package. + *
+ * The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}. + * + * @hide */ @UserHandleAware @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE) - public @GameMode int getGameMode(String packageName) { + public @GameMode int getGameMode(@NonNull String packageName) { try { return mService.getGameMode(packageName, mContext.getUserId()); } catch (RemoteException e) { @@ -87,10 +120,15 @@ public final class GameManager { /** * Sets the game mode for the given package. + *
+ * The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}.
+ *
+ * @hide
*/
+ @TestApi
@UserHandleAware
@RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
- public void setGameMode(String packageName, @GameMode int gameMode) {
+ public void setGameMode(@NonNull String packageName, @GameMode int gameMode) {
try {
mService.setGameMode(packageName, gameMode, mContext.getUserId());
} catch (RemoteException e) {
diff --git a/core/java/android/app/IGameManager.aidl b/core/java/android/app/IGameManager.aidl
new file mode 100644
index 0000000000000..3730de82f94a8
--- /dev/null
+++ b/core/java/android/app/IGameManager.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+/**
+ * Interface used to control Game Manager modes.
+ * @hide
+ */
+interface IGameManager {
+ /**
+ * Return the current Game Mode for the calling package.
+ */
+ int getGameMode();
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 48754cccfe0d7..30b3d43ab23e2 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5523,8 +5523,6 @@ public abstract class Context {
* {@link GameManager}.
*
* @see #getSystemService(String)
- *
- * @hide
*/
public static final String GAME_SERVICE = "game";
diff --git a/core/tests/GameManagerTests/Android.bp b/core/tests/GameManagerTests/Android.bp
index 2789e9f316d1d..8c5d6d5a76a1f 100644
--- a/core/tests/GameManagerTests/Android.bp
+++ b/core/tests/GameManagerTests/Android.bp
@@ -29,6 +29,7 @@ android_test {
"androidx.test.rules",
"frameworks-base-testutils",
"junit",
+ "platform-test-annotations",
"truth-prebuilt",
],
libs: ["android.test.runner"],
diff --git a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
index 8f50051725cd0..0c964114a76ea 100644
--- a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
+++ b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java
@@ -16,13 +16,13 @@
package android.app;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static junit.framework.Assert.assertEquals;
-import android.app.GameManager.GameMode;
-import android.util.ArrayMap;
-import android.util.Pair;
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
-import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -35,22 +35,43 @@ import org.junit.runner.RunWith;
*/
@RunWith(AndroidJUnit4.class)
@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";
- private TestGameManagerService mService;
+ protected Context mContext;
private GameManager mGameManager;
+ private String mPackageName;
@Before
public void setUp() {
- mService = new TestGameManagerService();
- mGameManager = new GameManager(
- InstrumentationRegistry.getContext(), mService);
+ mContext = getInstrumentation().getContext();
+ mGameManager = mContext.getSystemService(GameManager.class);
+ mPackageName = mContext.getPackageName();
+
+ // 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
- public void testGameModeGetterSetter() {
+ public void testPublicApiGameModeGetterSetter() {
+ assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
+ mGameManager.getGameMode());
+
+ mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD);
+ assertEquals(GameManager.GAME_MODE_STANDARD,
+ mGameManager.getGameMode());
+
+ mGameManager.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE);
+ assertEquals(GameManager.GAME_MODE_PERFORMANCE,
+ mGameManager.getGameMode());
+ }
+
+ @Test
+ public void testPrivilegedGameModeGetterSetter() {
assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
mGameManager.getGameMode(PACKAGE_NAME_0));
@@ -62,22 +83,4 @@ public final class GameManagerTests {
assertEquals(GameManager.GAME_MODE_PERFORMANCE,
mGameManager.getGameMode(PACKAGE_NAME_1));
}
-
- private final class TestGameManagerService extends IGameManagerService.Stub {
- private final ArrayMap