Merge "Add TestApi for setRefreshRateSwitchingType"

This commit is contained in:
TreeHugger Robot
2020-12-02 21:07:04 +00:00
committed by Android (Google) Code Review
9 changed files with 169 additions and 40 deletions

View File

@@ -18,6 +18,7 @@ package android {
field public static final String MANAGE_CRATES = "android.permission.MANAGE_CRATES";
field public static final String MANAGE_NOTIFICATION_LISTENERS = "android.permission.MANAGE_NOTIFICATION_LISTENERS";
field public static final String MANAGE_ROLLBACKS = "android.permission.MANAGE_ROLLBACKS";
field public static final String MODIFY_REFRESH_RATE_SWITCHING_TYPE = "android.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE";
field public static final String NETWORK_SETTINGS = "android.permission.NETWORK_SETTINGS";
field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK";
field public static final String OVERRIDE_DISPLAY_MODE_REQUESTS = "android.permission.OVERRIDE_DISPLAY_MODE_REQUESTS";
@@ -743,9 +744,14 @@ package android.hardware.display {
}
public final class DisplayManager {
method @RequiresPermission(android.Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE) public int getRefreshRateSwitchingType();
method public boolean isMinimalPostProcessingRequested(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE) public void setRefreshRateSwitchingType(int);
method @RequiresPermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS) public void setShouldAlwaysRespectAppRequestedMode(boolean);
method @RequiresPermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS) public boolean shouldAlwaysRespectAppRequestedMode();
field public static final int SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS = 2; // 0x2
field public static final int SWITCHING_TYPE_NONE = 0; // 0x0
field public static final int SWITCHING_TYPE_WITHIN_GROUPS = 1; // 0x1
field public static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 512; // 0x200
field public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1024; // 0x400
}

View File

@@ -19,6 +19,7 @@ package android.hardware.display;
import static android.view.Display.DEFAULT_DISPLAY;
import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -38,9 +39,12 @@ import android.util.SparseArray;
import android.view.Display;
import android.view.Surface;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
/**
* Manages the properties of attached displays.
*/
@@ -336,6 +340,40 @@ public final class DisplayManager {
*/
public static final int VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP = 1 << 11;
/** @hide */
@IntDef(prefix = {"SWITCHING_TYPE_"}, value = {
SWITCHING_TYPE_NONE,
SWITCHING_TYPE_WITHIN_GROUPS,
SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SwitchingType {}
/**
* No mode switching will happen.
* @hide
*/
@TestApi
public static final int SWITCHING_TYPE_NONE = 0;
/**
* Allow only refresh rate switching between modes in the same configuration group. This way
* only switches without visual interruptions for the user will be allowed.
* @hide
*/
@TestApi
public static final int SWITCHING_TYPE_WITHIN_GROUPS = 1;
/**
* Allow refresh rate switching between all refresh rates even if the switch with have visual
* interruptions for the user.
* @hide
*/
@TestApi
public static final int SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS = 2;
/** @hide */
public DisplayManager(Context context) {
mContext = context;
@@ -874,6 +912,29 @@ public final class DisplayManager {
return mGlobal.shouldAlwaysRespectAppRequestedMode();
}
/**
* Sets the refresh rate switching type.
* This matches {@link android.provider.Settings.Secure.MATCH_CONTENT_FRAME_RATE}
*
* @hide
*/
@TestApi
@RequiresPermission(Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE)
public void setRefreshRateSwitchingType(@SwitchingType int newValue) {
mGlobal.setRefreshRateSwitchingType(newValue);
}
/**
* Returns the refresh rate switching type.
*
* @hide
*/
@TestApi
@RequiresPermission(Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE)
@SwitchingType public int getRefreshRateSwitchingType() {
return mGlobal.getRefreshRateSwitchingType();
}
/**
* Listens for changes in available display devices.
*/

View File

@@ -725,6 +725,33 @@ public final class DisplayManagerGlobal {
}
}
/**
* Sets the refresh rate switching type.
*
* @hide
*/
public void setRefreshRateSwitchingType(@DisplayManager.SwitchingType int newValue) {
try {
mDm.setRefreshRateSwitchingType(newValue);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
/**
* Returns the refresh rate switching type.
*
* @hide
*/
@DisplayManager.SwitchingType
public int getRefreshRateSwitchingType() {
try {
return mDm.getRefreshRateSwitchingType();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub {
@Override
public void onDisplayEvent(int displayId, int event) {

View File

@@ -134,4 +134,10 @@ interface IDisplayManager {
// battery etc.
void setShouldAlwaysRespectAppRequestedMode(boolean enabled);
boolean shouldAlwaysRespectAppRequestedMode();
// Sets the refresh rate switching type.
void setRefreshRateSwitchingType(int newValue);
// Returns the refresh rate switching type.
int getRefreshRateSwitchingType();
}

View File

@@ -4047,6 +4047,13 @@
<permission android:name="android.permission.OVERRIDE_DISPLAY_MODE_REQUESTS"
android:protectionLevel="signature" />
<!-- Allows an application to modify the refresh rate switching type. This
matches Setting.Secure.MATCH_CONTENT_FRAME_RATE.
@hide
@TestApi -->
<permission android:name="android.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE"
android:protectionLevel="signature" />
<!-- @SystemApi Allows an application to control VPN.
<p>Not for use by third-party applications.</p>
@hide -->

View File

@@ -332,6 +332,9 @@
<!-- Permission needed for CTS test - DisplayTest -->
<uses-permission android:name="android.permission.OVERRIDE_DISPLAY_MODE_REQUESTS" />
<!-- Permission needed for CTS test - MatchContentFrameRateTest -->
<uses-permission android:name="android.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE" />
<!-- Permission needed for CTS test - TimeManagerTest -->
<uses-permission android:name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION" />

View File

@@ -53,6 +53,7 @@ import android.hardware.display.AmbientBrightnessDayStats;
import android.hardware.display.BrightnessChangeEvent;
import android.hardware.display.BrightnessConfiguration;
import android.hardware.display.Curve;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
@@ -1252,11 +1253,19 @@ public final class DisplayManagerService extends SystemService {
mDisplayModeDirector.setShouldAlwaysRespectAppRequestedMode(enabled);
}
boolean shouldAlwaysRespectAppRequestedModeInternal() {
return mDisplayModeDirector.shouldAlwaysRespectAppRequestedMode();
}
void setRefreshRateSwitchingTypeInternal(@DisplayManager.SwitchingType int newValue) {
mDisplayModeDirector.setModeSwitchingType(newValue);
}
@DisplayManager.SwitchingType
int getRefreshRateSwitchingTypeInternal() {
return mDisplayModeDirector.getModeSwitchingType();
}
private void setBrightnessConfigurationForUserInternal(
@Nullable BrightnessConfiguration c, @UserIdInt int userId,
@Nullable String packageName) {
@@ -2595,6 +2604,32 @@ public final class DisplayManagerService extends SystemService {
}
}
@Override // Binder call
public void setRefreshRateSwitchingType(int newValue) {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE,
"Permission required to modify refresh rate switching type.");
final long token = Binder.clearCallingIdentity();
try {
setRefreshRateSwitchingTypeInternal(newValue);
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override // Binder call
public int getRefreshRateSwitchingType() {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE,
"Permission required read refresh rate switching type.");
final long token = Binder.clearCallingIdentity();
try {
return getRefreshRateSwitchingTypeInternal();
} finally {
Binder.restoreCallingIdentity(token);
}
}
private boolean validatePackageName(int uid, String packageName) {
if (packageName != null) {
String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);

View File

@@ -16,7 +16,6 @@
package com.android.server.display;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentResolver;
@@ -53,8 +52,6 @@ import com.android.server.display.utils.AmbientFilterFactory;
import com.android.server.utils.DeviceConfigInterface;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -110,28 +107,11 @@ public class DisplayModeDirector {
private boolean mAlwaysRespectAppRequest;
@IntDef(prefix = {"SWITCHING_TYPE_"}, value = {
SWITCHING_TYPE_NONE,
SWITCHING_TYPE_WITHIN_GROUPS,
SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SwitchingType {}
// No mode switching will happen.
public static final int SWITCHING_TYPE_NONE = 0;
// Allow only refresh rate switching between modes in the same configuration group. This way
// only switches without visual interruptions for the user will be allowed.
public static final int SWITCHING_TYPE_WITHIN_GROUPS = 1;
// Allow refresh rate switching between all refresh rates even if the switch with have visual
// interruptions for the user.
public static final int SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS = 2;
/**
* The allowed refresh rate switching type. This is used by SurfaceFlinger.
*/
@SwitchingType
private int mModeSwitchingType = SWITCHING_TYPE_WITHIN_GROUPS;
@DisplayManager.SwitchingType
private int mModeSwitchingType = DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS;
public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler) {
this(context, handler, new RealInjector());
@@ -337,7 +317,7 @@ public class DisplayModeDirector {
if (availableModes.length > 0) {
baseModeId = availableModes[0];
}
if (mModeSwitchingType == SWITCHING_TYPE_NONE) {
if (mModeSwitchingType == DisplayManager.SWITCHING_TYPE_NONE) {
Display.Mode baseMode = null;
for (Display.Mode mode : modes) {
if (mode.getModeId() == baseModeId) {
@@ -359,7 +339,7 @@ public class DisplayModeDirector {
}
boolean allowGroupSwitching =
mModeSwitchingType == SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS;
mModeSwitchingType == DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS;
return new DesiredDisplayModeSpecs(baseModeId,
allowGroupSwitching,
new RefreshRateRange(
@@ -450,18 +430,21 @@ public class DisplayModeDirector {
/**
* Sets the display mode switching type.
* @param type
* @param newType
*/
public void setModeSwitchingType(@SwitchingType int type) {
public void setModeSwitchingType(@DisplayManager.SwitchingType int newType) {
synchronized (mLock) {
mModeSwitchingType = type;
if (newType != mModeSwitchingType) {
mModeSwitchingType = newType;
notifyDesiredDisplayModeSpecsChangedLocked();
}
}
}
/**
* Returns the display mode switching type.
*/
@SwitchingType
@DisplayManager.SwitchingType
public int getModeSwitchingType() {
synchronized (mLock) {
return mModeSwitchingType;
@@ -583,13 +566,13 @@ public class DisplayModeDirector {
}
}
private static String switchingTypeToString(@SwitchingType int type) {
private static String switchingTypeToString(@DisplayManager.SwitchingType int type) {
switch (type) {
case SWITCHING_TYPE_NONE:
case DisplayManager.SWITCHING_TYPE_NONE:
return "SWITCHING_TYPE_NONE";
case SWITCHING_TYPE_WITHIN_GROUPS:
case DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS:
return "SWITCHING_TYPE_WITHIN_GROUPS";
case SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS:
case DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS:
return "SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS";
default:
return "Unknown SwitchingType " + type;

View File

@@ -40,6 +40,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.database.ContentObserver;
import android.hardware.display.DisplayManager;
import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
@@ -402,7 +403,7 @@ public class DisplayModeDirectorTest {
director.injectVotesByDisplay(votesByDisplay);
assertThat(director.getModeSwitchingType())
.isNotEqualTo(DisplayModeDirector.SWITCHING_TYPE_NONE);
.isNotEqualTo(DisplayManager.SWITCHING_TYPE_NONE);
DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30);
@@ -411,9 +412,9 @@ public class DisplayModeDirectorTest {
assertThat(desiredSpecs.appRequestRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
assertThat(desiredSpecs.baseModeId).isEqualTo(30);
director.setModeSwitchingType(DisplayModeDirector.SWITCHING_TYPE_NONE);
director.setModeSwitchingType(DisplayManager.SWITCHING_TYPE_NONE);
assertThat(director.getModeSwitchingType())
.isEqualTo(DisplayModeDirector.SWITCHING_TYPE_NONE);
.isEqualTo(DisplayManager.SWITCHING_TYPE_NONE);
desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30);
@@ -428,9 +429,9 @@ public class DisplayModeDirectorTest {
final int displayId = 0;
DisplayModeDirector director = createDirectorFromFpsRange(0, 90);
director.setModeSwitchingType(DisplayModeDirector.SWITCHING_TYPE_WITHIN_GROUPS);
director.setModeSwitchingType(DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS);
assertThat(director.getModeSwitchingType())
.isEqualTo(DisplayModeDirector.SWITCHING_TYPE_WITHIN_GROUPS);
.isEqualTo(DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS);
DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
assertThat(desiredSpecs.allowGroupSwitching).isFalse();
}
@@ -440,9 +441,9 @@ public class DisplayModeDirectorTest {
final int displayId = 0;
DisplayModeDirector director = createDirectorFromFpsRange(0, 90);
director.setModeSwitchingType(DisplayModeDirector.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS);
director.setModeSwitchingType(DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS);
assertThat(director.getModeSwitchingType())
.isEqualTo(DisplayModeDirector.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS);
.isEqualTo(DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS);
DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
assertThat(desiredSpecs.allowGroupSwitching).isTrue();
}