Add display committed state to DisplayInfo
This adds the committed state to the display. The `state` is used to set the correct power state (e.g. turning display on/off), however there was no way to know when this power state change finished. This new "committedState" aims to fulfill this gap. DisplayListeners receives a `onDisplayChanged` callback whenever the power state change is fully committed, and can get this information from DisplayInfo. This will be used in a follow up cl to improve unfold latency performances. Bug: 223808403 Bug: 220690092 Bug: 197515205 Test: atest LocalDisplayAdapterTest && manual Change-Id: Ia2fbab768b696c59578d974c88157ee3c8f3ddde
This commit is contained in:
@@ -41,6 +41,7 @@ import android.os.Looper;
|
|||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
|
import android.os.Trace;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
@@ -987,7 +988,8 @@ public final class DisplayManagerGlobal {
|
|||||||
@Override
|
@Override
|
||||||
public void onDisplayEvent(int displayId, @DisplayEvent int event) {
|
public void onDisplayEvent(int displayId, @DisplayEvent int event) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event=" + event);
|
Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event=" + eventToString(
|
||||||
|
event));
|
||||||
}
|
}
|
||||||
handleDisplayEvent(displayId, event);
|
handleDisplayEvent(displayId, event);
|
||||||
}
|
}
|
||||||
@@ -1021,6 +1023,12 @@ public final class DisplayManagerGlobal {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Trace.beginSection(
|
||||||
|
"DisplayListenerDelegate(" + eventToString(msg.what)
|
||||||
|
+ ", display=" + msg.arg1
|
||||||
|
+ ", listener=" + mListener.getClass() + ")");
|
||||||
|
}
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case EVENT_DISPLAY_ADDED:
|
case EVENT_DISPLAY_ADDED:
|
||||||
if ((mEventsMask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {
|
if ((mEventsMask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {
|
||||||
@@ -1047,6 +1055,9 @@ public final class DisplayManagerGlobal {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (DEBUG) {
|
||||||
|
Trace.endSection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1150,4 +1161,18 @@ public final class DisplayManagerGlobal {
|
|||||||
updateCallbackIfNeededLocked();
|
updateCallbackIfNeededLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String eventToString(@DisplayEvent int event) {
|
||||||
|
switch (event) {
|
||||||
|
case EVENT_DISPLAY_ADDED:
|
||||||
|
return "ADDED";
|
||||||
|
case EVENT_DISPLAY_CHANGED:
|
||||||
|
return "CHANGED";
|
||||||
|
case EVENT_DISPLAY_REMOVED:
|
||||||
|
return "REMOVED";
|
||||||
|
case EVENT_DISPLAY_BRIGHTNESS_CHANGED:
|
||||||
|
return "BRIGHTNESS_CHANGED";
|
||||||
|
}
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1615,6 +1615,21 @@ public final class Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the committed state of the display.
|
||||||
|
*
|
||||||
|
* @return The latest committed display state, such as {@link #STATE_ON}. The display state
|
||||||
|
* {@link Display#getState()} is set as committed only after power state changes finish.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public int getCommittedState() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
updateDisplayInfoLocked();
|
||||||
|
return mIsValid ? mDisplayInfo.committedState : STATE_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the specified UID has access to this display.
|
* Returns true if the specified UID has access to this display.
|
||||||
* @hide
|
* @hide
|
||||||
|
|||||||
@@ -252,6 +252,12 @@ public final class DisplayInfo implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public int state;
|
public int state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current committed state of the display. For example, this becomes
|
||||||
|
* {@link android.view.Display#STATE_ON} only after the power state ON is fully committed.
|
||||||
|
*/
|
||||||
|
public int committedState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The UID of the application that owns this display, or zero if it is owned by the system.
|
* The UID of the application that owns this display, or zero if it is owned by the system.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -387,6 +393,7 @@ public final class DisplayInfo implements Parcelable {
|
|||||||
&& appVsyncOffsetNanos == other.appVsyncOffsetNanos
|
&& appVsyncOffsetNanos == other.appVsyncOffsetNanos
|
||||||
&& presentationDeadlineNanos == other.presentationDeadlineNanos
|
&& presentationDeadlineNanos == other.presentationDeadlineNanos
|
||||||
&& state == other.state
|
&& state == other.state
|
||||||
|
&& committedState == other.committedState
|
||||||
&& ownerUid == other.ownerUid
|
&& ownerUid == other.ownerUid
|
||||||
&& Objects.equals(ownerPackageName, other.ownerPackageName)
|
&& Objects.equals(ownerPackageName, other.ownerPackageName)
|
||||||
&& removeMode == other.removeMode
|
&& removeMode == other.removeMode
|
||||||
@@ -439,6 +446,7 @@ public final class DisplayInfo implements Parcelable {
|
|||||||
appVsyncOffsetNanos = other.appVsyncOffsetNanos;
|
appVsyncOffsetNanos = other.appVsyncOffsetNanos;
|
||||||
presentationDeadlineNanos = other.presentationDeadlineNanos;
|
presentationDeadlineNanos = other.presentationDeadlineNanos;
|
||||||
state = other.state;
|
state = other.state;
|
||||||
|
committedState = other.committedState;
|
||||||
ownerUid = other.ownerUid;
|
ownerUid = other.ownerUid;
|
||||||
ownerPackageName = other.ownerPackageName;
|
ownerPackageName = other.ownerPackageName;
|
||||||
removeMode = other.removeMode;
|
removeMode = other.removeMode;
|
||||||
@@ -491,6 +499,7 @@ public final class DisplayInfo implements Parcelable {
|
|||||||
appVsyncOffsetNanos = source.readLong();
|
appVsyncOffsetNanos = source.readLong();
|
||||||
presentationDeadlineNanos = source.readLong();
|
presentationDeadlineNanos = source.readLong();
|
||||||
state = source.readInt();
|
state = source.readInt();
|
||||||
|
committedState = source.readInt();
|
||||||
ownerUid = source.readInt();
|
ownerUid = source.readInt();
|
||||||
ownerPackageName = source.readString8();
|
ownerPackageName = source.readString8();
|
||||||
uniqueId = source.readString8();
|
uniqueId = source.readString8();
|
||||||
@@ -548,6 +557,7 @@ public final class DisplayInfo implements Parcelable {
|
|||||||
dest.writeLong(appVsyncOffsetNanos);
|
dest.writeLong(appVsyncOffsetNanos);
|
||||||
dest.writeLong(presentationDeadlineNanos);
|
dest.writeLong(presentationDeadlineNanos);
|
||||||
dest.writeInt(state);
|
dest.writeInt(state);
|
||||||
|
dest.writeInt(committedState);
|
||||||
dest.writeInt(ownerUid);
|
dest.writeInt(ownerUid);
|
||||||
dest.writeString8(ownerPackageName);
|
dest.writeString8(ownerPackageName);
|
||||||
dest.writeString8(uniqueId);
|
dest.writeString8(uniqueId);
|
||||||
@@ -772,6 +782,8 @@ public final class DisplayInfo implements Parcelable {
|
|||||||
sb.append(rotation);
|
sb.append(rotation);
|
||||||
sb.append(", state ");
|
sb.append(", state ");
|
||||||
sb.append(Display.stateToString(state));
|
sb.append(Display.stateToString(state));
|
||||||
|
sb.append(", committedState ");
|
||||||
|
sb.append(Display.stateToString(committedState));
|
||||||
|
|
||||||
if (Process.myUid() != Process.SYSTEM_UID) {
|
if (Process.myUid() != Process.SYSTEM_UID) {
|
||||||
sb.append("}");
|
sb.append("}");
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ final class DisplayDeviceInfo {
|
|||||||
public static final int TOUCH_VIRTUAL = 3;
|
public static final int TOUCH_VIRTUAL = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diff result: The {@link #state} fields differ.
|
* Diff result: The {@link #state} or {@link #committedState} fields differ.
|
||||||
*/
|
*/
|
||||||
public static final int DIFF_STATE = 1 << 0;
|
public static final int DIFF_STATE = 1 << 0;
|
||||||
|
|
||||||
@@ -334,6 +334,13 @@ final class DisplayDeviceInfo {
|
|||||||
*/
|
*/
|
||||||
public int state = Display.STATE_ON;
|
public int state = Display.STATE_ON;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display committed state.
|
||||||
|
*
|
||||||
|
* This matches {@link DisplayDeviceInfo#state} only after the power state change finishes.
|
||||||
|
*/
|
||||||
|
public int committedState = Display.STATE_UNKNOWN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The UID of the application that owns this display, or zero if it is owned by the system.
|
* The UID of the application that owns this display, or zero if it is owned by the system.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -387,7 +394,7 @@ final class DisplayDeviceInfo {
|
|||||||
*/
|
*/
|
||||||
public int diff(DisplayDeviceInfo other) {
|
public int diff(DisplayDeviceInfo other) {
|
||||||
int diff = 0;
|
int diff = 0;
|
||||||
if (state != other.state) {
|
if (state != other.state || committedState != other.committedState) {
|
||||||
diff |= DIFF_STATE;
|
diff |= DIFF_STATE;
|
||||||
}
|
}
|
||||||
if (colorMode != other.colorMode) {
|
if (colorMode != other.colorMode) {
|
||||||
@@ -461,6 +468,7 @@ final class DisplayDeviceInfo {
|
|||||||
address = other.address;
|
address = other.address;
|
||||||
deviceProductInfo = other.deviceProductInfo;
|
deviceProductInfo = other.deviceProductInfo;
|
||||||
state = other.state;
|
state = other.state;
|
||||||
|
committedState = other.committedState;
|
||||||
ownerUid = other.ownerUid;
|
ownerUid = other.ownerUid;
|
||||||
ownerPackageName = other.ownerPackageName;
|
ownerPackageName = other.ownerPackageName;
|
||||||
frameRateOverrides = other.frameRateOverrides;
|
frameRateOverrides = other.frameRateOverrides;
|
||||||
@@ -501,6 +509,7 @@ final class DisplayDeviceInfo {
|
|||||||
}
|
}
|
||||||
sb.append(", deviceProductInfo ").append(deviceProductInfo);
|
sb.append(", deviceProductInfo ").append(deviceProductInfo);
|
||||||
sb.append(", state ").append(Display.stateToString(state));
|
sb.append(", state ").append(Display.stateToString(state));
|
||||||
|
sb.append(", committedState ").append(Display.stateToString(committedState));
|
||||||
if (ownerUid != 0 || ownerPackageName != null) {
|
if (ownerUid != 0 || ownerPackageName != null) {
|
||||||
sb.append(", owner ").append(ownerPackageName);
|
sb.append(", owner ").append(ownerPackageName);
|
||||||
sb.append(" (uid ").append(ownerUid).append(")");
|
sb.append(" (uid ").append(ownerUid).append(")");
|
||||||
|
|||||||
@@ -191,6 +191,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
private DisplayDeviceInfo mInfo;
|
private DisplayDeviceInfo mInfo;
|
||||||
private boolean mHavePendingChanges;
|
private boolean mHavePendingChanges;
|
||||||
private int mState = Display.STATE_UNKNOWN;
|
private int mState = Display.STATE_UNKNOWN;
|
||||||
|
private int mCommittedState = Display.STATE_UNKNOWN;
|
||||||
|
|
||||||
// This is only set in the runnable returned from requestDisplayStateLocked.
|
// This is only set in the runnable returned from requestDisplayStateLocked.
|
||||||
private float mBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
private float mBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
||||||
private float mSdrBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
private float mSdrBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
||||||
@@ -632,6 +634,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
mInfo.appVsyncOffsetNanos = mActiveSfDisplayMode.appVsyncOffsetNanos;
|
mInfo.appVsyncOffsetNanos = mActiveSfDisplayMode.appVsyncOffsetNanos;
|
||||||
mInfo.presentationDeadlineNanos = mActiveSfDisplayMode.presentationDeadlineNanos;
|
mInfo.presentationDeadlineNanos = mActiveSfDisplayMode.presentationDeadlineNanos;
|
||||||
mInfo.state = mState;
|
mInfo.state = mState;
|
||||||
|
mInfo.committedState = mCommittedState;
|
||||||
mInfo.uniqueId = getUniqueId();
|
mInfo.uniqueId = getUniqueId();
|
||||||
final DisplayAddress.Physical physicalAddress =
|
final DisplayAddress.Physical physicalAddress =
|
||||||
DisplayAddress.fromPhysicalDisplayId(mPhysicalDisplayId);
|
DisplayAddress.fromPhysicalDisplayId(mPhysicalDisplayId);
|
||||||
@@ -812,6 +815,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
} finally {
|
} finally {
|
||||||
Trace.traceEnd(Trace.TRACE_TAG_POWER);
|
Trace.traceEnd(Trace.TRACE_TAG_POWER);
|
||||||
}
|
}
|
||||||
|
setCommittedState(state);
|
||||||
// If we're entering a suspended (but not OFF) power state and we
|
// If we're entering a suspended (but not OFF) power state and we
|
||||||
// have a sidekick available, tell it now that it can take control.
|
// have a sidekick available, tell it now that it can take control.
|
||||||
if (Display.isSuspendedState(state) && state != Display.STATE_OFF
|
if (Display.isSuspendedState(state) && state != Display.STATE_OFF
|
||||||
@@ -826,6 +830,16 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setCommittedState(int state) {
|
||||||
|
// After the display state is set, let's update the committed state.
|
||||||
|
getHandler().post(() -> {
|
||||||
|
synchronized (getSyncRoot()) {
|
||||||
|
mCommittedState = state;
|
||||||
|
updateDeviceInfoLocked();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void setDisplayBrightness(float brightnessState,
|
private void setDisplayBrightness(float brightnessState,
|
||||||
float sdrBrightnessState) {
|
float sdrBrightnessState) {
|
||||||
// brightnessState includes invalid, off and full range.
|
// brightnessState includes invalid, off and full range.
|
||||||
@@ -1091,6 +1105,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
pw.println("mDefaultModeId=" + mDefaultModeId);
|
pw.println("mDefaultModeId=" + mDefaultModeId);
|
||||||
pw.println("mUserPreferredModeId=" + mUserPreferredModeId);
|
pw.println("mUserPreferredModeId=" + mUserPreferredModeId);
|
||||||
pw.println("mState=" + Display.stateToString(mState));
|
pw.println("mState=" + Display.stateToString(mState));
|
||||||
|
pw.println("mCommittedState=" + Display.stateToString(mCommittedState));
|
||||||
pw.println("mBrightnessState=" + mBrightnessState);
|
pw.println("mBrightnessState=" + mBrightnessState);
|
||||||
pw.println("mBacklightAdapter=" + mBacklightAdapter);
|
pw.println("mBacklightAdapter=" + mBacklightAdapter);
|
||||||
pw.println("mAllmSupported=" + mAllmSupported);
|
pw.println("mAllmSupported=" + mAllmSupported);
|
||||||
|
|||||||
@@ -413,6 +413,7 @@ final class LogicalDisplay {
|
|||||||
mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
|
mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
|
||||||
mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
|
mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
|
||||||
mBaseDisplayInfo.state = deviceInfo.state;
|
mBaseDisplayInfo.state = deviceInfo.state;
|
||||||
|
mBaseDisplayInfo.committedState = deviceInfo.committedState;
|
||||||
mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth;
|
mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth;
|
||||||
mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight;
|
mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight;
|
||||||
mBaseDisplayInfo.largestNominalAppWidth = maskedWidth;
|
mBaseDisplayInfo.largestNominalAppWidth = maskedWidth;
|
||||||
|
|||||||
@@ -556,6 +556,40 @@ public class LocalDisplayAdapterTest {
|
|||||||
assertThat(displayDeviceInfo.allmSupported).isFalse();
|
assertThat(displayDeviceInfo.allmSupported).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAfterDisplayStateChanges_committedSetAfterState() throws Exception {
|
||||||
|
FakeDisplay display = new FakeDisplay(PORT_A);
|
||||||
|
setUpDisplay(display);
|
||||||
|
updateAvailableDisplays();
|
||||||
|
mAdapter.registerLocked();
|
||||||
|
waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
|
||||||
|
assertThat(mListener.addedDisplays.size()).isEqualTo(1);
|
||||||
|
DisplayDevice displayDevice = mListener.addedDisplays.get(0);
|
||||||
|
|
||||||
|
// Turn off.
|
||||||
|
Runnable changeStateRunnable = displayDevice.requestDisplayStateLocked(Display.STATE_OFF, 0,
|
||||||
|
0);
|
||||||
|
waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
|
||||||
|
assertThat(mListener.changedDisplays.size()).isEqualTo(1);
|
||||||
|
mListener.changedDisplays.clear();
|
||||||
|
assertThat(displayDevice.getDisplayDeviceInfoLocked().state).isEqualTo(Display.STATE_OFF);
|
||||||
|
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState).isNotEqualTo(
|
||||||
|
Display.STATE_OFF);
|
||||||
|
verify(mSurfaceControlProxy, never()).setDisplayPowerMode(display.token, Display.STATE_OFF);
|
||||||
|
|
||||||
|
// Execute powerstate change.
|
||||||
|
changeStateRunnable.run();
|
||||||
|
waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
|
||||||
|
|
||||||
|
|
||||||
|
// Verify that committed triggered a new change event and is set correctly.
|
||||||
|
verify(mSurfaceControlProxy, never()).setDisplayPowerMode(display.token, Display.STATE_OFF);
|
||||||
|
assertThat(mListener.changedDisplays.size()).isEqualTo(1);
|
||||||
|
assertThat(displayDevice.getDisplayDeviceInfoLocked().state).isEqualTo(Display.STATE_OFF);
|
||||||
|
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState).isEqualTo(
|
||||||
|
Display.STATE_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAfterDisplayChange_GameContentTypeSupportIsUpdated() throws Exception {
|
public void testAfterDisplayChange_GameContentTypeSupportIsUpdated() throws Exception {
|
||||||
FakeDisplay display = new FakeDisplay(PORT_A);
|
FakeDisplay display = new FakeDisplay(PORT_A);
|
||||||
|
|||||||
Reference in New Issue
Block a user