Add plumbing to show/hide side-fps UI affordance near power button
Configure side-fps devices to display a indicator for the fingerprint sensor location during fps-related events (enrollment, auth, etc) Test: Observe indicator behavior during fingerprint enrollment Bug: 186470722 Change-Id: I353ec22a239a01edc5cc3dbf0e3c6d80faa2a0e9
This commit is contained in:
@@ -85,7 +85,6 @@ import javax.crypto.Mac;
|
||||
@SystemService(Context.FINGERPRINT_SERVICE)
|
||||
@RequiresFeature(PackageManager.FEATURE_FINGERPRINT)
|
||||
public class FingerprintManager implements BiometricAuthenticator, BiometricFingerprintConstants {
|
||||
|
||||
private static final String TAG = "FingerprintManager";
|
||||
private static final boolean DEBUG = true;
|
||||
private static final int MSG_ENROLL_RESULT = 100;
|
||||
@@ -881,6 +880,24 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public void setSidefpsController(@NonNull ISidefpsController controller) {
|
||||
if (mService == null) {
|
||||
Slog.w(TAG, "setSidefpsController: no fingerprint service");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mService.setSidefpsController(controller);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Forwards FingerprintStateListener to FingerprintService
|
||||
* @param listener new FingerprintStateListener being added
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.hardware.fingerprint;
|
||||
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC;
|
||||
|
||||
@@ -136,6 +137,19 @@ public class FingerprintSensorPropertiesInternal extends SensorPropertiesInterna
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if sensor type is side-FPS
|
||||
* @return true if sensor is side-fps, false otherwise
|
||||
*/
|
||||
public boolean isAnySidefpsType() {
|
||||
switch (sensorType) {
|
||||
case TYPE_POWER_BUTTON:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType;
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
import android.hardware.fingerprint.IFingerprintStateListener;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import java.util.List;
|
||||
@@ -166,6 +167,9 @@ interface IFingerprintService {
|
||||
// Sets the controller for managing the UDFPS overlay.
|
||||
void setUdfpsOverlayController(in IUdfpsOverlayController controller);
|
||||
|
||||
// Sets the controller for managing the SideFPS overlay.
|
||||
void setSidefpsController(in ISidefpsController controller);
|
||||
|
||||
// Registers FingerprintStateListener in list stored by FingerprintService.
|
||||
void registerFingerprintStateListener(IFingerprintStateListener listener);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Interface for interacting with the side fingerprint sensor (side-fps) overlay.
|
||||
* @hide
|
||||
*/
|
||||
oneway interface ISidefpsController {
|
||||
|
||||
// Shows the overlay.
|
||||
void show();
|
||||
|
||||
// Hides the overlay.
|
||||
void hide();
|
||||
}
|
||||
24
packages/SystemUI/res/layout/sidefps_view.xml
Normal file
24
packages/SystemUI/res/layout/sidefps_view.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<com.android.systemui.biometrics.SidefpsView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:systemui="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/sidefps_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/accessibility_fingerprint_label">
|
||||
</com.android.systemui.biometrics.SidefpsView>
|
||||
@@ -83,6 +83,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
@Nullable private final FingerprintManager mFingerprintManager;
|
||||
@Nullable private final FaceManager mFaceManager;
|
||||
private final Provider<UdfpsController> mUdfpsControllerFactory;
|
||||
private final Provider<SidefpsController> mSidefpsControllerFactory;
|
||||
@Nullable private final PointF mFaceAuthSensorLocation;
|
||||
|
||||
// TODO: These should just be saved from onSaveState
|
||||
@@ -93,6 +94,8 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
private WindowManager mWindowManager;
|
||||
@Nullable
|
||||
private UdfpsController mUdfpsController;
|
||||
@Nullable
|
||||
private SidefpsController mSidefpsController;
|
||||
@VisibleForTesting
|
||||
TaskStackListener mTaskStackListener;
|
||||
@VisibleForTesting
|
||||
@@ -100,6 +103,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
@Nullable private final List<FaceSensorPropertiesInternal> mFaceProps;
|
||||
@Nullable private List<FingerprintSensorPropertiesInternal> mFpProps;
|
||||
@Nullable private List<FingerprintSensorPropertiesInternal> mUdfpsProps;
|
||||
@Nullable private List<FingerprintSensorPropertiesInternal> mSidefpsProps;
|
||||
|
||||
private class BiometricTaskStackListener extends TaskStackListener {
|
||||
@Override
|
||||
@@ -120,15 +124,23 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
}
|
||||
mFpProps = sensors;
|
||||
List<FingerprintSensorPropertiesInternal> udfpsProps = new ArrayList<>();
|
||||
List<FingerprintSensorPropertiesInternal> sidefpsProps = new ArrayList<>();
|
||||
for (FingerprintSensorPropertiesInternal props : mFpProps) {
|
||||
if (props.isAnyUdfpsType()) {
|
||||
udfpsProps.add(props);
|
||||
}
|
||||
if (props.isAnySidefpsType()) {
|
||||
sidefpsProps.add(props);
|
||||
}
|
||||
}
|
||||
mUdfpsProps = !udfpsProps.isEmpty() ? udfpsProps : null;
|
||||
if (mUdfpsProps != null) {
|
||||
mUdfpsController = mUdfpsControllerFactory.get();
|
||||
}
|
||||
mSidefpsProps = !sidefpsProps.isEmpty() ? sidefpsProps : null;
|
||||
if (mSidefpsProps != null) {
|
||||
mSidefpsController = mSidefpsControllerFactory.get();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -364,7 +376,8 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
ActivityTaskManager activityTaskManager,
|
||||
@Nullable FingerprintManager fingerprintManager,
|
||||
@Nullable FaceManager faceManager,
|
||||
Provider<UdfpsController> udfpsControllerFactory) {
|
||||
Provider<UdfpsController> udfpsControllerFactory,
|
||||
Provider<SidefpsController> sidefpsControllerFactory) {
|
||||
super(context);
|
||||
mCommandQueue = commandQueue;
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
@@ -372,6 +385,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
mFingerprintManager = fingerprintManager;
|
||||
mFaceManager = faceManager;
|
||||
mUdfpsControllerFactory = udfpsControllerFactory;
|
||||
mSidefpsControllerFactory = sidefpsControllerFactory;
|
||||
|
||||
mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null;
|
||||
|
||||
@@ -618,6 +632,10 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
mUdfpsController.onConfigurationChanged();
|
||||
}
|
||||
|
||||
if (mSidefpsController != null) {
|
||||
mSidefpsController.onConfigurationChanged();
|
||||
}
|
||||
|
||||
// Save the state of the current dialog (buttons showing, etc)
|
||||
if (mCurrentDialog != null) {
|
||||
final Bundle savedState = new Bundle();
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* 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 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.content.Context;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Shows and hides the side fingerprint sensor (side-fps) overlay and handles side fps touch events.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class SidefpsController {
|
||||
private static final String TAG = "SidefpsController";
|
||||
// TODO (b/188690214): define and retrieve values from framework via SensorProps
|
||||
static final int DISPLAY_HEIGHT = 1804;
|
||||
static final int DISPLAY_WIDTH = 2208;
|
||||
static final int SFPS_INDICATOR_HEIGHT = 225;
|
||||
static final int SFPS_Y = 500;
|
||||
static final int SFPS_INDICATOR_WIDTH = 50;
|
||||
|
||||
@Nullable private SidefpsView mView;
|
||||
private final FingerprintManager mFingerprintManager;
|
||||
private final Context mContext;
|
||||
@NonNull private final LayoutInflater mInflater;
|
||||
private final WindowManager mWindowManager;
|
||||
private final DelayableExecutor mFgExecutor;
|
||||
private boolean mIsVisible = false;
|
||||
|
||||
@NonNull
|
||||
private final ISidefpsController mSidefpsControllerImpl = new ISidefpsController.Stub() {
|
||||
@Override
|
||||
public void show() {
|
||||
mFgExecutor.execute(() -> {
|
||||
SidefpsController.this.show();
|
||||
mIsVisible = true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
mFgExecutor.execute(() -> {
|
||||
SidefpsController.this.hide();
|
||||
mIsVisible = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
final FingerprintSensorPropertiesInternal mSensorProps;
|
||||
private final WindowManager.LayoutParams mCoreLayoutParams;
|
||||
|
||||
@Inject
|
||||
public SidefpsController(@NonNull Context context,
|
||||
@NonNull LayoutInflater inflater,
|
||||
@Nullable FingerprintManager fingerprintManager,
|
||||
@NonNull WindowManager windowManager,
|
||||
@Main DelayableExecutor fgExecutor) {
|
||||
mContext = context;
|
||||
mInflater = inflater;
|
||||
mFingerprintManager = checkNotNull(fingerprintManager);
|
||||
mWindowManager = windowManager;
|
||||
mFgExecutor = fgExecutor;
|
||||
|
||||
mSensorProps = findFirstSidefps();
|
||||
checkArgument(mSensorProps != null);
|
||||
|
||||
mCoreLayoutParams = new WindowManager.LayoutParams(
|
||||
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
|
||||
getCoreLayoutParamFlags(),
|
||||
PixelFormat.TRANSLUCENT);
|
||||
mCoreLayoutParams.setTitle(TAG);
|
||||
// Overrides default, avoiding status bars during layout
|
||||
mCoreLayoutParams.setFitInsetsTypes(0);
|
||||
mCoreLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
|
||||
mCoreLayoutParams.layoutInDisplayCutoutMode =
|
||||
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
|
||||
mCoreLayoutParams.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
|
||||
|
||||
mFingerprintManager.setSidefpsController(mSidefpsControllerImpl);
|
||||
}
|
||||
|
||||
void show() {
|
||||
mView = (SidefpsView) mInflater.inflate(R.layout.sidefps_view, null, false);
|
||||
mView.setSensorProperties(mSensorProps);
|
||||
mWindowManager.addView(mView, computeLayoutParams());
|
||||
|
||||
}
|
||||
|
||||
void hide() {
|
||||
if (mView != null) {
|
||||
Log.v(TAG, "hideUdfpsOverlay | removing window");
|
||||
mWindowManager.removeView(mView);
|
||||
mView.setOnTouchListener(null);
|
||||
mView.setOnHoverListener(null);
|
||||
mView = null;
|
||||
} else {
|
||||
Log.v(TAG, "hideUdfpsOverlay | the overlay is already hidden");
|
||||
}
|
||||
}
|
||||
|
||||
void onConfigurationChanged() {
|
||||
// If overlay was hidden, it should remain hidden
|
||||
if (!mIsVisible) {
|
||||
return;
|
||||
}
|
||||
// If the overlay needs to be shown, destroy the current overlay, and re-create and show
|
||||
// the overlay with the updated LayoutParams.
|
||||
hide();
|
||||
show();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FingerprintSensorPropertiesInternal findFirstSidefps() {
|
||||
for (FingerprintSensorPropertiesInternal props :
|
||||
mFingerprintManager.getSensorPropertiesInternal()) {
|
||||
if (props.isAnySidefpsType()) {
|
||||
return props;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getCoreLayoutParamFlags() {
|
||||
return WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes layout params depending on orientation & folding configuration of device
|
||||
*/
|
||||
private WindowManager.LayoutParams computeLayoutParams() {
|
||||
mCoreLayoutParams.flags = getCoreLayoutParamFlags();
|
||||
|
||||
// Default dimensions assume portrait mode.
|
||||
mCoreLayoutParams.x = DISPLAY_WIDTH - SFPS_INDICATOR_WIDTH;
|
||||
mCoreLayoutParams.y = SFPS_Y;
|
||||
mCoreLayoutParams.height = SFPS_INDICATOR_HEIGHT;
|
||||
mCoreLayoutParams.width = SFPS_INDICATOR_WIDTH;
|
||||
|
||||
/*
|
||||
TODO (b/188692405): recalculate coordinates for non-portrait configurations and folding
|
||||
states
|
||||
*/
|
||||
return mCoreLayoutParams;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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 static com.android.systemui.biometrics.SidefpsController.SFPS_INDICATOR_HEIGHT;
|
||||
import static com.android.systemui.biometrics.SidefpsController.SFPS_INDICATOR_WIDTH;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
/**
|
||||
* A view containing a normal drawable view for sidefps events.
|
||||
*/
|
||||
public class SidefpsView extends FrameLayout {
|
||||
private static final String TAG = "SidefpsView";
|
||||
@NonNull private final RectF mSensorRect;
|
||||
@NonNull private final Paint mSensorRectPaint;
|
||||
@NonNull private final Paint mPointerText;
|
||||
private static final int POINTER_SIZE_PX = 50;
|
||||
|
||||
// Used to obtain the sensor location.
|
||||
@NonNull private FingerprintSensorPropertiesInternal mSensorProps;
|
||||
|
||||
public SidefpsView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
super.setWillNotDraw(false);
|
||||
|
||||
mPointerText = new Paint(0 /* flags */);
|
||||
mPointerText.setAntiAlias(true);
|
||||
mPointerText.setColor(Color.WHITE);
|
||||
mPointerText.setTextSize(POINTER_SIZE_PX);
|
||||
|
||||
mSensorRect = new RectF();
|
||||
mSensorRectPaint = new Paint(0 /* flags */);
|
||||
mSensorRectPaint.setAntiAlias(true);
|
||||
mSensorRectPaint.setColor(Color.BLUE);
|
||||
mSensorRectPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
void setSensorProperties(@NonNull FingerprintSensorPropertiesInternal properties) {
|
||||
mSensorProps = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
canvas.drawRect(mSensorRect, mSensorRectPaint);
|
||||
canvas.drawText(
|
||||
">",
|
||||
SFPS_INDICATOR_WIDTH / 2 - 10, // TODO(b/188690214): retrieve from sensorProps
|
||||
SFPS_INDICATOR_HEIGHT / 2 + 30, //TODO(b/188690214): retrieve from sensorProps
|
||||
mPointerText
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
|
||||
mSensorRect.set(
|
||||
0,
|
||||
0,
|
||||
SFPS_INDICATOR_WIDTH, //TODO(b/188690214): retrieve from sensorProps
|
||||
SFPS_INDICATOR_HEIGHT); //TODO(b/188690214): retrieve from sensorProps
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,8 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
private FaceManager mFaceManager;
|
||||
@Mock
|
||||
private UdfpsController mUdfpsController;
|
||||
@Mock
|
||||
private SidefpsController mSidefpsController;
|
||||
@Captor
|
||||
ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mAuthenticatorsRegisteredCaptor;
|
||||
|
||||
@@ -149,7 +151,7 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
|
||||
mAuthController = new TestableAuthController(context, mCommandQueue,
|
||||
mStatusBarStateController, mActivityTaskManager, mFingerprintManager, mFaceManager,
|
||||
() -> mUdfpsController);
|
||||
() -> mUdfpsController, () -> mSidefpsController);
|
||||
|
||||
mAuthController.start();
|
||||
verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(
|
||||
@@ -560,9 +562,11 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
ActivityTaskManager activityTaskManager,
|
||||
FingerprintManager fingerprintManager,
|
||||
FaceManager faceManager,
|
||||
Provider<UdfpsController> udfpsControllerFactory) {
|
||||
Provider<UdfpsController> udfpsControllerFactory,
|
||||
Provider<SidefpsController> sidefpsControllerFactory) {
|
||||
super(context, commandQueue, statusBarStateController, activityTaskManager,
|
||||
fingerprintManager, faceManager, udfpsControllerFactory);
|
||||
fingerprintManager, faceManager, udfpsControllerFactory,
|
||||
sidefpsControllerFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -55,6 +55,7 @@ import android.hardware.fingerprint.IFingerprintClientActiveCallback;
|
||||
import android.hardware.fingerprint.IFingerprintService;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
import android.hardware.fingerprint.IFingerprintStateListener;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
@@ -945,6 +946,15 @@ public class FingerprintService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSidefpsController(@NonNull ISidefpsController controller) {
|
||||
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
|
||||
|
||||
for (ServiceProvider provider : mServiceProviders) {
|
||||
provider.setSidefpsController(controller);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerFingerprintStateListener(@NonNull IFingerprintStateListener listener) {
|
||||
FingerprintService.this.registerFingerprintStateListener(listener);
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.IBinder;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
@@ -144,6 +145,12 @@ public interface ServiceProvider {
|
||||
|
||||
void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller);
|
||||
|
||||
/**
|
||||
* Sets side-fps controller
|
||||
* @param controller side-fps controller
|
||||
*/
|
||||
void setSidefpsController(@NonNull ISidefpsController controller);
|
||||
|
||||
void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
|
||||
boolean clearSchedulerBuffer);
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.biometrics.sensors.fingerprint;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
/**
|
||||
* Contains helper methods for side-fps fingerprint controller.
|
||||
*/
|
||||
public class SidefpsHelper {
|
||||
private static final String TAG = "SidefpsHelper";
|
||||
|
||||
/**
|
||||
* Shows the side-fps affordance
|
||||
* @param sidefpsController controller that shows and hides the side-fps affordance
|
||||
*/
|
||||
public static void showOverlay(@Nullable ISidefpsController sidefpsController) {
|
||||
if (sidefpsController == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sidefpsController.show();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception when showing the side-fps overlay", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the side-fps affordance
|
||||
* @param sidefpsController controller that shows and hides the side-fps affordance
|
||||
*/
|
||||
public static void hideOverlay(@Nullable ISidefpsController sidefpsController) {
|
||||
if (sidefpsController == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sidefpsController.hide();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception when hiding the side-fps overlay", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.fingerprint.ISession;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -36,6 +37,7 @@ import com.android.server.biometrics.sensors.BiometricUtils;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.EnrollClient;
|
||||
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
|
||||
import com.android.server.biometrics.sensors.fingerprint.SidefpsHelper;
|
||||
import com.android.server.biometrics.sensors.fingerprint.Udfps;
|
||||
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
|
||||
|
||||
@@ -44,6 +46,8 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
||||
private static final String TAG = "FingerprintEnrollClient";
|
||||
|
||||
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
|
||||
@Nullable private final ISidefpsController mSidefpsController;
|
||||
|
||||
private final @FingerprintManager.EnrollReason int mEnrollReason;
|
||||
@Nullable private ICancellationSignal mCancellationSignal;
|
||||
private final int mMaxTemplatesPerUser;
|
||||
@@ -53,12 +57,14 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
||||
@NonNull ClientMonitorCallbackConverter listener, int userId,
|
||||
@NonNull byte[] hardwareAuthToken, @NonNull String owner,
|
||||
@NonNull BiometricUtils<Fingerprint> utils, int sensorId,
|
||||
@Nullable IUdfpsOverlayController udfpsOvelayController, int maxTemplatesPerUser,
|
||||
@FingerprintManager.EnrollReason int enrollReason) {
|
||||
@Nullable IUdfpsOverlayController udfpsOvelayController,
|
||||
@Nullable ISidefpsController sidefpsController,
|
||||
int maxTemplatesPerUser, @FingerprintManager.EnrollReason int enrollReason) {
|
||||
super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils,
|
||||
0 /* timeoutSec */, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId,
|
||||
true /* shouldVibrate */);
|
||||
mUdfpsOverlayController = udfpsOvelayController;
|
||||
mSidefpsController = sidefpsController;
|
||||
mMaxTemplatesPerUser = maxTemplatesPerUser;
|
||||
|
||||
mEnrollReason = enrollReason;
|
||||
@@ -75,6 +81,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
||||
|
||||
if (remaining == 0) {
|
||||
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
|
||||
SidefpsHelper.hideOverlay(mSidefpsController);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +100,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
||||
super.onError(errorCode, vendorCode);
|
||||
|
||||
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
|
||||
SidefpsHelper.hideOverlay(mSidefpsController);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,6 +113,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
||||
@Override
|
||||
protected void stopHalOperation() {
|
||||
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
|
||||
SidefpsHelper.hideOverlay(mSidefpsController);
|
||||
if (mCancellationSignal != null) {
|
||||
try {
|
||||
mCancellationSignal.cancel();
|
||||
@@ -122,6 +131,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
||||
UdfpsHelper.showUdfpsOverlay(getSensorId(),
|
||||
UdfpsHelper.getReasonFromEnrollReason(mEnrollReason),
|
||||
mUdfpsOverlayController, this);
|
||||
SidefpsHelper.showOverlay(mSidefpsController);
|
||||
try {
|
||||
mCancellationSignal = getFreshDaemon().enroll(
|
||||
HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken));
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
@@ -90,6 +91,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
|
||||
@Nullable private IFingerprint mDaemon;
|
||||
@Nullable private IUdfpsOverlayController mUdfpsOverlayController;
|
||||
@Nullable private ISidefpsController mSidefpsController;
|
||||
|
||||
private final class BiometricTaskStackListener extends TaskStackListener {
|
||||
@Override
|
||||
@@ -330,7 +332,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mSensors.get(sensorId).getLazySession(), token,
|
||||
new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
|
||||
opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
|
||||
mUdfpsOverlayController, maxTemplatesPerUser, enrollReason);
|
||||
mUdfpsOverlayController, mSidefpsController, maxTemplatesPerUser, enrollReason);
|
||||
scheduleForSensor(sensorId, client, new BaseClientMonitor.Callback() {
|
||||
|
||||
@Override
|
||||
@@ -530,6 +532,11 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mUdfpsOverlayController = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSidefpsController(@NonNull ISidefpsController controller) {
|
||||
mSidefpsController = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
|
||||
boolean clearSchedulerBuffer) {
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -113,6 +114,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
@Nullable private IBiometricsFingerprint mDaemon;
|
||||
@NonNull private final HalResultController mHalResultController;
|
||||
@Nullable private IUdfpsOverlayController mUdfpsOverlayController;
|
||||
@Nullable private ISidefpsController mSidefpsController;
|
||||
private int mCurrentUserId = UserHandle.USER_NULL;
|
||||
private final boolean mIsUdfps;
|
||||
private final int mSensorId;
|
||||
@@ -558,7 +560,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
|
||||
hardwareAuthToken, opPackageName, FingerprintUtils.getLegacyInstance(mSensorId),
|
||||
ENROLL_TIMEOUT_SEC, mSensorProperties.sensorId, mUdfpsOverlayController,
|
||||
enrollReason);
|
||||
mSidefpsController, enrollReason);
|
||||
mScheduler.scheduleClientMonitor(client, new BaseClientMonitor.Callback() {
|
||||
@Override
|
||||
public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
|
||||
@@ -753,6 +755,11 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mUdfpsOverlayController = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSidefpsController(@NonNull ISidefpsController controller) {
|
||||
mSidefpsController = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
|
||||
boolean clearSchedulerBuffer) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -33,6 +34,7 @@ import android.util.Slog;
|
||||
import com.android.server.biometrics.sensors.BiometricUtils;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.EnrollClient;
|
||||
import com.android.server.biometrics.sensors.fingerprint.SidefpsHelper;
|
||||
import com.android.server.biometrics.sensors.fingerprint.Udfps;
|
||||
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
|
||||
|
||||
@@ -47,6 +49,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
||||
private static final String TAG = "FingerprintEnrollClient";
|
||||
|
||||
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
|
||||
@Nullable private final ISidefpsController mSidefpsController;
|
||||
private final @FingerprintManager.EnrollReason int mEnrollReason;
|
||||
|
||||
FingerprintEnrollClient(@NonNull Context context,
|
||||
@@ -55,11 +58,13 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
||||
@NonNull byte[] hardwareAuthToken, @NonNull String owner,
|
||||
@NonNull BiometricUtils<Fingerprint> utils, int timeoutSec, int sensorId,
|
||||
@Nullable IUdfpsOverlayController udfpsOverlayController,
|
||||
@Nullable ISidefpsController sidefpsController,
|
||||
@FingerprintManager.EnrollReason int enrollReason) {
|
||||
super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils,
|
||||
timeoutSec, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId,
|
||||
true /* shouldVibrate */);
|
||||
mUdfpsOverlayController = udfpsOverlayController;
|
||||
mSidefpsController = sidefpsController;
|
||||
|
||||
mEnrollReason = enrollReason;
|
||||
if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) {
|
||||
@@ -85,6 +90,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
||||
UdfpsHelper.showUdfpsOverlay(getSensorId(),
|
||||
UdfpsHelper.getReasonFromEnrollReason(mEnrollReason),
|
||||
mUdfpsOverlayController, this);
|
||||
SidefpsHelper.showOverlay(mSidefpsController);
|
||||
try {
|
||||
// GroupId was never used. In fact, groupId is always the same as userId.
|
||||
getFreshDaemon().enroll(mHardwareAuthToken, getTargetUserId(), mTimeoutSec);
|
||||
@@ -93,6 +99,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
||||
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
|
||||
0 /* vendorCode */);
|
||||
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
|
||||
SidefpsHelper.hideOverlay(mSidefpsController);
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
}
|
||||
}
|
||||
@@ -100,6 +107,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
||||
@Override
|
||||
protected void stopHalOperation() {
|
||||
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
|
||||
SidefpsHelper.hideOverlay(mSidefpsController);
|
||||
try {
|
||||
getFreshDaemon().cancel();
|
||||
} catch (RemoteException e) {
|
||||
@@ -118,6 +126,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
||||
|
||||
if (remaining == 0) {
|
||||
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
|
||||
SidefpsHelper.hideOverlay(mSidefpsController);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +144,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
||||
super.onError(errorCode, vendorCode);
|
||||
|
||||
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
|
||||
SidefpsHelper.hideOverlay(mSidefpsController);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user