Loading services/core/java/com/android/server/display/DisplayModeDirector.java +70 −11 Original line number Diff line number Diff line Loading @@ -153,7 +153,7 @@ public class DisplayModeDirector { updateVoteLocked(displayId, priority, vote); } }; mSensorObserver = new SensorObserver(context, ballotBox); mSensorObserver = new SensorObserver(context, ballotBox, injector); mHbmObserver = new HbmObserver(injector, ballotBox, BackgroundThread.getHandler()); mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings(); mDeviceConfig = injector.getDeviceConfig(); Loading Loading @@ -2127,27 +2127,34 @@ public class DisplayModeDirector { } } private static class SensorObserver implements ProximityActiveListener { private static final String PROXIMITY_SENSOR_NAME = null; private static final String PROXIMITY_SENSOR_TYPE = Sensor.STRING_TYPE_PROXIMITY; private final class SensorObserver implements ProximityActiveListener, DisplayManager.DisplayListener { private final String mProximitySensorName = null; private final String mProximitySensorType = Sensor.STRING_TYPE_PROXIMITY; private final BallotBox mBallotBox; private final Context mContext; private final Injector mInjector; private DisplayManager mDisplayManager; private DisplayManagerInternal mDisplayManagerInternal; private boolean mIsProxActive = false; private final SparseBooleanArray mDozeStateByDisplay; SensorObserver(Context context, BallotBox ballotBox) { SensorObserver(Context context, BallotBox ballotBox, Injector injector) { mContext = context; mBallotBox = ballotBox; mInjector = injector; mDozeStateByDisplay = new SparseBooleanArray(); } @Override public void onProximityActive(boolean isActive) { synchronized (mLock) { if (mIsProxActive != isActive) { mIsProxActive = isActive; recalculateVotes(); recalculateVotesLocked(); } } } Loading @@ -2158,17 +2165,27 @@ public class DisplayModeDirector { final SensorManagerInternal sensorManager = LocalServices.getService(SensorManagerInternal.class); sensorManager.addProximityActiveListener(BackgroundThread.getExecutor(), this); synchronized (mLock) { for (Display d : mDisplayManager.getDisplays()) { mDozeStateByDisplay.put(d.getDisplayId(), mInjector.isDozeState(d)); } } mInjector.registerDisplayListener(this, BackgroundThread.getHandler(), DisplayManager.EVENT_FLAG_DISPLAY_ADDED | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED); } private void recalculateVotes() { private void recalculateVotesLocked() { final Display[] displays = mDisplayManager.getDisplays(); for (Display d : displays) { int displayId = d.getDisplayId(); Vote vote = null; if (mIsProxActive) { if (mIsProxActive && !mDozeStateByDisplay.get(displayId)) { final RefreshRateRange rate = mDisplayManagerInternal.getRefreshRateForDisplayAndSensor( displayId, PROXIMITY_SENSOR_NAME, PROXIMITY_SENSOR_TYPE); displayId, mProximitySensorName, mProximitySensorType); if (rate != null) { vote = Vote.forRefreshRates(rate.min, rate.max); } Loading @@ -2180,6 +2197,41 @@ public class DisplayModeDirector { void dumpLocked(PrintWriter pw) { pw.println(" SensorObserver"); pw.println(" mIsProxActive=" + mIsProxActive); pw.println(" mDozeStateByDisplay:"); for (int i = 0; i < mDozeStateByDisplay.size(); i++) { final int id = mDozeStateByDisplay.keyAt(i); final boolean dozed = mDozeStateByDisplay.valueAt(i); pw.println(" " + id + " -> " + dozed); } } @Override public void onDisplayAdded(int displayId) { boolean isDozeState = mInjector.isDozeState(mDisplayManager.getDisplay(displayId)); synchronized (mLock) { mDozeStateByDisplay.put(displayId, isDozeState); recalculateVotesLocked(); } } @Override public void onDisplayChanged(int displayId) { boolean wasDozeState = mDozeStateByDisplay.get(displayId); synchronized (mLock) { mDozeStateByDisplay.put(displayId, mInjector.isDozeState(mDisplayManager.getDisplay(displayId))); if (wasDozeState != mDozeStateByDisplay.get(displayId)) { recalculateVotesLocked(); } } } @Override public void onDisplayRemoved(int displayId) { synchronized (mLock) { mDozeStateByDisplay.delete(displayId); recalculateVotesLocked(); } } } Loading Loading @@ -2411,6 +2463,8 @@ public class DisplayModeDirector { Handler handler, long flags); BrightnessInfo getBrightnessInfo(int displayId); boolean isDozeState(Display d); } @VisibleForTesting Loading Loading @@ -2463,6 +2517,11 @@ public class DisplayModeDirector { return null; } @Override public boolean isDozeState(Display d) { return Display.isDozeState(d.getState()); } private DisplayManager getDisplayManager() { if (mDisplayManager == null) { mDisplayManager = mContext.getSystemService(DisplayManager.class); Loading services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +43 −5 Original line number Diff line number Diff line Loading @@ -1340,11 +1340,19 @@ public class DisplayModeDirectorTest { createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0); director.start(createMockSensorManager()); ArgumentCaptor<ProximityActiveListener> captor = ArgumentCaptor<ProximityActiveListener> ProximityCaptor = ArgumentCaptor.forClass(ProximityActiveListener.class); verify(mSensorManagerInternalMock).addProximityActiveListener(any(Executor.class), captor.capture()); ProximityActiveListener listener = captor.getValue(); ProximityCaptor.capture()); ProximityActiveListener proximityListener = ProximityCaptor.getValue(); ArgumentCaptor<DisplayListener> DisplayCaptor = ArgumentCaptor.forClass(DisplayListener.class); verify(mInjector).registerDisplayListener(DisplayCaptor.capture(), any(Handler.class), eq(DisplayManager.EVENT_FLAG_DISPLAY_ADDED | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED)); DisplayListener displayListener = DisplayCaptor.getValue(); // Verify that there is no proximity vote initially Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); Loading @@ -1353,13 +1361,38 @@ public class DisplayModeDirectorTest { when(mDisplayManagerInternalMock.getRefreshRateForDisplayAndSensor(eq(DISPLAY_ID), eq(null), eq(Sensor.STRING_TYPE_PROXIMITY))).thenReturn(new RefreshRateRange(60, 60)); when(mInjector.isDozeState(any(Display.class))).thenReturn(false); // Set the proximity to active and verify that we added a vote. listener.onProximityActive(true); proximityListener.onProximityActive(true); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertVoteForRefreshRate(vote, 60.f); // Set the display state to doze and verify that the vote is gone when(mInjector.isDozeState(any(Display.class))).thenReturn(true); displayListener.onDisplayAdded(DISPLAY_ID); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertNull(vote); // Set the display state to on and verify that we added the vote back. when(mInjector.isDozeState(any(Display.class))).thenReturn(false); displayListener.onDisplayChanged(DISPLAY_ID); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertVoteForRefreshRate(vote, 60.f); // Set the display state to doze and verify that the vote is gone when(mInjector.isDozeState(any(Display.class))).thenReturn(true); displayListener.onDisplayAdded(DISPLAY_ID); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertNull(vote); // Remove the display to cause the doze state to be removed displayListener.onDisplayRemoved(DISPLAY_ID); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertVoteForRefreshRate(vote, 60.f); // Turn prox off and verify vote is gone. listener.onProximityActive(false); proximityListener.onProximityActive(false); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertNull(vote); } Loading Loading @@ -1710,6 +1743,11 @@ public class DisplayModeDirectorTest { return null; } @Override public boolean isDozeState(Display d) { return false; } void notifyPeakRefreshRateChanged() { if (mPeakRefreshRateObserver != null) { mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/, Loading Loading
services/core/java/com/android/server/display/DisplayModeDirector.java +70 −11 Original line number Diff line number Diff line Loading @@ -153,7 +153,7 @@ public class DisplayModeDirector { updateVoteLocked(displayId, priority, vote); } }; mSensorObserver = new SensorObserver(context, ballotBox); mSensorObserver = new SensorObserver(context, ballotBox, injector); mHbmObserver = new HbmObserver(injector, ballotBox, BackgroundThread.getHandler()); mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings(); mDeviceConfig = injector.getDeviceConfig(); Loading Loading @@ -2127,27 +2127,34 @@ public class DisplayModeDirector { } } private static class SensorObserver implements ProximityActiveListener { private static final String PROXIMITY_SENSOR_NAME = null; private static final String PROXIMITY_SENSOR_TYPE = Sensor.STRING_TYPE_PROXIMITY; private final class SensorObserver implements ProximityActiveListener, DisplayManager.DisplayListener { private final String mProximitySensorName = null; private final String mProximitySensorType = Sensor.STRING_TYPE_PROXIMITY; private final BallotBox mBallotBox; private final Context mContext; private final Injector mInjector; private DisplayManager mDisplayManager; private DisplayManagerInternal mDisplayManagerInternal; private boolean mIsProxActive = false; private final SparseBooleanArray mDozeStateByDisplay; SensorObserver(Context context, BallotBox ballotBox) { SensorObserver(Context context, BallotBox ballotBox, Injector injector) { mContext = context; mBallotBox = ballotBox; mInjector = injector; mDozeStateByDisplay = new SparseBooleanArray(); } @Override public void onProximityActive(boolean isActive) { synchronized (mLock) { if (mIsProxActive != isActive) { mIsProxActive = isActive; recalculateVotes(); recalculateVotesLocked(); } } } Loading @@ -2158,17 +2165,27 @@ public class DisplayModeDirector { final SensorManagerInternal sensorManager = LocalServices.getService(SensorManagerInternal.class); sensorManager.addProximityActiveListener(BackgroundThread.getExecutor(), this); synchronized (mLock) { for (Display d : mDisplayManager.getDisplays()) { mDozeStateByDisplay.put(d.getDisplayId(), mInjector.isDozeState(d)); } } mInjector.registerDisplayListener(this, BackgroundThread.getHandler(), DisplayManager.EVENT_FLAG_DISPLAY_ADDED | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED); } private void recalculateVotes() { private void recalculateVotesLocked() { final Display[] displays = mDisplayManager.getDisplays(); for (Display d : displays) { int displayId = d.getDisplayId(); Vote vote = null; if (mIsProxActive) { if (mIsProxActive && !mDozeStateByDisplay.get(displayId)) { final RefreshRateRange rate = mDisplayManagerInternal.getRefreshRateForDisplayAndSensor( displayId, PROXIMITY_SENSOR_NAME, PROXIMITY_SENSOR_TYPE); displayId, mProximitySensorName, mProximitySensorType); if (rate != null) { vote = Vote.forRefreshRates(rate.min, rate.max); } Loading @@ -2180,6 +2197,41 @@ public class DisplayModeDirector { void dumpLocked(PrintWriter pw) { pw.println(" SensorObserver"); pw.println(" mIsProxActive=" + mIsProxActive); pw.println(" mDozeStateByDisplay:"); for (int i = 0; i < mDozeStateByDisplay.size(); i++) { final int id = mDozeStateByDisplay.keyAt(i); final boolean dozed = mDozeStateByDisplay.valueAt(i); pw.println(" " + id + " -> " + dozed); } } @Override public void onDisplayAdded(int displayId) { boolean isDozeState = mInjector.isDozeState(mDisplayManager.getDisplay(displayId)); synchronized (mLock) { mDozeStateByDisplay.put(displayId, isDozeState); recalculateVotesLocked(); } } @Override public void onDisplayChanged(int displayId) { boolean wasDozeState = mDozeStateByDisplay.get(displayId); synchronized (mLock) { mDozeStateByDisplay.put(displayId, mInjector.isDozeState(mDisplayManager.getDisplay(displayId))); if (wasDozeState != mDozeStateByDisplay.get(displayId)) { recalculateVotesLocked(); } } } @Override public void onDisplayRemoved(int displayId) { synchronized (mLock) { mDozeStateByDisplay.delete(displayId); recalculateVotesLocked(); } } } Loading Loading @@ -2411,6 +2463,8 @@ public class DisplayModeDirector { Handler handler, long flags); BrightnessInfo getBrightnessInfo(int displayId); boolean isDozeState(Display d); } @VisibleForTesting Loading Loading @@ -2463,6 +2517,11 @@ public class DisplayModeDirector { return null; } @Override public boolean isDozeState(Display d) { return Display.isDozeState(d.getState()); } private DisplayManager getDisplayManager() { if (mDisplayManager == null) { mDisplayManager = mContext.getSystemService(DisplayManager.class); Loading
services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +43 −5 Original line number Diff line number Diff line Loading @@ -1340,11 +1340,19 @@ public class DisplayModeDirectorTest { createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0); director.start(createMockSensorManager()); ArgumentCaptor<ProximityActiveListener> captor = ArgumentCaptor<ProximityActiveListener> ProximityCaptor = ArgumentCaptor.forClass(ProximityActiveListener.class); verify(mSensorManagerInternalMock).addProximityActiveListener(any(Executor.class), captor.capture()); ProximityActiveListener listener = captor.getValue(); ProximityCaptor.capture()); ProximityActiveListener proximityListener = ProximityCaptor.getValue(); ArgumentCaptor<DisplayListener> DisplayCaptor = ArgumentCaptor.forClass(DisplayListener.class); verify(mInjector).registerDisplayListener(DisplayCaptor.capture(), any(Handler.class), eq(DisplayManager.EVENT_FLAG_DISPLAY_ADDED | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED)); DisplayListener displayListener = DisplayCaptor.getValue(); // Verify that there is no proximity vote initially Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); Loading @@ -1353,13 +1361,38 @@ public class DisplayModeDirectorTest { when(mDisplayManagerInternalMock.getRefreshRateForDisplayAndSensor(eq(DISPLAY_ID), eq(null), eq(Sensor.STRING_TYPE_PROXIMITY))).thenReturn(new RefreshRateRange(60, 60)); when(mInjector.isDozeState(any(Display.class))).thenReturn(false); // Set the proximity to active and verify that we added a vote. listener.onProximityActive(true); proximityListener.onProximityActive(true); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertVoteForRefreshRate(vote, 60.f); // Set the display state to doze and verify that the vote is gone when(mInjector.isDozeState(any(Display.class))).thenReturn(true); displayListener.onDisplayAdded(DISPLAY_ID); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertNull(vote); // Set the display state to on and verify that we added the vote back. when(mInjector.isDozeState(any(Display.class))).thenReturn(false); displayListener.onDisplayChanged(DISPLAY_ID); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertVoteForRefreshRate(vote, 60.f); // Set the display state to doze and verify that the vote is gone when(mInjector.isDozeState(any(Display.class))).thenReturn(true); displayListener.onDisplayAdded(DISPLAY_ID); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertNull(vote); // Remove the display to cause the doze state to be removed displayListener.onDisplayRemoved(DISPLAY_ID); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertVoteForRefreshRate(vote, 60.f); // Turn prox off and verify vote is gone. listener.onProximityActive(false); proximityListener.onProximityActive(false); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_PROXIMITY); assertNull(vote); } Loading Loading @@ -1710,6 +1743,11 @@ public class DisplayModeDirectorTest { return null; } @Override public boolean isDozeState(Display d) { return false; } void notifyPeakRefreshRateChanged() { if (mPeakRefreshRateObserver != null) { mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/, Loading