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
|
* @hide
|
||||||
*/
|
*/
|
||||||
oneway interface IUdfpsHbmListener {
|
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.
|
* UdfpsController will call this method when the HBM is enabled.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.systemui.biometrics;
|
package com.android.systemui.biometrics;
|
||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
|
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -26,10 +27,10 @@ import java.lang.annotation.RetentionPolicy;
|
|||||||
*/
|
*/
|
||||||
public final class HbmTypes {
|
public final class HbmTypes {
|
||||||
/** HBM that applies to the whole screen. */
|
/** 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. */
|
/** 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)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({GLOBAL_HBM, LOCAL_HBM})
|
@IntDef({GLOBAL_HBM, LOCAL_HBM})
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.hardware.SensorEvent;
|
|||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
|
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@@ -40,14 +41,17 @@ import android.util.IndentingPrintWriter;
|
|||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
import android.util.SparseBooleanArray;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.DisplayInfo;
|
import android.view.DisplayInfo;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.os.BackgroundThread;
|
import com.android.internal.os.BackgroundThread;
|
||||||
|
import com.android.server.LocalServices;
|
||||||
import com.android.server.display.utils.AmbientFilter;
|
import com.android.server.display.utils.AmbientFilter;
|
||||||
import com.android.server.display.utils.AmbientFilterFactory;
|
import com.android.server.display.utils.AmbientFilterFactory;
|
||||||
|
import com.android.server.statusbar.StatusBarManagerInternal;
|
||||||
import com.android.server.utils.DeviceConfigInterface;
|
import com.android.server.utils.DeviceConfigInterface;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -93,6 +97,7 @@ public class DisplayModeDirector {
|
|||||||
private final AppRequestObserver mAppRequestObserver;
|
private final AppRequestObserver mAppRequestObserver;
|
||||||
private final SettingsObserver mSettingsObserver;
|
private final SettingsObserver mSettingsObserver;
|
||||||
private final DisplayObserver mDisplayObserver;
|
private final DisplayObserver mDisplayObserver;
|
||||||
|
private final UdfpsObserver mUdfpsObserver;
|
||||||
private final DeviceConfigInterface mDeviceConfig;
|
private final DeviceConfigInterface mDeviceConfig;
|
||||||
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
|
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
|
||||||
|
|
||||||
@@ -133,6 +138,7 @@ public class DisplayModeDirector {
|
|||||||
mSettingsObserver = new SettingsObserver(context, handler);
|
mSettingsObserver = new SettingsObserver(context, handler);
|
||||||
mDisplayObserver = new DisplayObserver(context, handler);
|
mDisplayObserver = new DisplayObserver(context, handler);
|
||||||
mBrightnessObserver = new BrightnessObserver(context, handler);
|
mBrightnessObserver = new BrightnessObserver(context, handler);
|
||||||
|
mUdfpsObserver = new UdfpsObserver();
|
||||||
mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
|
mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
|
||||||
mDeviceConfig = injector.getDeviceConfig();
|
mDeviceConfig = injector.getDeviceConfig();
|
||||||
mAlwaysRespectAppRequest = false;
|
mAlwaysRespectAppRequest = false;
|
||||||
@@ -149,6 +155,7 @@ public class DisplayModeDirector {
|
|||||||
mSettingsObserver.observe();
|
mSettingsObserver.observe();
|
||||||
mDisplayObserver.observe();
|
mDisplayObserver.observe();
|
||||||
mBrightnessObserver.observe(sensorManager);
|
mBrightnessObserver.observe(sensorManager);
|
||||||
|
mUdfpsObserver.observe();
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
// We may have a listener already registered before the call to start, so go ahead and
|
// 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.
|
// notify them to pick up our newly initialized state.
|
||||||
@@ -545,6 +552,7 @@ public class DisplayModeDirector {
|
|||||||
mSettingsObserver.dumpLocked(pw);
|
mSettingsObserver.dumpLocked(pw);
|
||||||
mAppRequestObserver.dumpLocked(pw);
|
mAppRequestObserver.dumpLocked(pw);
|
||||||
mBrightnessObserver.dumpLocked(pw);
|
mBrightnessObserver.dumpLocked(pw);
|
||||||
|
mUdfpsObserver.dumpLocked(pw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,7 +574,6 @@ public class DisplayModeDirector {
|
|||||||
}
|
}
|
||||||
final SparseArray<Vote> votes = getOrCreateVotesByDisplay(displayId);
|
final SparseArray<Vote> votes = getOrCreateVotesByDisplay(displayId);
|
||||||
|
|
||||||
Vote currentVote = votes.get(priority);
|
|
||||||
if (vote != null) {
|
if (vote != null) {
|
||||||
votes.put(priority, vote);
|
votes.put(priority, vote);
|
||||||
} else {
|
} else {
|
||||||
@@ -649,6 +656,11 @@ public class DisplayModeDirector {
|
|||||||
return mSettingsObserver;
|
return mSettingsObserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
UdfpsObserver getUdpfsObserver() {
|
||||||
|
return mUdfpsObserver;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings(
|
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.
|
// 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;
|
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
|
// 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.
|
// 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 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
|
// 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.
|
// 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";
|
return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";
|
||||||
case PRIORITY_LOW_POWER_MODE:
|
case PRIORITY_LOW_POWER_MODE:
|
||||||
return "PRIORITY_LOW_POWER_MODE";
|
return "PRIORITY_LOW_POWER_MODE";
|
||||||
|
case PRIORITY_UDFPS:
|
||||||
|
return "PRIORITY_UDFPS";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Integer.toString(priority);
|
return Integer.toString(priority);
|
||||||
}
|
}
|
||||||
@@ -1162,7 +1181,7 @@ public class DisplayModeDirector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final class AppRequestObserver {
|
final class AppRequestObserver {
|
||||||
private SparseArray<Display.Mode> mAppRequestedModeByDisplay;
|
private final SparseArray<Display.Mode> mAppRequestedModeByDisplay;
|
||||||
|
|
||||||
AppRequestObserver() {
|
AppRequestObserver() {
|
||||||
mAppRequestedModeByDisplay = new SparseArray<>();
|
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_REFRESH_RATE, refreshRateVote);
|
||||||
updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote);
|
updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Display.Mode findModeByIdLocked(int displayId, int modeId) {
|
private Display.Mode findModeByIdLocked(int displayId, int modeId) {
|
||||||
@@ -1328,7 +1346,8 @@ public class DisplayModeDirector {
|
|||||||
|
|
||||||
private SensorManager mSensorManager;
|
private SensorManager mSensorManager;
|
||||||
private Sensor mLightSensor;
|
private Sensor mLightSensor;
|
||||||
private LightSensorEventListener mLightSensorListener = new LightSensorEventListener();
|
private final LightSensorEventListener mLightSensorListener =
|
||||||
|
new LightSensorEventListener();
|
||||||
// Take it as low brightness before valid sensor data comes
|
// Take it as low brightness before valid sensor data comes
|
||||||
private float mAmbientLux = -1.0f;
|
private float mAmbientLux = -1.0f;
|
||||||
private AmbientFilter mAmbientFilter;
|
private AmbientFilter mAmbientFilter;
|
||||||
@@ -1559,8 +1578,7 @@ public class DisplayModeDirector {
|
|||||||
mLightSensorListener.dumpLocked(pw);
|
mLightSensorListener.dumpLocked(pw);
|
||||||
|
|
||||||
if (mAmbientFilter != null) {
|
if (mAmbientFilter != null) {
|
||||||
IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
|
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
|
||||||
ipw.setIndent(" ");
|
|
||||||
mAmbientFilter.dump(ipw);
|
mAmbientFilter.dump(ipw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1907,7 +1925,7 @@ public class DisplayModeDirector {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable mInjectSensorEventRunnable = new Runnable() {
|
private final Runnable mInjectSensorEventRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
long now = SystemClock.uptimeMillis();
|
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 {
|
private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener {
|
||||||
public DeviceConfigDisplaySettings() {
|
public DeviceConfigDisplaySettings() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.server.statusbar;
|
|||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.ITransientNotificationCallback;
|
import android.app.ITransientNotificationCallback;
|
||||||
|
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
@@ -166,4 +167,11 @@ public interface StatusBarManagerInternal {
|
|||||||
* boolean)
|
* boolean)
|
||||||
*/
|
*/
|
||||||
void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable);
|
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 final Context mContext;
|
||||||
|
|
||||||
private Handler mHandler = new Handler();
|
private final Handler mHandler = new Handler();
|
||||||
private NotificationDelegate mNotificationDelegate;
|
private NotificationDelegate mNotificationDelegate;
|
||||||
private volatile IStatusBar mBar;
|
private volatile IStatusBar mBar;
|
||||||
private ArrayMap<String, StatusBarIcon> mIcons = new ArrayMap<>();
|
private final ArrayMap<String, StatusBarIcon> mIcons = new ArrayMap<>();
|
||||||
|
|
||||||
// for disabling the status bar
|
// for disabling the status bar
|
||||||
private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
|
private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
|
||||||
private GlobalActionsProvider.GlobalActionsListener mGlobalActionListener;
|
private GlobalActionsProvider.GlobalActionsListener mGlobalActionListener;
|
||||||
private IBinder mSysUiVisToken = new Binder();
|
private final IBinder mSysUiVisToken = new Binder();
|
||||||
|
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
private final DeathRecipient mDeathRecipient = new DeathRecipient();
|
private final DeathRecipient mDeathRecipient = new DeathRecipient();
|
||||||
@@ -123,7 +123,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
|||||||
private int mCurrentUserId;
|
private int mCurrentUserId;
|
||||||
private boolean mTracingEnabled;
|
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 {
|
private class DeathRecipient implements IBinder.DeathRecipient {
|
||||||
public void binderDied() {
|
public void binderDied() {
|
||||||
@@ -598,6 +600,18 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
|||||||
} catch (RemoteException ex) { }
|
} 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() {
|
private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
|
||||||
@@ -1204,6 +1218,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
|||||||
if (mGlobalActionListener == null) return;
|
if (mGlobalActionListener == null) return;
|
||||||
mGlobalActionListener.onGlobalActionsAvailableChanged(mBar != null);
|
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 com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.any;
|
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.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -45,6 +48,7 @@ import android.hardware.Sensor;
|
|||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
|
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.provider.DeviceConfig;
|
import android.provider.DeviceConfig;
|
||||||
@@ -61,9 +65,11 @@ import androidx.test.runner.AndroidJUnit4;
|
|||||||
import com.android.internal.util.Preconditions;
|
import com.android.internal.util.Preconditions;
|
||||||
import com.android.internal.util.test.FakeSettingsProvider;
|
import com.android.internal.util.test.FakeSettingsProvider;
|
||||||
import com.android.internal.util.test.FakeSettingsProviderRule;
|
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.BrightnessObserver;
|
||||||
import com.android.server.display.DisplayModeDirector.DesiredDisplayModeSpecs;
|
import com.android.server.display.DisplayModeDirector.DesiredDisplayModeSpecs;
|
||||||
import com.android.server.display.DisplayModeDirector.Vote;
|
import com.android.server.display.DisplayModeDirector.Vote;
|
||||||
|
import com.android.server.statusbar.StatusBarManagerInternal;
|
||||||
import com.android.server.testutils.FakeDeviceConfigInterface;
|
import com.android.server.testutils.FakeDeviceConfigInterface;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -71,6 +77,7 @@ import org.junit.Rule;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
@@ -95,6 +102,8 @@ public class DisplayModeDirectorTest {
|
|||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
@Rule
|
@Rule
|
||||||
public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
|
public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
|
||||||
|
@Mock
|
||||||
|
public StatusBarManagerInternal mStatusBarMock;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
@@ -104,6 +113,9 @@ public class DisplayModeDirectorTest {
|
|||||||
when(mContext.getContentResolver()).thenReturn(resolver);
|
when(mContext.getContentResolver()).thenReturn(resolver);
|
||||||
mInjector = new FakesInjector();
|
mInjector = new FakesInjector();
|
||||||
mHandler = new Handler(Looper.getMainLooper());
|
mHandler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
|
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
|
||||||
|
LocalServices.addService(StatusBarManagerInternal.class, mStatusBarMock);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DisplayModeDirector createDirectorFromRefreshRateArray(
|
private DisplayModeDirector createDirectorFromRefreshRateArray(
|
||||||
@@ -338,7 +350,7 @@ public class DisplayModeDirectorTest {
|
|||||||
|
|
||||||
void verifyBrightnessObserverCall(DisplayModeDirector director, float minFps, float peakFps,
|
void verifyBrightnessObserverCall(DisplayModeDirector director, float minFps, float peakFps,
|
||||||
float defaultFps, float brightnessObserverMin, float brightnessObserverMax) {
|
float defaultFps, float brightnessObserverMin, float brightnessObserverMax) {
|
||||||
BrightnessObserver brightnessObserver = Mockito.mock(BrightnessObserver.class);
|
BrightnessObserver brightnessObserver = mock(BrightnessObserver.class);
|
||||||
director.injectBrightnessObserver(brightnessObserver);
|
director.injectBrightnessObserver(brightnessObserver);
|
||||||
director.getDesiredDisplayModeSpecsWithInjectedFpsSettings(minFps, peakFps, defaultFps);
|
director.getDesiredDisplayModeSpecsWithInjectedFpsSettings(minFps, peakFps, defaultFps);
|
||||||
verify(brightnessObserver)
|
verify(brightnessObserver)
|
||||||
@@ -581,7 +593,7 @@ public class DisplayModeDirectorTest {
|
|||||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 20 /*lux*/));
|
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 20 /*lux*/));
|
||||||
|
|
||||||
Vote vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER);
|
Vote vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER);
|
||||||
assertVoteForRefreshRateLocked(vote, 90 /*fps*/);
|
assertVoteForRefreshRate(vote, 90 /*fps*/);
|
||||||
|
|
||||||
setBrightness(125);
|
setBrightness(125);
|
||||||
// Sensor reads 1000 lux,
|
// Sensor reads 1000 lux,
|
||||||
@@ -611,7 +623,7 @@ public class DisplayModeDirectorTest {
|
|||||||
|
|
||||||
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||||
ArgumentCaptor.forClass(SensorEventListener.class);
|
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||||
Mockito.verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
|
verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
|
||||||
.registerListener(
|
.registerListener(
|
||||||
listenerCaptor.capture(),
|
listenerCaptor.capture(),
|
||||||
eq(lightSensor),
|
eq(lightSensor),
|
||||||
@@ -631,7 +643,7 @@ public class DisplayModeDirectorTest {
|
|||||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 9000));
|
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 9000));
|
||||||
|
|
||||||
vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER);
|
vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER);
|
||||||
assertVoteForRefreshRateLocked(vote, 60 /*fps*/);
|
assertVoteForRefreshRate(vote, 60 /*fps*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -654,21 +666,21 @@ public class DisplayModeDirectorTest {
|
|||||||
director.start(sensorManager);
|
director.start(sensorManager);
|
||||||
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||||
ArgumentCaptor.forClass(SensorEventListener.class);
|
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||||
Mockito.verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
|
verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
|
||||||
.registerListener(
|
.registerListener(
|
||||||
listenerCaptor.capture(),
|
listenerCaptor.capture(),
|
||||||
eq(lightSensor),
|
eq(lightSensor),
|
||||||
anyInt(),
|
anyInt(),
|
||||||
any(Handler.class));
|
any(Handler.class));
|
||||||
|
|
||||||
// Dispaly state changed from On to Doze
|
// Display state changed from On to Doze
|
||||||
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_DOZE);
|
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_DOZE);
|
||||||
Mockito.verify(sensorManager)
|
verify(sensorManager)
|
||||||
.unregisterListener(listenerCaptor.capture());
|
.unregisterListener(listenerCaptor.capture());
|
||||||
|
|
||||||
// Dispaly state changed from Doze to On
|
// Display state changed from Doze to On
|
||||||
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
|
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
|
||||||
Mockito.verify(sensorManager, times(2))
|
verify(sensorManager, times(2))
|
||||||
.registerListener(
|
.registerListener(
|
||||||
listenerCaptor.capture(),
|
listenerCaptor.capture(),
|
||||||
eq(lightSensor),
|
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();
|
assertThat(vote).isNotNull();
|
||||||
final DisplayModeDirector.RefreshRateRange expectedRange =
|
final DisplayModeDirector.RefreshRateRange expectedRange =
|
||||||
new DisplayModeDirector.RefreshRateRange(refreshRate, refreshRate);
|
new DisplayModeDirector.RefreshRateRange(refreshRate, refreshRate);
|
||||||
@@ -787,7 +834,7 @@ public class DisplayModeDirectorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static SensorManager createMockSensorManager(Sensor... sensors) {
|
private static SensorManager createMockSensorManager(Sensor... sensors) {
|
||||||
SensorManager sensorManager = Mockito.mock(SensorManager.class);
|
SensorManager sensorManager = mock(SensorManager.class);
|
||||||
when(sensorManager.getSensorList(anyInt())).then((invocation) -> {
|
when(sensorManager.getSensorList(anyInt())).then((invocation) -> {
|
||||||
List<Sensor> requestedSensors = new ArrayList<>();
|
List<Sensor> requestedSensors = new ArrayList<>();
|
||||||
int type = invocation.getArgument(0);
|
int type = invocation.getArgument(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user