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 android.app; 18 19 import android.Manifest; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.RequiresPermission; 24 import android.annotation.SystemApi; 25 import android.annotation.SystemService; 26 import android.annotation.TestApi; 27 import android.annotation.UserHandleAware; 28 import android.content.Context; 29 import android.os.Handler; 30 import android.os.RemoteException; 31 import android.os.ServiceManager; 32 import android.os.ServiceManager.ServiceNotFoundException; 33 34 import java.lang.annotation.Retention; 35 import java.lang.annotation.RetentionPolicy; 36 37 /** 38 * The GameManager allows system apps to modify and query the game mode of apps. 39 */ 40 @SystemService(Context.GAME_SERVICE) 41 public final class GameManager { 42 43 private static final String TAG = "GameManager"; 44 45 private final @Nullable Context mContext; 46 private final IGameManagerService mService; 47 48 /** @hide */ 49 @IntDef(flag = false, prefix = {"GAME_MODE_"}, value = { 50 GAME_MODE_UNSUPPORTED, // 0 51 GAME_MODE_STANDARD, // 1 52 GAME_MODE_PERFORMANCE, // 2 53 GAME_MODE_BATTERY, // 3 54 }) 55 @Retention(RetentionPolicy.SOURCE) 56 public @interface GameMode { 57 } 58 59 /** 60 * Game mode is not supported for this application. 61 */ 62 public static final int GAME_MODE_UNSUPPORTED = 0; 63 64 /** 65 * Standard game mode means the platform will use the game's default 66 * performance characteristics. 67 */ 68 public static final int GAME_MODE_STANDARD = 1; 69 70 /** 71 * Performance game mode maximizes the game's performance. 72 * <p> 73 * This game mode is highly likely to increase battery consumption. 74 */ 75 public static final int GAME_MODE_PERFORMANCE = 2; 76 77 /** 78 * Battery game mode will save battery and give longer game play time. 79 */ 80 public static final int GAME_MODE_BATTERY = 3; 81 GameManager(Context context, Handler handler)82 GameManager(Context context, Handler handler) throws ServiceNotFoundException { 83 mContext = context; 84 mService = IGameManagerService.Stub.asInterface( 85 ServiceManager.getServiceOrThrow(Context.GAME_SERVICE)); 86 } 87 88 /** 89 * Return the user selected game mode for this application. 90 * <p> 91 * An application can use <code>android:isGame="true"</code> or 92 * <code>android:appCategory="game"</code> to indicate that the application is a game. If an 93 * application is not a game, always return {@link #GAME_MODE_UNSUPPORTED}. 94 * <p> 95 * Developers should call this API every time the application is resumed. 96 */ getGameMode()97 public @GameMode int getGameMode() { 98 try { 99 return mService.getGameMode(mContext.getPackageName(), mContext.getUserId()); 100 } catch (RemoteException e) { 101 throw e.rethrowFromSystemServer(); 102 } 103 } 104 105 /** 106 * Gets the game mode for the given package. 107 * <p> 108 * The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}. 109 * 110 * @hide 111 */ 112 @TestApi 113 @UserHandleAware 114 @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE) getGameMode(@onNull String packageName)115 public @GameMode int getGameMode(@NonNull String packageName) { 116 try { 117 return mService.getGameMode(packageName, mContext.getUserId()); 118 } catch (RemoteException e) { 119 throw e.rethrowFromSystemServer(); 120 } 121 } 122 123 /** 124 * Returns the {@link GameModeInfo} associated with the game associated with 125 * the given {@code packageName}. If the given package is not a game, {@code null} is 126 * always returned. 127 * <p> 128 * An application can use <code>android:isGame="true"</code> or 129 * <code>android:appCategory="game"</code> to indicate that the application is a game. 130 * If the manifest doesn't define a category, the category can also be 131 * provided by the installer via 132 * {@link android.content.pm.PackageManager#setApplicationCategoryHint(String, int)}. 133 * <p> 134 * 135 * @hide 136 */ 137 @SystemApi 138 @UserHandleAware 139 @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE) getGameModeInfo(@onNull String packageName)140 public @Nullable GameModeInfo getGameModeInfo(@NonNull String packageName) { 141 try { 142 return mService.getGameModeInfo(packageName, mContext.getUserId()); 143 } catch (RemoteException e) { 144 throw e.rethrowFromSystemServer(); 145 } 146 } 147 148 /** 149 * Sets the game mode for the given package. 150 * <p> 151 * The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}. 152 * 153 * @hide 154 */ 155 @SystemApi 156 @UserHandleAware 157 @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE) setGameMode(@onNull String packageName, @GameMode int gameMode)158 public void setGameMode(@NonNull String packageName, @GameMode int gameMode) { 159 try { 160 mService.setGameMode(packageName, gameMode, mContext.getUserId()); 161 } catch (RemoteException e) { 162 throw e.rethrowFromSystemServer(); 163 } 164 } 165 166 /** 167 * Returns a list of supported game modes for a given package. 168 * <p> 169 * The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}. 170 * 171 * @hide 172 */ 173 @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE) getAvailableGameModes(@onNull String packageName)174 public @GameMode int[] getAvailableGameModes(@NonNull String packageName) { 175 try { 176 return mService.getAvailableGameModes(packageName); 177 } catch (RemoteException e) { 178 throw e.rethrowFromSystemServer(); 179 } 180 } 181 182 /** 183 * Returns if ANGLE is enabled for a given package and user ID. 184 * <p> 185 * ANGLE (Almost Native Graphics Layer Engine) can translate OpenGL ES commands to Vulkan 186 * commands. Enabling ANGLE may improve the performance and/or reduce the power consumption of 187 * applications. 188 * The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}. 189 * 190 * @hide 191 */ 192 @TestApi 193 @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE) isAngleEnabled(@onNull String packageName)194 public boolean isAngleEnabled(@NonNull String packageName) { 195 try { 196 return mService.isAngleEnabled(packageName, mContext.getUserId()); 197 } catch (RemoteException e) { 198 throw e.rethrowFromSystemServer(); 199 } 200 } 201 202 /** 203 * Set up the automatic power boost if appropriate. 204 * 205 * @hide 206 */ 207 @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE) notifyGraphicsEnvironmentSetup()208 public void notifyGraphicsEnvironmentSetup() { 209 try { 210 mService.notifyGraphicsEnvironmentSetup( 211 mContext.getPackageName(), mContext.getUserId()); 212 } catch (RemoteException e) { 213 throw e.rethrowFromSystemServer(); 214 } 215 } 216 217 /** 218 * Called by games to communicate the current state to the platform. 219 * @param gameState An object set to the current state. 220 */ setGameState(@onNull GameState gameState)221 public void setGameState(@NonNull GameState gameState) { 222 try { 223 mService.setGameState(mContext.getPackageName(), gameState, mContext.getUserId()); 224 } catch (RemoteException e) { 225 throw e.rethrowFromSystemServer(); 226 } 227 } 228 229 230 /** 231 * Sets the game service provider to the given package name for test only. 232 * 233 * <p>Passing in {@code null} will clear a previously set value. 234 * @hide 235 */ 236 @TestApi setGameServiceProvider(@ullable String packageName)237 public void setGameServiceProvider(@Nullable String packageName) { 238 try { 239 mService.setGameServiceProvider(packageName); 240 } catch (RemoteException e) { 241 throw e.rethrowFromSystemServer(); 242 } 243 } 244 } 245