Merge "Add DisplayModeDirector support for UDFPS" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
22f7cd1311
@@ -24,6 +24,13 @@ package android.hardware.fingerprint;
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IUdfpsHbmListener {
|
||||
|
||||
/** HBM that applies to the whole screen. */
|
||||
const int GLOBAL_HBM = 0;
|
||||
|
||||
/** HBM that only applies to a portion of the screen. */
|
||||
const int LOCAL_HBM = 1;
|
||||
|
||||
/**
|
||||
* UdfpsController will call this method when the HBM is enabled.
|
||||
*
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui.biometrics;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -26,10 +27,10 @@ import java.lang.annotation.RetentionPolicy;
|
||||
*/
|
||||
public final class HbmTypes {
|
||||
/** HBM that applies to the whole screen. */
|
||||
public static final int GLOBAL_HBM = 0;
|
||||
public static final int GLOBAL_HBM = IUdfpsHbmListener.GLOBAL_HBM;
|
||||
|
||||
/** HBM that only applies to a portion of the screen. */
|
||||
public static final int LOCAL_HBM = 1;
|
||||
public static final int LOCAL_HBM = IUdfpsHbmListener.LOCAL_HBM;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({GLOBAL_HBM, LOCAL_HBM})
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@@ -40,14 +41,17 @@ import android.util.IndentingPrintWriter;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.display.utils.AmbientFilter;
|
||||
import com.android.server.display.utils.AmbientFilterFactory;
|
||||
import com.android.server.statusbar.StatusBarManagerInternal;
|
||||
import com.android.server.utils.DeviceConfigInterface;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -93,6 +97,7 @@ public class DisplayModeDirector {
|
||||
private final AppRequestObserver mAppRequestObserver;
|
||||
private final SettingsObserver mSettingsObserver;
|
||||
private final DisplayObserver mDisplayObserver;
|
||||
private final UdfpsObserver mUdfpsObserver;
|
||||
private final DeviceConfigInterface mDeviceConfig;
|
||||
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
|
||||
|
||||
@@ -133,6 +138,7 @@ public class DisplayModeDirector {
|
||||
mSettingsObserver = new SettingsObserver(context, handler);
|
||||
mDisplayObserver = new DisplayObserver(context, handler);
|
||||
mBrightnessObserver = new BrightnessObserver(context, handler);
|
||||
mUdfpsObserver = new UdfpsObserver();
|
||||
mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
|
||||
mDeviceConfig = injector.getDeviceConfig();
|
||||
mAlwaysRespectAppRequest = false;
|
||||
@@ -149,6 +155,7 @@ public class DisplayModeDirector {
|
||||
mSettingsObserver.observe();
|
||||
mDisplayObserver.observe();
|
||||
mBrightnessObserver.observe(sensorManager);
|
||||
mUdfpsObserver.observe();
|
||||
synchronized (mLock) {
|
||||
// We may have a listener already registered before the call to start, so go ahead and
|
||||
// notify them to pick up our newly initialized state.
|
||||
@@ -545,6 +552,7 @@ public class DisplayModeDirector {
|
||||
mSettingsObserver.dumpLocked(pw);
|
||||
mAppRequestObserver.dumpLocked(pw);
|
||||
mBrightnessObserver.dumpLocked(pw);
|
||||
mUdfpsObserver.dumpLocked(pw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,7 +574,6 @@ public class DisplayModeDirector {
|
||||
}
|
||||
final SparseArray<Vote> votes = getOrCreateVotesByDisplay(displayId);
|
||||
|
||||
Vote currentVote = votes.get(priority);
|
||||
if (vote != null) {
|
||||
votes.put(priority, vote);
|
||||
} else {
|
||||
@@ -649,6 +656,11 @@ public class DisplayModeDirector {
|
||||
return mSettingsObserver;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
UdfpsObserver getUdpfsObserver() {
|
||||
return mUdfpsObserver;
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings(
|
||||
@@ -928,11 +940,15 @@ public class DisplayModeDirector {
|
||||
// LOW_POWER_MODE force display to [0, 60HZ] if Settings.Global.LOW_POWER_MODE is on.
|
||||
public static final int PRIORITY_LOW_POWER_MODE = 6;
|
||||
|
||||
// The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order
|
||||
// to function, so this needs to be the highest priority of all votes.
|
||||
public static final int PRIORITY_UDFPS = 7;
|
||||
|
||||
// Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
|
||||
// APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
|
||||
|
||||
public static final int MIN_PRIORITY = PRIORITY_DEFAULT_REFRESH_RATE;
|
||||
public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
|
||||
public static final int MAX_PRIORITY = PRIORITY_UDFPS;
|
||||
|
||||
// The cutoff for the app request refresh rate range. Votes with priorities lower than this
|
||||
// value will not be considered when constructing the app request refresh rate range.
|
||||
@@ -989,6 +1005,9 @@ public class DisplayModeDirector {
|
||||
return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";
|
||||
case PRIORITY_LOW_POWER_MODE:
|
||||
return "PRIORITY_LOW_POWER_MODE";
|
||||
case PRIORITY_UDFPS:
|
||||
return "PRIORITY_UDFPS";
|
||||
|
||||
default:
|
||||
return Integer.toString(priority);
|
||||
}
|
||||
@@ -1162,7 +1181,7 @@ public class DisplayModeDirector {
|
||||
}
|
||||
|
||||
final class AppRequestObserver {
|
||||
private SparseArray<Display.Mode> mAppRequestedModeByDisplay;
|
||||
private final SparseArray<Display.Mode> mAppRequestedModeByDisplay;
|
||||
|
||||
AppRequestObserver() {
|
||||
mAppRequestedModeByDisplay = new SparseArray<>();
|
||||
@@ -1196,7 +1215,6 @@ public class DisplayModeDirector {
|
||||
|
||||
updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, refreshRateVote);
|
||||
updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote);
|
||||
return;
|
||||
}
|
||||
|
||||
private Display.Mode findModeByIdLocked(int displayId, int modeId) {
|
||||
@@ -1328,7 +1346,8 @@ public class DisplayModeDirector {
|
||||
|
||||
private SensorManager mSensorManager;
|
||||
private Sensor mLightSensor;
|
||||
private LightSensorEventListener mLightSensorListener = new LightSensorEventListener();
|
||||
private final LightSensorEventListener mLightSensorListener =
|
||||
new LightSensorEventListener();
|
||||
// Take it as low brightness before valid sensor data comes
|
||||
private float mAmbientLux = -1.0f;
|
||||
private AmbientFilter mAmbientFilter;
|
||||
@@ -1559,8 +1578,7 @@ public class DisplayModeDirector {
|
||||
mLightSensorListener.dumpLocked(pw);
|
||||
|
||||
if (mAmbientFilter != null) {
|
||||
IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
|
||||
ipw.setIndent(" ");
|
||||
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
|
||||
mAmbientFilter.dump(ipw);
|
||||
}
|
||||
}
|
||||
@@ -1907,7 +1925,7 @@ public class DisplayModeDirector {
|
||||
return false;
|
||||
}
|
||||
|
||||
private Runnable mInjectSensorEventRunnable = new Runnable() {
|
||||
private final Runnable mInjectSensorEventRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long now = SystemClock.uptimeMillis();
|
||||
@@ -1926,6 +1944,83 @@ public class DisplayModeDirector {
|
||||
}
|
||||
}
|
||||
|
||||
private class UdfpsObserver extends IUdfpsHbmListener.Stub {
|
||||
private final SparseBooleanArray mLocalHbmEnabled = new SparseBooleanArray();
|
||||
private final SparseBooleanArray mGlobalHbmEnabled = new SparseBooleanArray();
|
||||
|
||||
public void observe() {
|
||||
StatusBarManagerInternal statusBar =
|
||||
LocalServices.getService(StatusBarManagerInternal.class);
|
||||
statusBar.setUdfpsHbmListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHbmEnabled(int hbmType, int displayId) {
|
||||
synchronized (mLock) {
|
||||
updateHbmStateLocked(hbmType, displayId, true /*enabled*/);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHbmDisabled(int hbmType, int displayId) {
|
||||
synchronized (mLock) {
|
||||
updateHbmStateLocked(hbmType, displayId, false /*enabled*/);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHbmStateLocked(int hbmType, int displayId, boolean enabled) {
|
||||
switch (hbmType) {
|
||||
case UdfpsObserver.LOCAL_HBM:
|
||||
mLocalHbmEnabled.put(displayId, enabled);
|
||||
break;
|
||||
case UdfpsObserver.GLOBAL_HBM:
|
||||
mGlobalHbmEnabled.put(displayId, enabled);
|
||||
break;
|
||||
default:
|
||||
Slog.w(TAG, "Unknown HBM type reported. Ignoring.");
|
||||
return;
|
||||
}
|
||||
updateVoteLocked(displayId);
|
||||
}
|
||||
|
||||
private void updateVoteLocked(int displayId) {
|
||||
final Vote vote;
|
||||
if (mGlobalHbmEnabled.get(displayId)) {
|
||||
vote = Vote.forRefreshRates(60f, 60f);
|
||||
} else if (mLocalHbmEnabled.get(displayId)) {
|
||||
Display.Mode[] modes = mSupportedModesByDisplay.get(displayId);
|
||||
float maxRefreshRate = 0f;
|
||||
for (Display.Mode mode : modes) {
|
||||
if (mode.getRefreshRate() > maxRefreshRate) {
|
||||
maxRefreshRate = mode.getRefreshRate();
|
||||
}
|
||||
}
|
||||
vote = Vote.forRefreshRates(maxRefreshRate, maxRefreshRate);
|
||||
} else {
|
||||
vote = null;
|
||||
}
|
||||
|
||||
DisplayModeDirector.this.updateVoteLocked(displayId, Vote.PRIORITY_UDFPS, vote);
|
||||
}
|
||||
|
||||
void dumpLocked(PrintWriter pw) {
|
||||
pw.println(" UdfpsObserver");
|
||||
pw.println(" mLocalHbmEnabled: ");
|
||||
for (int i = 0; i < mLocalHbmEnabled.size(); i++) {
|
||||
final int displayId = mLocalHbmEnabled.keyAt(i);
|
||||
final String enabled = mLocalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
|
||||
pw.println(" Display " + displayId + ": " + enabled);
|
||||
}
|
||||
pw.println(" mGlobalHbmEnabled: ");
|
||||
for (int i = 0; i < mGlobalHbmEnabled.size(); i++) {
|
||||
final int displayId = mGlobalHbmEnabled.keyAt(i);
|
||||
final String enabled = mGlobalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
|
||||
pw.println(" Display " + displayId + ": " + enabled);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener {
|
||||
public DeviceConfigDisplaySettings() {
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.statusbar;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ITransientNotificationCallback;
|
||||
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
@@ -166,4 +167,11 @@ public interface StatusBarManagerInternal {
|
||||
* boolean)
|
||||
*/
|
||||
void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable);
|
||||
|
||||
/**
|
||||
* Sets the system-wide listener for UDFPS HBM status changes.
|
||||
*
|
||||
* @see com.android.internal.statusbar.IStatusBar#setUdfpsHbmListener(IUdfpsHbmListener)
|
||||
*/
|
||||
void setUdfpsHbmListener(IUdfpsHbmListener listener);
|
||||
}
|
||||
|
||||
@@ -107,15 +107,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private Handler mHandler = new Handler();
|
||||
private final Handler mHandler = new Handler();
|
||||
private NotificationDelegate mNotificationDelegate;
|
||||
private volatile IStatusBar mBar;
|
||||
private ArrayMap<String, StatusBarIcon> mIcons = new ArrayMap<>();
|
||||
private final ArrayMap<String, StatusBarIcon> mIcons = new ArrayMap<>();
|
||||
|
||||
// for disabling the status bar
|
||||
private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
|
||||
private GlobalActionsProvider.GlobalActionsListener mGlobalActionListener;
|
||||
private IBinder mSysUiVisToken = new Binder();
|
||||
private final IBinder mSysUiVisToken = new Binder();
|
||||
|
||||
private final Object mLock = new Object();
|
||||
private final DeathRecipient mDeathRecipient = new DeathRecipient();
|
||||
@@ -123,7 +123,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
private int mCurrentUserId;
|
||||
private boolean mTracingEnabled;
|
||||
|
||||
private SparseArray<UiState> mDisplayUiState = new SparseArray<>();
|
||||
private final SparseArray<UiState> mDisplayUiState = new SparseArray<>();
|
||||
@GuardedBy("mLock")
|
||||
private IUdfpsHbmListener mUdfpsHbmListener;
|
||||
|
||||
private class DeathRecipient implements IBinder.DeathRecipient {
|
||||
public void binderDied() {
|
||||
@@ -598,6 +600,18 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
} catch (RemoteException ex) { }
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUdfpsHbmListener(IUdfpsHbmListener listener) {
|
||||
synchronized (mLock) {
|
||||
mUdfpsHbmListener = listener;
|
||||
}
|
||||
if (mBar != null) {
|
||||
try {
|
||||
mBar.setUdfpsHbmListener(listener);
|
||||
} catch (RemoteException ex) { }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
|
||||
@@ -1204,6 +1218,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
if (mGlobalActionListener == null) return;
|
||||
mGlobalActionListener.onGlobalActionsAvailableChanged(mBar != null);
|
||||
});
|
||||
// If StatusBarService dies, system_server doesn't get killed with it, so we need to make
|
||||
// sure the UDFPS listener is refreshed as well. Deferring to the handler just so to avoid
|
||||
// making registerStatusBar re-entrant.
|
||||
mHandler.post(() -> {
|
||||
synchronized (mLock) {
|
||||
setUdfpsHbmListener(mUdfpsHbmListener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,10 +27,13 @@ import static com.android.server.display.DisplayModeDirector.Vote.PRIORITY_FLICK
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -45,6 +48,7 @@ import android.hardware.Sensor;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.DeviceConfig;
|
||||
@@ -61,9 +65,11 @@ import androidx.test.runner.AndroidJUnit4;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.internal.util.test.FakeSettingsProvider;
|
||||
import com.android.internal.util.test.FakeSettingsProviderRule;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.display.DisplayModeDirector.BrightnessObserver;
|
||||
import com.android.server.display.DisplayModeDirector.DesiredDisplayModeSpecs;
|
||||
import com.android.server.display.DisplayModeDirector.Vote;
|
||||
import com.android.server.statusbar.StatusBarManagerInternal;
|
||||
import com.android.server.testutils.FakeDeviceConfigInterface;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -71,6 +77,7 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@@ -95,6 +102,8 @@ public class DisplayModeDirectorTest {
|
||||
private Handler mHandler;
|
||||
@Rule
|
||||
public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
|
||||
@Mock
|
||||
public StatusBarManagerInternal mStatusBarMock;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -104,6 +113,9 @@ public class DisplayModeDirectorTest {
|
||||
when(mContext.getContentResolver()).thenReturn(resolver);
|
||||
mInjector = new FakesInjector();
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
|
||||
LocalServices.addService(StatusBarManagerInternal.class, mStatusBarMock);
|
||||
}
|
||||
|
||||
private DisplayModeDirector createDirectorFromRefreshRateArray(
|
||||
@@ -338,7 +350,7 @@ public class DisplayModeDirectorTest {
|
||||
|
||||
void verifyBrightnessObserverCall(DisplayModeDirector director, float minFps, float peakFps,
|
||||
float defaultFps, float brightnessObserverMin, float brightnessObserverMax) {
|
||||
BrightnessObserver brightnessObserver = Mockito.mock(BrightnessObserver.class);
|
||||
BrightnessObserver brightnessObserver = mock(BrightnessObserver.class);
|
||||
director.injectBrightnessObserver(brightnessObserver);
|
||||
director.getDesiredDisplayModeSpecsWithInjectedFpsSettings(minFps, peakFps, defaultFps);
|
||||
verify(brightnessObserver)
|
||||
@@ -581,7 +593,7 @@ public class DisplayModeDirectorTest {
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 20 /*lux*/));
|
||||
|
||||
Vote vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER);
|
||||
assertVoteForRefreshRateLocked(vote, 90 /*fps*/);
|
||||
assertVoteForRefreshRate(vote, 90 /*fps*/);
|
||||
|
||||
setBrightness(125);
|
||||
// Sensor reads 1000 lux,
|
||||
@@ -611,7 +623,7 @@ public class DisplayModeDirectorTest {
|
||||
|
||||
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||
Mockito.verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
|
||||
verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
|
||||
.registerListener(
|
||||
listenerCaptor.capture(),
|
||||
eq(lightSensor),
|
||||
@@ -631,7 +643,7 @@ public class DisplayModeDirectorTest {
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 9000));
|
||||
|
||||
vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER);
|
||||
assertVoteForRefreshRateLocked(vote, 60 /*fps*/);
|
||||
assertVoteForRefreshRate(vote, 60 /*fps*/);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -654,21 +666,21 @@ public class DisplayModeDirectorTest {
|
||||
director.start(sensorManager);
|
||||
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||
Mockito.verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
|
||||
verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
|
||||
.registerListener(
|
||||
listenerCaptor.capture(),
|
||||
eq(lightSensor),
|
||||
anyInt(),
|
||||
any(Handler.class));
|
||||
|
||||
// Dispaly state changed from On to Doze
|
||||
// Display state changed from On to Doze
|
||||
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_DOZE);
|
||||
Mockito.verify(sensorManager)
|
||||
verify(sensorManager)
|
||||
.unregisterListener(listenerCaptor.capture());
|
||||
|
||||
// Dispaly state changed from Doze to On
|
||||
// Display state changed from Doze to On
|
||||
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
|
||||
Mockito.verify(sensorManager, times(2))
|
||||
verify(sensorManager, times(2))
|
||||
.registerListener(
|
||||
listenerCaptor.capture(),
|
||||
eq(lightSensor),
|
||||
@@ -677,7 +689,42 @@ public class DisplayModeDirectorTest {
|
||||
|
||||
}
|
||||
|
||||
private void assertVoteForRefreshRateLocked(Vote vote, float refreshRate) {
|
||||
@Test
|
||||
public void testUdfpsListenerGetsRegistered() {
|
||||
DisplayModeDirector director =
|
||||
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f, 110.f}, 0);
|
||||
verify(mStatusBarMock, never()).setUdfpsHbmListener(any());
|
||||
|
||||
director.start(createMockSensorManager());
|
||||
verify(mStatusBarMock).setUdfpsHbmListener(eq(director.getUdpfsObserver()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGbhmVotesFor60hz() throws Exception {
|
||||
DisplayModeDirector director =
|
||||
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f, 110.f}, 0);
|
||||
director.start(createMockSensorManager());
|
||||
ArgumentCaptor<IUdfpsHbmListener> captor =
|
||||
ArgumentCaptor.forClass(IUdfpsHbmListener.class);
|
||||
verify(mStatusBarMock).setUdfpsHbmListener(captor.capture());
|
||||
IUdfpsHbmListener hbmListener = captor.getValue();
|
||||
|
||||
// Should be no vote initially
|
||||
Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
|
||||
assertNull(vote);
|
||||
|
||||
// Enabling GHBM votes for 60hz
|
||||
hbmListener.onHbmEnabled(IUdfpsHbmListener.GLOBAL_HBM, DISPLAY_ID);
|
||||
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
|
||||
assertVoteForRefreshRate(vote, 60.f);
|
||||
|
||||
// Disabling GHBM removes the vote
|
||||
hbmListener.onHbmDisabled(IUdfpsHbmListener.GLOBAL_HBM, DISPLAY_ID);
|
||||
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
|
||||
assertNull(vote);
|
||||
}
|
||||
|
||||
private void assertVoteForRefreshRate(Vote vote, float refreshRate) {
|
||||
assertThat(vote).isNotNull();
|
||||
final DisplayModeDirector.RefreshRateRange expectedRange =
|
||||
new DisplayModeDirector.RefreshRateRange(refreshRate, refreshRate);
|
||||
@@ -787,7 +834,7 @@ public class DisplayModeDirectorTest {
|
||||
}
|
||||
|
||||
private static SensorManager createMockSensorManager(Sensor... sensors) {
|
||||
SensorManager sensorManager = Mockito.mock(SensorManager.class);
|
||||
SensorManager sensorManager = mock(SensorManager.class);
|
||||
when(sensorManager.getSensorList(anyInt())).then((invocation) -> {
|
||||
List<Sensor> requestedSensors = new ArrayList<>();
|
||||
int type = invocation.getArgument(0);
|
||||
|
||||
Reference in New Issue
Block a user