Merge "Send events when DisplayGroups are added/modified/removed" into sc-dev
This commit is contained in:
@@ -47,20 +47,22 @@ public abstract class DisplayManagerInternal {
|
||||
* begins adjusting the power state to match what was requested.
|
||||
* </p>
|
||||
*
|
||||
* @param groupId The identifier for the display group being requested to change power state
|
||||
* @param request The requested power state.
|
||||
* @param waitForNegativeProximity If true, issues a request to wait for
|
||||
* @param waitForNegativeProximity If {@code true}, issues a request to wait for
|
||||
* negative proximity before turning the screen back on, assuming the screen
|
||||
* was turned off by the proximity sensor.
|
||||
* @return True if display is ready, false if there are important changes that must
|
||||
* be made asynchronously (such as turning the screen on), in which case the caller
|
||||
* should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
|
||||
* then try the request again later until the state converges.
|
||||
* @return {@code true} if display group is ready, {@code false} if there are important
|
||||
* changes that must be made asynchronously (such as turning the screen on), in which case
|
||||
* the caller should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged}
|
||||
* then try the request again later until the state converges. If the provided {@code groupId}
|
||||
* cannot be found then {@code true} will be returned.
|
||||
*/
|
||||
public abstract boolean requestPowerState(DisplayPowerRequest request,
|
||||
public abstract boolean requestPowerState(int groupId, DisplayPowerRequest request,
|
||||
boolean waitForNegativeProximity);
|
||||
|
||||
/**
|
||||
* Returns true if the proximity sensor screen-off function is available.
|
||||
* Returns {@code true} if the proximity sensor screen-off function is available.
|
||||
*/
|
||||
public abstract boolean isProximitySensorAvailable();
|
||||
|
||||
@@ -70,6 +72,22 @@ public abstract class DisplayManagerInternal {
|
||||
*/
|
||||
public abstract int getDisplayGroupId(int displayId);
|
||||
|
||||
/**
|
||||
* Registers a display group listener which will be informed of the addition, removal, or change
|
||||
* of display groups.
|
||||
*
|
||||
* @param listener The listener to register.
|
||||
*/
|
||||
public abstract void registerDisplayGroupListener(DisplayGroupListener listener);
|
||||
|
||||
/**
|
||||
* Unregisters a display group listener which will be informed of the addition, removal, or
|
||||
* change of display groups.
|
||||
*
|
||||
* @param listener The listener to unregister.
|
||||
*/
|
||||
public abstract void unregisterDisplayGroupListener(DisplayGroupListener listener);
|
||||
|
||||
/**
|
||||
* Screenshot for internal system-only use such as rotation, etc. This method includes
|
||||
* secure layers and the result should never be exposed to non-system applications.
|
||||
|
||||
@@ -21,7 +21,8 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and
|
||||
* operations.
|
||||
* operations; particularly display-state.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class DisplayGroup {
|
||||
@@ -33,17 +34,44 @@ public class DisplayGroup {
|
||||
mGroupId = groupId;
|
||||
}
|
||||
|
||||
/** Returns the identifier for the Group. */
|
||||
int getGroupId() {
|
||||
return mGroupId;
|
||||
}
|
||||
|
||||
void addDisplay(LogicalDisplay display) {
|
||||
/**
|
||||
* Adds the provided {@code display} to the Group
|
||||
*
|
||||
* @param display the {@link LogicalDisplay} to add to the Group
|
||||
*/
|
||||
void addDisplayLocked(LogicalDisplay display) {
|
||||
if (!mDisplays.contains(display)) {
|
||||
mDisplays.add(display);
|
||||
}
|
||||
}
|
||||
|
||||
boolean removeDisplay(LogicalDisplay display) {
|
||||
/**
|
||||
* Removes the provided {@code display} from the Group.
|
||||
*
|
||||
* @param display The {@link LogicalDisplay} to remove from the Group.
|
||||
* @return {@code true} if the {@code display} was removed; otherwise {@code false}
|
||||
*/
|
||||
boolean removeDisplayLocked(LogicalDisplay display) {
|
||||
return mDisplays.remove(display);
|
||||
}
|
||||
|
||||
/** Returns {@code true} if there are no {@link LogicalDisplay LogicalDisplays} in the Group. */
|
||||
boolean isEmptyLocked() {
|
||||
return mDisplays.isEmpty();
|
||||
}
|
||||
|
||||
/** Returns the number of {@link LogicalDisplay LogicalDisplays} in the Group. */
|
||||
int getSizeLocked() {
|
||||
return mDisplays.size();
|
||||
}
|
||||
|
||||
/** Returns the ID of the {@link LogicalDisplay} at the provided {@code index}. */
|
||||
int getIdLocked(int index) {
|
||||
return mDisplays.get(index).getDisplayIdLocked();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ 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.DisplayGroupListener;
|
||||
import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
|
||||
import android.hardware.display.DisplayViewport;
|
||||
import android.hardware.display.DisplayedContentSample;
|
||||
@@ -190,6 +191,7 @@ public final class DisplayManagerService extends SystemService {
|
||||
private static final int MSG_UPDATE_VIEWPORT = 5;
|
||||
private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6;
|
||||
private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7;
|
||||
private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8;
|
||||
|
||||
private final Context mContext;
|
||||
private final DisplayManagerHandler mHandler;
|
||||
@@ -237,6 +239,10 @@ public final class DisplayManagerService extends SystemService {
|
||||
private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
|
||||
new CopyOnWriteArrayList<DisplayTransactionListener>();
|
||||
|
||||
/** List of all display group listeners. */
|
||||
private final CopyOnWriteArrayList<DisplayGroupListener> mDisplayGroupListeners =
|
||||
new CopyOnWriteArrayList<>();
|
||||
|
||||
/** All {@link DisplayPowerController}s indexed by {@link LogicalDisplay} ID. */
|
||||
private final SparseArray<DisplayPowerController> mDisplayPowerControllers =
|
||||
new SparseArray<>();
|
||||
@@ -1677,6 +1683,11 @@ public final class DisplayManagerService extends SystemService {
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
private void sendDisplayGroupEvent(int groupId, int event) {
|
||||
Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_GROUP_EVENT, groupId, event);
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
private void sendDisplayEventFrameRateOverrideLocked(int displayId) {
|
||||
Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE,
|
||||
displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
|
||||
@@ -1721,6 +1732,35 @@ public final class DisplayManagerService extends SystemService {
|
||||
mTempCallbacks.clear();
|
||||
}
|
||||
|
||||
// Runs on Handler thread.
|
||||
// Delivers display group event notifications to callbacks.
|
||||
private void deliverDisplayGroupEvent(int groupId, int event) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Delivering display group event: groupId=" + groupId + ", event="
|
||||
+ event);
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED:
|
||||
for (DisplayGroupListener listener : mDisplayGroupListeners) {
|
||||
listener.onDisplayGroupAdded(groupId);
|
||||
}
|
||||
break;
|
||||
|
||||
case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED:
|
||||
for (DisplayGroupListener listener : mDisplayGroupListeners) {
|
||||
listener.onDisplayGroupChanged(groupId);
|
||||
}
|
||||
break;
|
||||
|
||||
case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED:
|
||||
for (DisplayGroupListener listener : mDisplayGroupListeners) {
|
||||
listener.onDisplayGroupRemoved(groupId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private IMediaProjectionManager getProjectionService() {
|
||||
if (mProjectionService == null) {
|
||||
IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
|
||||
@@ -1943,6 +1983,11 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
deliverDisplayEvent(msg.arg1, uids, msg.arg2);
|
||||
break;
|
||||
|
||||
case MSG_DELIVER_DISPLAY_GROUP_EVENT:
|
||||
deliverDisplayGroupEvent(msg.arg1, msg.arg2);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1973,6 +2018,11 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayGroupEventLocked(int groupId, int event) {
|
||||
sendDisplayGroupEvent(groupId, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTraversalRequested() {
|
||||
synchronized (mSyncRoot) {
|
||||
@@ -2708,11 +2758,25 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestPowerState(DisplayPowerRequest request,
|
||||
public boolean requestPowerState(int groupId, DisplayPowerRequest request,
|
||||
boolean waitForNegativeProximity) {
|
||||
synchronized (mSyncRoot) {
|
||||
return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
|
||||
.requestPowerState(request, waitForNegativeProximity);
|
||||
final DisplayGroup displayGroup = mLogicalDisplayMapper.getDisplayGroupLocked(
|
||||
groupId);
|
||||
if (displayGroup == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final int size = displayGroup.getSizeLocked();
|
||||
boolean ready = true;
|
||||
for (int i = 0; i < size; i++) {
|
||||
final DisplayPowerController displayPowerController =
|
||||
mDisplayPowerControllers.get(displayGroup.getIdLocked(i));
|
||||
ready &= displayPowerController.requestPowerState(request,
|
||||
waitForNegativeProximity);
|
||||
}
|
||||
|
||||
return ready;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2731,6 +2795,16 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDisplayGroupListener(DisplayGroupListener listener) {
|
||||
mDisplayGroupListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterDisplayGroupListener(DisplayGroupListener listener) {
|
||||
mDisplayGroupListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceControl.ScreenshotHardwareBuffer systemScreenshot(int displayId) {
|
||||
return systemScreenshotInternal(displayId);
|
||||
|
||||
@@ -55,6 +55,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
public static final int LOGICAL_DISPLAY_EVENT_SWAPPED = 4;
|
||||
public static final int LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED = 5;
|
||||
|
||||
public static final int DISPLAY_GROUP_EVENT_ADDED = 1;
|
||||
public static final int DISPLAY_GROUP_EVENT_CHANGED = 2;
|
||||
public static final int DISPLAY_GROUP_EVENT_REMOVED = 3;
|
||||
|
||||
/**
|
||||
* Temporary display info, used for comparing display configurations.
|
||||
*/
|
||||
@@ -99,7 +103,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
private int mNextNonDefaultGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
|
||||
|
||||
/** A mapping from logical display id to display group. */
|
||||
private final SparseArray<DisplayGroup> mDisplayGroups = new SparseArray<>();
|
||||
private final SparseArray<DisplayGroup> mDisplayIdToGroupMap = new SparseArray<>();
|
||||
|
||||
private final DisplayDeviceRepository mDisplayDeviceRepo;
|
||||
private final Listener mListener;
|
||||
@@ -183,7 +187,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
}
|
||||
|
||||
public int getDisplayGroupIdLocked(int displayId) {
|
||||
final DisplayGroup displayGroup = mDisplayGroups.get(displayId);
|
||||
final DisplayGroup displayGroup = mDisplayIdToGroupMap.get(displayId);
|
||||
if (displayGroup != null) {
|
||||
return displayGroup.getGroupId();
|
||||
}
|
||||
@@ -191,6 +195,18 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public DisplayGroup getDisplayGroupLocked(int groupId) {
|
||||
final int size = mDisplayIdToGroupMap.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final DisplayGroup displayGroup = mDisplayIdToGroupMap.valueAt(i);
|
||||
if (displayGroup.getGroupId() == groupId) {
|
||||
return displayGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void dumpLocked(PrintWriter pw) {
|
||||
pw.println("LogicalDisplayMapper:");
|
||||
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
|
||||
@@ -320,7 +336,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
final int groupId = assignDisplayGroupIdLocked(isDefault);
|
||||
displayGroup = new DisplayGroup(groupId);
|
||||
} else {
|
||||
displayGroup = mDisplayGroups.get(Display.DEFAULT_DISPLAY);
|
||||
displayGroup = mDisplayIdToGroupMap.get(Display.DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
|
||||
@@ -335,11 +351,23 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
|
||||
mLogicalDisplays.put(displayId, display);
|
||||
|
||||
displayGroup.addDisplay(display);
|
||||
mDisplayGroups.append(displayId, displayGroup);
|
||||
displayGroup.addDisplayLocked(display);
|
||||
mDisplayIdToGroupMap.append(displayId, displayGroup);
|
||||
|
||||
if (addNewDisplayGroup) {
|
||||
// Group added events happen before Logical Display added events.
|
||||
mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
|
||||
LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED);
|
||||
}
|
||||
|
||||
mListener.onLogicalDisplayEventLocked(display,
|
||||
LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED);
|
||||
|
||||
if (!addNewDisplayGroup) {
|
||||
// Group changed events happen after Logical Display added events.
|
||||
mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
|
||||
LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,33 +384,47 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
DisplayEventReceiver.FrameRateOverride[] frameRatesOverrides =
|
||||
display.getFrameRateOverrides();
|
||||
display.updateLocked(mDisplayDeviceRepo);
|
||||
final DisplayGroup changedDisplayGroup;
|
||||
if (!display.isValidLocked()) {
|
||||
mLogicalDisplays.removeAt(i);
|
||||
mDisplayGroups.removeReturnOld(displayId).removeDisplay(display);
|
||||
final DisplayGroup displayGroup = mDisplayIdToGroupMap.removeReturnOld(displayId);
|
||||
displayGroup.removeDisplayLocked(display);
|
||||
|
||||
mListener.onLogicalDisplayEventLocked(display,
|
||||
LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED);
|
||||
|
||||
changedDisplayGroup = displayGroup;
|
||||
} else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
|
||||
final int flags = display.getDisplayInfoLocked().flags;
|
||||
final DisplayGroup defaultDisplayGroup = mDisplayGroups.get(
|
||||
final DisplayGroup defaultDisplayGroup = mDisplayIdToGroupMap.get(
|
||||
Display.DEFAULT_DISPLAY);
|
||||
if ((flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0) {
|
||||
// The display should have its own DisplayGroup.
|
||||
if (defaultDisplayGroup.removeDisplay(display)) {
|
||||
if (defaultDisplayGroup.removeDisplayLocked(display)) {
|
||||
final int groupId = assignDisplayGroupIdLocked(false);
|
||||
final DisplayGroup displayGroup = new DisplayGroup(groupId);
|
||||
displayGroup.addDisplay(display);
|
||||
mDisplayGroups.append(display.getDisplayIdLocked(), displayGroup);
|
||||
displayGroup.addDisplayLocked(display);
|
||||
display.updateDisplayGroupIdLocked(groupId);
|
||||
mDisplayIdToGroupMap.append(display.getDisplayIdLocked(), displayGroup);
|
||||
mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
|
||||
LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED);
|
||||
changedDisplayGroup = defaultDisplayGroup;
|
||||
} else {
|
||||
changedDisplayGroup = null;
|
||||
}
|
||||
} else {
|
||||
// The display should be a part of the default DisplayGroup.
|
||||
final DisplayGroup displayGroup = mDisplayGroups.get(displayId);
|
||||
final DisplayGroup displayGroup = mDisplayIdToGroupMap.get(displayId);
|
||||
if (displayGroup != defaultDisplayGroup) {
|
||||
displayGroup.removeDisplay(display);
|
||||
defaultDisplayGroup.addDisplay(display);
|
||||
mDisplayGroups.put(displayId, defaultDisplayGroup);
|
||||
displayGroup.removeDisplayLocked(display);
|
||||
defaultDisplayGroup.addDisplayLocked(display);
|
||||
display.updateDisplayGroupIdLocked(defaultDisplayGroup.getGroupId());
|
||||
mListener.onDisplayGroupEventLocked(defaultDisplayGroup.getGroupId(),
|
||||
LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED);
|
||||
mDisplayIdToGroupMap.put(displayId, defaultDisplayGroup);
|
||||
changedDisplayGroup = displayGroup;
|
||||
} else {
|
||||
changedDisplayGroup = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,6 +436,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
} else if (!display.getPendingFrameRateOverrideUids().isEmpty()) {
|
||||
mListener.onLogicalDisplayEventLocked(display,
|
||||
LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED);
|
||||
changedDisplayGroup = null;
|
||||
} else {
|
||||
// While applications shouldn't know nor care about the non-overridden info, we
|
||||
// still need to let WindowManager know so it can update its own internal state for
|
||||
@@ -403,6 +446,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
mListener.onLogicalDisplayEventLocked(display,
|
||||
LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CHANGED);
|
||||
}
|
||||
changedDisplayGroup = null;
|
||||
}
|
||||
|
||||
// CHANGED and REMOVED DisplayGroup events should always fire after Display events.
|
||||
if (changedDisplayGroup != null) {
|
||||
final int event = changedDisplayGroup.isEmptyLocked()
|
||||
? LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED
|
||||
: LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED;
|
||||
mListener.onDisplayGroupEventLocked(changedDisplayGroup.getGroupId(), event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -438,6 +490,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
|
||||
public interface Listener {
|
||||
void onLogicalDisplayEventLocked(LogicalDisplay display, int event);
|
||||
void onDisplayGroupEventLocked(int groupId, int event);
|
||||
void onTraversalRequested();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2892,8 +2892,8 @@ public final class PowerManagerService extends SystemService
|
||||
PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
||||
}
|
||||
|
||||
mDisplayReady = mDisplayManagerInternal.requestPowerState(displayPowerRequest,
|
||||
mRequestWaitForNegativeProximity);
|
||||
mDisplayReady = mDisplayManagerInternal.requestPowerState(Display.DEFAULT_DISPLAY_GROUP,
|
||||
displayPowerRequest, mRequestWaitForNegativeProximity);
|
||||
mRequestWaitForNegativeProximity = false;
|
||||
|
||||
if (DEBUG_SPEW) {
|
||||
|
||||
@@ -179,7 +179,8 @@ public class PowerManagerServiceTest {
|
||||
.thenReturn(mPowerSaveState);
|
||||
when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(false);
|
||||
when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(false);
|
||||
when(mDisplayManagerInternalMock.requestPowerState(any(), anyBoolean())).thenReturn(true);
|
||||
when(mDisplayManagerInternalMock.requestPowerState(anyInt(), any(), anyBoolean()))
|
||||
.thenReturn(true);
|
||||
when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), anyString())).thenReturn("");
|
||||
when(mAmbientDisplayConfigurationMock.ambientDisplayAvailable()).thenReturn(true);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user