summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/display/DisplayManagerInternal.java6
-rw-r--r--services/core/java/com/android/server/display/DisplayGroup.java14
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java7
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplayMapper.java20
-rw-r--r--services/core/java/com/android/server/power/DisplayPowerRequestMapper.java122
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java76
6 files changed, 212 insertions, 33 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index defcab7c3035..5a03adee4eab 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -65,6 +65,12 @@ public abstract class DisplayManagerInternal {
public abstract boolean isProximitySensorAvailable();
/**
+ * Returns the id of the {@link com.android.server.display.DisplayGroup} to which the provided
+ * display belongs.
+ */
+ public abstract int getDisplayGroupId(int displayId);
+
+ /**
* 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.
* This method does not apply any rotation and provides the output in natural orientation.
diff --git a/services/core/java/com/android/server/display/DisplayGroup.java b/services/core/java/com/android/server/display/DisplayGroup.java
index f2413edd1a3a..2ba875813734 100644
--- a/services/core/java/com/android/server/display/DisplayGroup.java
+++ b/services/core/java/com/android/server/display/DisplayGroup.java
@@ -22,10 +22,22 @@ import java.util.List;
/**
* Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and
* operations.
+ * @hide
*/
public class DisplayGroup {
- final List<LogicalDisplay> mDisplays = new ArrayList<>();
+ public static final int DEFAULT = 0;
+
+ private final List<LogicalDisplay> mDisplays = new ArrayList<>();
+ private final int mGroupId;
+
+ DisplayGroup(int groupId) {
+ mGroupId = groupId;
+ }
+
+ int getGroupId() {
+ return mGroupId;
+ }
void addDisplay(LogicalDisplay display) {
if (!mDisplays.contains(display)) {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 004e481354ec..4e60f1ff929e 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2536,6 +2536,13 @@ public final class DisplayManagerService extends SystemService {
}
@Override
+ public int getDisplayGroupId(int displayId) {
+ synchronized (mSyncRoot) {
+ return mLogicalDisplayMapper.getDisplayGroupIdLocked(displayId);
+ }
+ }
+
+ @Override
public SurfaceControl.ScreenshotHardwareBuffer systemScreenshot(int displayId) {
return systemScreenshotInternal(displayId);
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index 45c38b456b0a..6b741709321c 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -94,6 +94,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
private final SparseArray<LogicalDisplay> mLogicalDisplays =
new SparseArray<LogicalDisplay>();
private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
+ private int mNextNonDefaultGroupId = DisplayGroup.DEFAULT + 1;
/** A mapping from logical display id to display group. */
private final SparseArray<DisplayGroup> mDisplayGroups = new SparseArray<>();
@@ -178,6 +179,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
}
}
+ public int getDisplayGroupIdLocked(int displayId) {
+ final DisplayGroup displayGroup = mDisplayGroups.get(displayId);
+ if (displayGroup != null) {
+ return displayGroup.getGroupId();
+ }
+
+ return -1;
+ }
+
public void dumpLocked(PrintWriter pw) {
pw.println("LogicalDisplayMapper:");
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
@@ -309,7 +319,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
final DisplayGroup displayGroup;
if (isDefault || (deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) {
- displayGroup = new DisplayGroup();
+ final int groupId = assignDisplayGroupIdLocked(isDefault);
+ displayGroup = new DisplayGroup(groupId);
} else {
displayGroup = mDisplayGroups.get(Display.DEFAULT_DISPLAY);
}
@@ -345,7 +356,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
if ((flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0) {
// The display should have its own DisplayGroup.
if (defaultDisplayGroup.removeDisplay(display)) {
- final DisplayGroup displayGroup = new DisplayGroup();
+ final int groupId = assignDisplayGroupIdLocked(false);
+ final DisplayGroup displayGroup = new DisplayGroup(groupId);
displayGroup.addDisplay(display);
mDisplayGroups.append(display.getDisplayIdLocked(), displayGroup);
}
@@ -381,6 +393,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
}
+ private int assignDisplayGroupIdLocked(boolean isDefault) {
+ return isDefault ? DisplayGroup.DEFAULT : mNextNonDefaultGroupId++;
+ }
+
private int assignLayerStackLocked(int displayId) {
// Currently layer stacks and display ids are the same.
// This need not be the case.
diff --git a/services/core/java/com/android/server/power/DisplayPowerRequestMapper.java b/services/core/java/com/android/server/power/DisplayPowerRequestMapper.java
new file mode 100644
index 000000000000..6477552eb550
--- /dev/null
+++ b/services/core/java/com/android/server/power/DisplayPowerRequestMapper.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManagerInternal;
+import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
+import android.os.Handler;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+import android.view.Display;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.display.DisplayGroup;
+
+/**
+ * Responsible for creating {@link DisplayPowerRequest}s and associating them with
+ * {@link com.android.server.display.DisplayGroup}s.
+ *
+ * Each {@link com.android.server.display.DisplayGroup} has a single {@link DisplayPowerRequest}
+ * which is used to request power state changes to every display in the group.
+ */
+class DisplayPowerRequestMapper {
+
+ private final Object mLock = new Object();
+
+ /** A mapping from LogicalDisplay Id to DisplayGroup Id. */
+ @GuardedBy("mLock")
+ private final SparseIntArray mDisplayGroupIds = new SparseIntArray();
+
+ /** A mapping from DisplayGroup Id to DisplayPowerRequest. */
+ @GuardedBy("mLock")
+ private final SparseArray<DisplayPowerRequest> mDisplayPowerRequests = new SparseArray<>();
+
+ private final DisplayManagerInternal mDisplayManagerInternal;
+
+ private final DisplayManager.DisplayListener mDisplayListener =
+ new DisplayManager.DisplayListener() {
+
+ @Override
+ public void onDisplayAdded(int displayId) {
+ synchronized (mLock) {
+ if (mDisplayGroupIds.indexOfKey(displayId) >= 0) {
+ return;
+ }
+ final int displayGroupId = mDisplayManagerInternal.getDisplayGroupId(
+ displayId);
+ if (!mDisplayPowerRequests.contains(displayGroupId)) {
+ // A new DisplayGroup was created; create a new DisplayPowerRequest.
+ mDisplayPowerRequests.append(displayGroupId, new DisplayPowerRequest());
+ }
+ mDisplayGroupIds.append(displayId, displayGroupId);
+ }
+ }
+
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ synchronized (mLock) {
+ final int index = mDisplayGroupIds.indexOfKey(displayId);
+ if (index < 0) {
+ return;
+ }
+ final int displayGroupId = mDisplayGroupIds.valueAt(index);
+ mDisplayGroupIds.removeAt(index);
+
+ if (mDisplayGroupIds.indexOfValue(displayGroupId) < 0) {
+ // The DisplayGroup no longer exists; delete the DisplayPowerRequest.
+ mDisplayPowerRequests.delete(displayGroupId);
+ }
+ }
+ }
+
+ @Override
+ public void onDisplayChanged(int displayId) {
+ synchronized (mLock) {
+ final int newDisplayGroupId = mDisplayManagerInternal.getDisplayGroupId(
+ displayId);
+ final int oldDisplayGroupId = mDisplayGroupIds.get(displayId);
+
+ if (!mDisplayPowerRequests.contains(newDisplayGroupId)) {
+ // A new DisplayGroup was created; create a new DisplayPowerRequest.
+ mDisplayPowerRequests.append(newDisplayGroupId,
+ new DisplayPowerRequest());
+ }
+ mDisplayGroupIds.put(displayId, newDisplayGroupId);
+
+ if (mDisplayGroupIds.indexOfValue(oldDisplayGroupId) < 0) {
+ // The DisplayGroup no longer exists; delete the DisplayPowerRequest.
+ mDisplayPowerRequests.delete(oldDisplayGroupId);
+ }
+ }
+ }
+ };
+
+ DisplayPowerRequestMapper(DisplayManager displayManager,
+ DisplayManagerInternal displayManagerInternal, Handler handler) {
+ mDisplayManagerInternal = displayManagerInternal;
+ displayManager.registerDisplayListener(mDisplayListener, handler);
+ mDisplayPowerRequests.append(DisplayGroup.DEFAULT, new DisplayPowerRequest());
+ mDisplayGroupIds.append(Display.DEFAULT_DISPLAY, DisplayGroup.DEFAULT);
+ }
+
+ DisplayPowerRequest get(int displayId) {
+ synchronized (mLock) {
+ return mDisplayPowerRequests.get(mDisplayGroupIds.get(displayId));
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index ccd659dcf5a4..955e1cdfeaaa 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -42,6 +42,7 @@ import android.database.ContentObserver;
import android.hardware.SensorManager;
import android.hardware.SystemSensorManager;
import android.hardware.display.AmbientDisplayConfiguration;
+import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.hardware.power.Boost;
@@ -348,9 +349,9 @@ public final class PowerManagerService extends SystemService
// A bitfield that summarizes the effect of the user activity timer.
private int mUserActivitySummary;
- // The desired display power state. The actual state may lag behind the
+ // Manages the desired power state of displays. The actual state may lag behind the
// requested because it is updated asynchronously by the display power controller.
- private final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
+ private DisplayPowerRequestMapper mDisplayPowerRequestMapper;
// True if the display power state has been fully applied, which means the display
// is actually on or actually off or whatever was requested.
@@ -1054,6 +1055,8 @@ public final class PowerManagerService extends SystemService
mPolicy = getLocalService(WindowManagerPolicy.class);
mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
mAttentionDetector.systemReady(mContext);
+ mDisplayPowerRequestMapper = new DisplayPowerRequestMapper(mContext.getSystemService(
+ DisplayManager.class), mDisplayManagerInternal, mHandler);
SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
@@ -2296,10 +2299,12 @@ public final class PowerManagerService extends SystemService
&& mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
if (now < nextTimeout) {
- if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT
- || mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) {
+ final DisplayPowerRequest displayPowerRequest =
+ mDisplayPowerRequestMapper.get(Display.DEFAULT_DISPLAY);
+ if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT
+ || displayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) {
mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
- } else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
+ } else if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
}
}
@@ -2771,11 +2776,13 @@ public final class PowerManagerService extends SystemService
* Returns true if the device is allowed to dream in its current state.
*/
private boolean canDreamLocked() {
+ final DisplayPowerRequest displayPowerRequest =
+ mDisplayPowerRequestMapper.get(Display.DEFAULT_DISPLAY);
if (getWakefulnessLocked() != WAKEFULNESS_DREAMING
|| !mDreamsSupportedConfig
|| !mDreamsEnabledSetting
- || !mDisplayPowerRequest.isBrightOrDim()
- || mDisplayPowerRequest.isVr()
+ || !displayPowerRequest.isBrightOrDim()
+ || displayPowerRequest.isVr()
|| (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
| USER_ACTIVITY_SCREEN_DIM | USER_ACTIVITY_SCREEN_DREAM)) == 0
|| !mBootCompleted) {
@@ -2826,7 +2833,9 @@ public final class PowerManagerService extends SystemService
sQuiescent = false;
}
- mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
+ final DisplayPowerRequest displayPowerRequest = mDisplayPowerRequestMapper.get(
+ Display.DEFAULT_DISPLAY);
+ displayPowerRequest.policy = getDesiredScreenPolicyLocked();
// Determine appropriate screen brightness and auto-brightness adjustments.
final boolean autoBrightness;
@@ -2846,39 +2855,39 @@ public final class PowerManagerService extends SystemService
}
// Update display power request.
- mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
- mDisplayPowerRequest.useAutoBrightness = autoBrightness;
- mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
- mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
+ displayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
+ displayPowerRequest.useAutoBrightness = autoBrightness;
+ displayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
+ displayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
- updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);
+ updatePowerRequestFromBatterySaverPolicy(displayPowerRequest);
- if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
- mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
+ if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
+ displayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0
&& !mDrawWakeLockOverrideFromSidekick) {
- if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {
- mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;
+ if (displayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {
+ displayPowerRequest.dozeScreenState = Display.STATE_DOZE;
}
- if (mDisplayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) {
- mDisplayPowerRequest.dozeScreenState = Display.STATE_ON;
+ if (displayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) {
+ displayPowerRequest.dozeScreenState = Display.STATE_ON;
}
}
- mDisplayPowerRequest.dozeScreenBrightness =
+ displayPowerRequest.dozeScreenBrightness =
mDozeScreenBrightnessOverrideFromDreamManagerFloat;
} else {
- mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
- mDisplayPowerRequest.dozeScreenBrightness =
+ displayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
+ displayPowerRequest.dozeScreenBrightness =
PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
- mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
+ mDisplayReady = mDisplayManagerInternal.requestPowerState(displayPowerRequest,
mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
if (DEBUG_SPEW) {
Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady
- + ", policy=" + mDisplayPowerRequest.policy
+ + ", policy=" + displayPowerRequest.policy
+ ", mWakefulness=" + getWakefulnessLocked()
+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
@@ -3049,7 +3058,9 @@ public final class PowerManagerService extends SystemService
final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
final boolean autoSuspend = !needDisplaySuspendBlocker;
- final boolean interactive = mDisplayPowerRequest.isBrightOrDim();
+ final DisplayPowerRequest displayPowerRequest = mDisplayPowerRequestMapper.get(
+ Display.DEFAULT_DISPLAY);
+ final boolean interactive = displayPowerRequest.isBrightOrDim();
// Disable auto-suspend if needed.
// FIXME We should consider just leaving auto-suspend enabled forever since
@@ -3108,19 +3119,21 @@ public final class PowerManagerService extends SystemService
if (!mDisplayReady) {
return true;
}
- if (mDisplayPowerRequest.isBrightOrDim()) {
+ final DisplayPowerRequest displayPowerRequest = mDisplayPowerRequestMapper.get(
+ Display.DEFAULT_DISPLAY);
+ if (displayPowerRequest.isBrightOrDim()) {
// If we asked for the screen to be on but it is off due to the proximity
// sensor then we may suspend but only if the configuration allows it.
// On some hardware it may not be safe to suspend because the proximity
// sensor may not be correctly configured as a wake-up source.
- if (!mDisplayPowerRequest.useProximitySensor || !mProximityPositive
+ if (!displayPowerRequest.useProximitySensor || !mProximityPositive
|| !mSuspendWhenScreenOffDueToProximityConfig) {
return true;
}
}
- if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE
- && mDisplayPowerRequest.dozeScreenState == Display.STATE_ON) {
+ if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE
+ && displayPowerRequest.dozeScreenState == Display.STATE_ON) {
// Although we are in DOZE and would normally allow the device to suspend,
// the doze service has explicitly requested the display to remain in the ON
// state which means we should hold the display suspend blocker.
@@ -5575,7 +5588,10 @@ public final class PowerManagerService extends SystemService
// DisplayPowerController only reports proximity positive (near) if it's
// positive and the proximity wasn't already being ignored. So it reliably
// also tells us that we're not already ignoring the proximity sensor.
- if (mDisplayPowerRequest.useProximitySensor && mProximityPositive) {
+
+ final DisplayPowerRequest displayPowerRequest =
+ mDisplayPowerRequestMapper.get(Display.DEFAULT_DISPLAY);
+ if (displayPowerRequest.useProximitySensor && mProximityPositive) {
mDisplayManagerInternal.ignoreProximitySensorUntilChanged();
return true;
}