Introduce new game mode config xml resource file
If the new resource file parser fail to parse the boolean values from the resource file due to tag not found in manifest or missing file, the existing metadata values will be used to populate pre-existing flags Bug: 214448560 Test: atest GameManagerTest Change-Id: I1543a1bb84379a2e9322a65d41e44fa6014821b9
This commit is contained in:
@@ -326,6 +326,8 @@ package android {
|
||||
field public static final int allowClearUserData = 16842757; // 0x1010005
|
||||
field public static final int allowClickWhenDisabled = 16844312; // 0x1010618
|
||||
field public static final int allowEmbedded = 16843765; // 0x10103f5
|
||||
field public static final int allowGameAngleDriver;
|
||||
field public static final int allowGameDownscaling;
|
||||
field public static final int allowNativeHeapPointerTagging = 16844306; // 0x1010612
|
||||
field public static final int allowParallelSyncs = 16843570; // 0x1010332
|
||||
field public static final int allowSingleTap = 16843353; // 0x1010259
|
||||
@@ -1435,10 +1437,12 @@ package android {
|
||||
field public static final int summaryOn = 16843247; // 0x10101ef
|
||||
field public static final int supportedTypes;
|
||||
field public static final int supportsAssist = 16844016; // 0x10104f0
|
||||
field public static final int supportsBatteryGameMode;
|
||||
field public static final int supportsInlineSuggestions = 16844301; // 0x101060d
|
||||
field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
|
||||
field public static final int supportsLocalInteraction = 16844047; // 0x101050f
|
||||
field public static final int supportsMultipleDisplays = 16844182; // 0x1010596
|
||||
field public static final int supportsPerformanceGameMode;
|
||||
field public static final int supportsPictureInPicture = 16844023; // 0x10104f7
|
||||
field public static final int supportsRtl = 16843695; // 0x10103af
|
||||
field public static final int supportsStylusHandwriting;
|
||||
|
||||
@@ -278,6 +278,7 @@ package android.app {
|
||||
}
|
||||
|
||||
public final class GameManager {
|
||||
method @RequiresPermission(android.Manifest.permission.MANAGE_GAME_MODE) public boolean isAngleEnabled(@NonNull String);
|
||||
method public void setGameServiceProvider(@Nullable String);
|
||||
}
|
||||
|
||||
|
||||
@@ -181,14 +181,18 @@ public final class GameManager {
|
||||
/**
|
||||
* Returns if ANGLE is enabled for a given package and user ID.
|
||||
* <p>
|
||||
* ANGLE (Almost Native Graphics Layer Engine) can translate OpenGL ES commands to Vulkan
|
||||
* commands. Enabling ANGLE may improve the performance and/or reduce the power consumption of
|
||||
* applications.
|
||||
* The caller must have {@link android.Manifest.permission#MANAGE_GAME_MODE}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
|
||||
public @GameMode boolean getAngleEnabled(@NonNull String packageName) {
|
||||
public @GameMode boolean isAngleEnabled(@NonNull String packageName) {
|
||||
try {
|
||||
return mService.getAngleEnabled(packageName, mContext.getUserId());
|
||||
return mService.isAngleEnabled(packageName, mContext.getUserId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ interface IGameManagerService {
|
||||
int getGameMode(String packageName, int userId);
|
||||
void setGameMode(String packageName, int gameMode, int userId);
|
||||
int[] getAvailableGameModes(String packageName);
|
||||
boolean getAngleEnabled(String packageName, int userId);
|
||||
boolean isAngleEnabled(String packageName, int userId);
|
||||
void setGameState(String packageName, in GameState gameState, int userId);
|
||||
GameModeInfo getGameModeInfo(String packageName, int userId);
|
||||
void setGameServiceProvider(String packageName);
|
||||
|
||||
@@ -165,7 +165,7 @@ public class GraphicsEnvironment {
|
||||
private boolean isAngleEnabledByGameMode(Context context, String packageName) {
|
||||
try {
|
||||
final boolean gameModeEnabledAngle =
|
||||
(mGameManager != null) && mGameManager.getAngleEnabled(packageName);
|
||||
(mGameManager != null) && mGameManager.isAngleEnabled(packageName);
|
||||
Log.v(TAG, "ANGLE GameManagerService for " + packageName + ": " + gameModeEnabledAngle);
|
||||
return gameModeEnabledAngle;
|
||||
} catch (SecurityException e) {
|
||||
|
||||
@@ -8875,6 +8875,20 @@
|
||||
<attr name="gameSessionService" format="string" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- Use <code>game-mode-config</code> as the root tag of the XML resource that
|
||||
describes a GameModeConfig.
|
||||
Described here are the attributes that can be included in that tag. -->
|
||||
<declare-styleable name="GameModeConfig">
|
||||
<!-- Set true to opt in BATTERY mode. -->
|
||||
<attr name="supportsBatteryGameMode" format="boolean" />
|
||||
<!-- Set true to opt in PERFORMANCE mode. -->
|
||||
<attr name="supportsPerformanceGameMode" format="boolean" />
|
||||
<!-- Set true to enable ANGLE. -->
|
||||
<attr name="allowGameAngleDriver" format="boolean" />
|
||||
<!-- Set true to allow resolution downscaling intervention. -->
|
||||
<attr name="allowGameDownscaling" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- Use <code>voice-enrollment-application</code>
|
||||
as the root tag of the XML resource that escribes the supported keyphrases (hotwords)
|
||||
by the enrollment application.
|
||||
|
||||
@@ -3255,6 +3255,10 @@
|
||||
<public name="showClockAndComplications" />
|
||||
<!-- @hide @SystemApi -->
|
||||
<public name="gameSessionService" />
|
||||
<public name="supportsBatteryGameMode" />
|
||||
<public name="supportsPerformanceGameMode" />
|
||||
<public name="allowGameAngleDriver" />
|
||||
<public name="allowGameDownscaling" />
|
||||
<public name="localeConfig" />
|
||||
<public name="showBackground" />
|
||||
<public name="inheritKeyStoreKeys" />
|
||||
|
||||
@@ -20,6 +20,10 @@ import static android.content.Intent.ACTION_PACKAGE_ADDED;
|
||||
import static android.content.Intent.ACTION_PACKAGE_CHANGED;
|
||||
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
|
||||
|
||||
import static com.android.internal.R.styleable.GameModeConfig_allowGameAngleDriver;
|
||||
import static com.android.internal.R.styleable.GameModeConfig_allowGameDownscaling;
|
||||
import static com.android.internal.R.styleable.GameModeConfig_supportsBatteryGameMode;
|
||||
import static com.android.internal.R.styleable.GameModeConfig_supportsPerformanceGameMode;
|
||||
import static com.android.server.wm.CompatModePackages.DOWNSCALED;
|
||||
import static com.android.server.wm.CompatModePackages.DOWNSCALE_30;
|
||||
import static com.android.server.wm.CompatModePackages.DOWNSCALE_35;
|
||||
@@ -54,6 +58,10 @@ import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.hardware.power.Mode;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
@@ -71,8 +79,10 @@ import android.os.ShellCallback;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.DeviceConfig.Properties;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.KeyValueListParser;
|
||||
import android.util.Slog;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -84,7 +94,11 @@ import com.android.server.ServiceThread;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.SystemService.TargetUser;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
|
||||
@@ -425,6 +439,13 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
public static final String METADATA_BATTERY_MODE_ENABLE =
|
||||
"com.android.app.gamemode.battery.enabled";
|
||||
|
||||
/**
|
||||
* Metadata that allows a game to specify all intervention information with an XML file in
|
||||
* the application field.
|
||||
*/
|
||||
public static final String METADATA_GAME_MODE_CONFIG = "android.game_mode_config";
|
||||
|
||||
private static final String GAME_MODE_CONFIG_NODE_NAME = "game-mode-config";
|
||||
private final String mPackageName;
|
||||
private final ArrayMap<Integer, GameModeConfiguration> mModeConfigs;
|
||||
private boolean mPerfModeOptedIn;
|
||||
@@ -438,18 +459,20 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
try {
|
||||
final ApplicationInfo ai = mPackageManager.getApplicationInfoAsUser(packageName,
|
||||
PackageManager.GET_META_DATA, userId);
|
||||
if (ai.metaData != null) {
|
||||
mPerfModeOptedIn = ai.metaData.getBoolean(METADATA_PERFORMANCE_MODE_ENABLE);
|
||||
mBatteryModeOptedIn = ai.metaData.getBoolean(METADATA_BATTERY_MODE_ENABLE);
|
||||
mAllowDownscale = ai.metaData.getBoolean(METADATA_WM_ALLOW_DOWNSCALE, true);
|
||||
mAllowAngle = ai.metaData.getBoolean(METADATA_ANGLE_ALLOW_ANGLE, true);
|
||||
} else {
|
||||
mPerfModeOptedIn = false;
|
||||
mBatteryModeOptedIn = false;
|
||||
mAllowDownscale = true;
|
||||
mAllowAngle = true;
|
||||
if (!parseInterventionFromXml(ai, packageName)) {
|
||||
if (ai.metaData != null) {
|
||||
mPerfModeOptedIn = ai.metaData.getBoolean(METADATA_PERFORMANCE_MODE_ENABLE);
|
||||
mBatteryModeOptedIn = ai.metaData.getBoolean(METADATA_BATTERY_MODE_ENABLE);
|
||||
mAllowDownscale = ai.metaData.getBoolean(METADATA_WM_ALLOW_DOWNSCALE, true);
|
||||
mAllowAngle = ai.metaData.getBoolean(METADATA_ANGLE_ALLOW_ANGLE, true);
|
||||
} else {
|
||||
mPerfModeOptedIn = false;
|
||||
mBatteryModeOptedIn = false;
|
||||
mAllowDownscale = true;
|
||||
mAllowAngle = true;
|
||||
}
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
} catch (NameNotFoundException e) {
|
||||
// Not all packages are installed, hence ignore those that are not installed yet.
|
||||
Slog.v(TAG, "Failed to get package metadata");
|
||||
}
|
||||
@@ -469,6 +492,51 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean parseInterventionFromXml(ApplicationInfo ai, String packageName) {
|
||||
boolean xmlFound = false;
|
||||
try (XmlResourceParser parser = ai.loadXmlMetaData(mPackageManager,
|
||||
METADATA_GAME_MODE_CONFIG)) {
|
||||
if (parser == null) {
|
||||
Slog.v(TAG, "No " + METADATA_GAME_MODE_CONFIG
|
||||
+ " meta-data found for package " + mPackageName);
|
||||
} else {
|
||||
xmlFound = true;
|
||||
final Resources resources = mPackageManager.getResourcesForApplication(
|
||||
packageName);
|
||||
final AttributeSet attributeSet = Xml.asAttributeSet(parser);
|
||||
int type;
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& type != XmlPullParser.START_TAG) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
boolean isStartingTagGameModeConfig =
|
||||
GAME_MODE_CONFIG_NODE_NAME.equals(parser.getName());
|
||||
if (!isStartingTagGameModeConfig) {
|
||||
Slog.w(TAG, "Meta-data does not start with "
|
||||
+ GAME_MODE_CONFIG_NODE_NAME
|
||||
+ " tag");
|
||||
} else {
|
||||
final TypedArray array = resources.obtainAttributes(attributeSet,
|
||||
com.android.internal.R.styleable.GameModeConfig);
|
||||
mPerfModeOptedIn = array.getBoolean(
|
||||
GameModeConfig_supportsPerformanceGameMode, false);
|
||||
mBatteryModeOptedIn = array.getBoolean(
|
||||
GameModeConfig_supportsBatteryGameMode,
|
||||
false);
|
||||
mAllowDownscale = array.getBoolean(GameModeConfig_allowGameDownscaling,
|
||||
true);
|
||||
mAllowAngle = array.getBoolean(GameModeConfig_allowGameAngleDriver, true);
|
||||
array.recycle();
|
||||
}
|
||||
}
|
||||
} catch (NameNotFoundException | XmlPullParserException | IOException ex) {
|
||||
Slog.e(TAG, "Error while parsing XML meta-data for "
|
||||
+ METADATA_GAME_MODE_CONFIG);
|
||||
}
|
||||
return xmlFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* GameModeConfiguration contains all the values for all the interventions associated with
|
||||
* a game mode.
|
||||
@@ -691,7 +759,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
try {
|
||||
return mPackageManager.getPackageUidAsUser(packageName, userId)
|
||||
== Binder.getCallingUid();
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
} catch (NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -855,7 +923,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
*/
|
||||
@Override
|
||||
@RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
|
||||
public @GameMode boolean getAngleEnabled(String packageName, int userId)
|
||||
public @GameMode boolean isAngleEnabled(String packageName, int userId)
|
||||
throws SecurityException {
|
||||
final int gameMode = getGameMode(packageName, userId);
|
||||
if (gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
|
||||
@@ -1413,7 +1481,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
|
||||
if (applicationInfo.category != ApplicationInfo.CATEGORY_GAME) {
|
||||
return;
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
} catch (NameNotFoundException e) {
|
||||
// Ignore the exception.
|
||||
}
|
||||
switch (intent.getAction()) {
|
||||
|
||||
@@ -511,8 +511,8 @@ public class GameManagerServiceTests {
|
||||
gameManagerService.getConfig(mPackageName);
|
||||
assertEquals(config.getGameModeConfiguration(gameMode).getUseAngle(), angleEnabled);
|
||||
|
||||
// Validate GameManagerService.getAngleEnabled() returns the correct value.
|
||||
assertEquals(gameManagerService.getAngleEnabled(mPackageName, USER_ID_1), angleEnabled);
|
||||
// Validate GameManagerService.isAngleEnabled() returns the correct value.
|
||||
assertEquals(gameManagerService.isAngleEnabled(mPackageName, USER_ID_1), angleEnabled);
|
||||
}
|
||||
|
||||
private void checkFps(GameManagerService gameManagerService, int gameMode, int fps) {
|
||||
|
||||
Reference in New Issue
Block a user