Merge changes from topic "implement-lhbm" into sc-dev

* changes:
  Introduce IUdfpsHbmListener
  Implement LHBM/GHBM switch
This commit is contained in:
Ilya Matyukhin
2021-03-18 21:27:21 +00:00
committed by Android (Google) Code Review
10 changed files with 207 additions and 26 deletions

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) 2021 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 android.hardware.fingerprint;
/**
* A listener for the high-brightness mode (HBM) transitions. This allows other components to
* perform certain actions when the HBM is toggled on or off. For example, a display manager
* implementation can subscribe to these events from UdfpsController and adjust the display's
* refresh rate when the HBM is enabled.
*
* @hide
*/
oneway interface IUdfpsHbmListener {
/**
* UdfpsController will call this method when the HBM is enabled.
*
* @param hbmType The type of HBM that was enabled. See
* {@link com.android.systemui.biometrics.HbmTypes}.
* @param displayId The displayId for which the HBM is enabled. See
* {@link android.view.Display#getDisplayId()}.
*/
void onHbmEnabled(int hbmType, int displayId);
/**
* UdfpsController will call this method when the HBM is disabled.
*
* @param hbmType The type of HBM that was disabled. See
* {@link com.android.systemui.biometrics.HbmTypes}.
* @param displayId The displayId for which the HBM is disabled. See
* {@link android.view.Display#getDisplayId()}.
*/
void onHbmDisabled(int hbmType, int displayId);
}

View File

@@ -21,6 +21,7 @@ import android.content.ComponentName;
import android.graphics.Rect;
import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.PromptInfo;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.service.notification.StatusBarNotification;
@@ -155,6 +156,11 @@ oneway interface IStatusBar
// Used to hide the authentication dialog, e.g. when the application cancels authentication
void hideAuthenticationDialog();
/**
* Sets an instance of IUdfpsHbmListener for UdfpsController.
*/
void setUdfpsHbmListener(in IUdfpsHbmListener listener);
/**
* Notifies System UI that the display is ready to show system decorations.
*/

View File

@@ -21,6 +21,7 @@ import android.content.ComponentName;
import android.graphics.Rect;
import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.PromptInfo;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
@@ -120,6 +121,11 @@ interface IStatusBarService
// Used to hide the authentication dialog, e.g. when the application cancels authentication
void hideAuthenticationDialog();
/**
* Sets an instance of IUdfpsHbmListener for UdfpsController.
*/
void setUdfpsHbmListener(in IUdfpsHbmListener listener);
/**
* Show a warning that the device is about to go to sleep due to user inactivity.
*/

View File

@@ -16,9 +16,11 @@
package com.android.systemui.biometrics;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.view.Surface;
import com.android.systemui.biometrics.HbmTypes.HbmType;
/**
* Interface for controlling the high-brightness mode (HBM). UdfpsView can use this callback to
* enable the HBM while showing the fingerprint illumination, and to disable the HBM after the
@@ -26,16 +28,20 @@ import android.view.Surface;
*/
public interface HbmCallback {
/**
* UdfpsView will call this to enable the HBM before drawing the illumination dot.
* UdfpsView will call this to enable the HBM when the fingerprint illumination is needed.
*
* @param surface A valid surface for which the HBM should be enabled.
* @param hbmType The type of HBM that should be enabled. See {@link HbmTypes}.
* @param surface The surface for which the HBM is requested, in case the HBM implementation
* needs to set special surface flags to enable the HBM. Can be null.
*/
void enableHbm(@NonNull Surface surface);
void enableHbm(@HbmType int hbmType, @Nullable Surface surface);
/**
* UdfpsView will call this to disable the HBM when the illumination is not longer needed.
*
* @param surface A valid surface for which the HBM should be disabled.
* @param hbmType The type of HBM that should be disabled. See {@link HbmTypes}.
* @param surface The surface for which the HBM is requested, in case the HBM implementation
* needs to unset special surface flags to disable the HBM. Can be null.
*/
void disableHbm(@NonNull Surface surface);
void disableHbm(@HbmType int hbmType, @Nullable Surface surface);
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2021 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.systemui.biometrics;
import android.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Different high-brightness mode (HBM) types that are relevant to this package.
*/
public final class HbmTypes {
/** HBM that applies to the whole screen. */
public static final int GLOBAL_HBM = 0;
/** HBM that only applies to a portion of the screen. */
public static final int LOCAL_HBM = 1;
@Retention(RetentionPolicy.SOURCE)
@IntDef({GLOBAL_HBM, LOCAL_HBM})
public @interface HbmType {
}
}

View File

@@ -19,6 +19,8 @@ package com.android.systemui.biometrics;
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -42,11 +44,9 @@ import android.view.Surface;
import android.view.VelocityTracker;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.biometrics.HbmTypes.HbmType;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
@@ -95,7 +95,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
// Tracks the velocity of a touch to help filter out the touches that move too fast.
@Nullable private VelocityTracker mVelocityTracker;
// The ID of the pointer for which ACTION_DOWN has occurred. -1 means no pointer is active.
private int mActivePointerId;
private int mActivePointerId = -1;
// The timestamp of the most recent touch log.
private long mTouchLogTime;
@@ -580,13 +580,13 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
}
@Override
public void enableHbm(@NonNull Surface surface) {
public void enableHbm(@HbmType int hbmType, @Nullable Surface surface) {
// Do nothing. This method can be implemented for devices that require the high-brightness
// mode for fingerprint illumination.
}
@Override
public void disableHbm(@NonNull Surface surface) {
public void disableHbm(@HbmType int hbmType, @Nullable Surface surface) {
// Do nothing. This method can be implemented for devices that require the high-brightness
// mode for fingerprint illumination.
}

View File

@@ -23,16 +23,25 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.os.Build;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.android.systemui.biometrics.HbmTypes.HbmType;
/**
* Under-display fingerprint sensor Surface View. The surface should be used for HBM-specific things
* only. All other animations should be done on the other view.
*/
public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
private static final String TAG = "UdfpsSurfaceView";
private static final String SETTING_HBM_TYPE =
"com.android.systemui.biometrics.UdfpsSurfaceView.hbmType";
private static final @HbmType int DEFAULT_HBM_TYPE = HbmTypes.GLOBAL_HBM;
/**
* This is used instead of {@link android.graphics.drawable.Drawable}, because the latter has
@@ -45,6 +54,7 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
@NonNull private final SurfaceHolder mHolder;
@NonNull private final Paint mSensorPaint;
@NonNull private final SimpleDrawable mIlluminationDotDrawable;
private final @HbmType int mHbmType;
@NonNull private RectF mSensorRect;
@Nullable private HbmCallback mHbmCallback;
@@ -70,6 +80,13 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
mIlluminationDotDrawable = canvas -> {
canvas.drawOval(mSensorRect, mSensorPaint);
};
if (Build.IS_ENG || Build.IS_USERDEBUG) {
mHbmType = Settings.Secure.getIntForUser(mContext.getContentResolver(),
SETTING_HBM_TYPE, DEFAULT_HBM_TYPE, UserHandle.USER_CURRENT);
} else {
mHbmType = DEFAULT_HBM_TYPE;
}
}
@Override
@@ -79,10 +96,15 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
@Override
public void startIllumination(@Nullable Runnable onIlluminatedRunnable) {
if (mHbmCallback != null && mHolder.getSurface().isValid()) {
mHbmCallback.enableHbm(mHolder.getSurface());
if (mHbmCallback != null) {
mHbmCallback.enableHbm(mHbmType, mHolder.getSurface());
} else {
Log.e(TAG, "startIllumination | mHbmCallback is null");
}
if (mHbmType == HbmTypes.GLOBAL_HBM) {
drawImmediately(mIlluminationDotDrawable);
}
drawImmediately(mIlluminationDotDrawable);
if (onIlluminatedRunnable != null) {
// No framework API can reliably tell when a frame reaches the panel. A timeout is the
@@ -94,8 +116,10 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator {
@Override
public void stopIllumination() {
if (mHbmCallback != null && mHolder.getSurface().isValid()) {
mHbmCallback.disableHbm(mHolder.getSurface());
if (mHbmCallback != null) {
mHbmCallback.disableHbm(mHbmType, mHolder.getSurface());
} else {
Log.e(TAG, "stopIllumination | mHbmCallback is null");
}
invalidate();

View File

@@ -37,6 +37,7 @@ import android.content.Context;
import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.PromptInfo;
import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.inputmethodservice.InputMethodService.BackDispositionMode;
import android.os.Bundle;
import android.os.Handler;
@@ -142,6 +143,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
//TODO(b/169175022) Update name and when feature name is locked.
private static final int MSG_EMERGENCY_ACTION_LAUNCH_GESTURE = 58 << MSG_SHIFT;
private static final int MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED = 59 << MSG_SHIFT;
private static final int MSG_SET_UDFPS_HBM_LISTENER = 60 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -286,21 +288,38 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
IBiometricSysuiReceiver receiver,
int[] sensorIds, boolean credentialAllowed,
boolean requireConfirmation, int userId, String opPackageName,
long operationId) { }
default void onBiometricAuthenticated() { }
default void onBiometricHelp(String message) { }
default void onBiometricError(int modality, int error, int vendorCode) { }
default void hideAuthenticationDialog() { }
long operationId) {
}
default void onBiometricAuthenticated() {
}
default void onBiometricHelp(String message) {
}
default void onBiometricError(int modality, int error, int vendorCode) {
}
default void hideAuthenticationDialog() {
}
/**
* @see IStatusBar#setUdfpsHbmListener(IUdfpsHbmListener)
*/
default void setUdfpsHbmListener(IUdfpsHbmListener listener) {
}
/**
* @see IStatusBar#onDisplayReady(int)
*/
default void onDisplayReady(int displayId) { }
default void onDisplayReady(int displayId) {
}
/**
* @see DisplayManager.DisplayListener#onDisplayRemoved(int)
*/
default void onDisplayRemoved(int displayId) { }
default void onDisplayRemoved(int displayId) {
}
/**
* @see IStatusBar#onRecentsAnimationStateChanged(boolean)
@@ -892,6 +911,13 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
}
}
@Override
public void setUdfpsHbmListener(IUdfpsHbmListener listener) {
synchronized (mLock) {
mHandler.obtainMessage(MSG_SET_UDFPS_HBM_LISTENER, listener).sendToTarget();
}
}
@Override
public void onDisplayReady(int displayId) {
synchronized (mLock) {
@@ -1286,7 +1312,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
mCallbacks.get(i).onBiometricHelp((String) msg.obj);
}
break;
case MSG_BIOMETRIC_ERROR:
case MSG_BIOMETRIC_ERROR: {
SomeArgs someArgs = (SomeArgs) msg.obj;
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onBiometricError(
@@ -1297,11 +1323,17 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
}
someArgs.recycle();
break;
}
case MSG_BIOMETRIC_HIDE:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).hideAuthenticationDialog();
}
break;
case MSG_SET_UDFPS_HBM_LISTENER:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).setUdfpsHbmListener((IUdfpsHbmListener) msg.obj);
}
break;
case MSG_SHOW_CHARGING_ANIMATION:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).showWirelessChargingAnimation(msg.arg1);

View File

@@ -29,6 +29,7 @@ import android.content.ComponentName;
import android.graphics.Rect;
import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.PromptInfo;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.os.Bundle;
import android.view.WindowInsetsController.Appearance;
import android.view.WindowInsetsController.Behavior;
@@ -463,6 +464,14 @@ public class CommandQueueTest extends SysuiTestCase {
verify(mCallbacks).hideAuthenticationDialog();
}
@Test
public void testSetUdfpsHbmListener() {
final IUdfpsHbmListener listener = mock(IUdfpsHbmListener.class);
mCommandQueue.setUdfpsHbmListener(listener);
waitForIdleSync();
verify(mCallbacks).setUdfpsHbmListener(eq(listener));
}
@Test
public void testSuppressAmbientDisplay() {
mCommandQueue.suppressAmbientDisplay(true);

View File

@@ -36,6 +36,7 @@ import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.PromptInfo;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -827,13 +828,25 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
}
@Override
public void setUdfpsHbmListener(IUdfpsHbmListener listener) {
enforceStatusBarService();
if (mBar != null) {
try {
mBar.setUdfpsHbmListener(listener);
} catch (RemoteException ex) {
}
}
}
@Override
public void startTracing() {
if (mBar != null) {
try {
mBar.startTracing();
mTracingEnabled = true;
} catch (RemoteException ex) {}
} catch (RemoteException ex) {
}
}
}