Merge "Add plumbing to show/hide side-fps UI affordance near power button" into sc-dev am: 961749155a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14628982

Change-Id: I3b4dd09801d179bbf5abb0eeb3b6a5555be1a511
This commit is contained in:
Grace Cheng
2021-05-21 17:04:11 +00:00
committed by Automerger Merge Worker
16 changed files with 499 additions and 9 deletions

View File

@@ -85,7 +85,6 @@ import javax.crypto.Mac;
@SystemService(Context.FINGERPRINT_SERVICE) @SystemService(Context.FINGERPRINT_SERVICE)
@RequiresFeature(PackageManager.FEATURE_FINGERPRINT) @RequiresFeature(PackageManager.FEATURE_FINGERPRINT)
public class FingerprintManager implements BiometricAuthenticator, BiometricFingerprintConstants { public class FingerprintManager implements BiometricAuthenticator, BiometricFingerprintConstants {
private static final String TAG = "FingerprintManager"; private static final String TAG = "FingerprintManager";
private static final boolean DEBUG = true; private static final boolean DEBUG = true;
private static final int MSG_ENROLL_RESULT = 100; 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 * Forwards FingerprintStateListener to FingerprintService
* @param listener new FingerprintStateListener being added * @param listener new FingerprintStateListener being added

View File

@@ -16,6 +16,7 @@
package android.hardware.fingerprint; 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_OPTICAL;
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC; 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 @Override
public String toString() { public String toString() {
return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType; return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType;

View File

@@ -25,6 +25,7 @@ import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.IFingerprintStateListener; import android.hardware.fingerprint.IFingerprintStateListener;
import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.IUdfpsOverlayController;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import java.util.List; import java.util.List;
@@ -166,6 +167,9 @@ interface IFingerprintService {
// Sets the controller for managing the UDFPS overlay. // Sets the controller for managing the UDFPS overlay.
void setUdfpsOverlayController(in IUdfpsOverlayController controller); 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. // Registers FingerprintStateListener in list stored by FingerprintService.
void registerFingerprintStateListener(IFingerprintStateListener listener); void registerFingerprintStateListener(IFingerprintStateListener listener);
} }

View File

@@ -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();
}

View 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>

View File

@@ -83,6 +83,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
@Nullable private final FingerprintManager mFingerprintManager; @Nullable private final FingerprintManager mFingerprintManager;
@Nullable private final FaceManager mFaceManager; @Nullable private final FaceManager mFaceManager;
private final Provider<UdfpsController> mUdfpsControllerFactory; private final Provider<UdfpsController> mUdfpsControllerFactory;
private final Provider<SidefpsController> mSidefpsControllerFactory;
@Nullable private final PointF mFaceAuthSensorLocation; @Nullable private final PointF mFaceAuthSensorLocation;
// TODO: These should just be saved from onSaveState // TODO: These should just be saved from onSaveState
@@ -93,6 +94,8 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
private WindowManager mWindowManager; private WindowManager mWindowManager;
@Nullable @Nullable
private UdfpsController mUdfpsController; private UdfpsController mUdfpsController;
@Nullable
private SidefpsController mSidefpsController;
@VisibleForTesting @VisibleForTesting
TaskStackListener mTaskStackListener; TaskStackListener mTaskStackListener;
@VisibleForTesting @VisibleForTesting
@@ -100,6 +103,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
@Nullable private final List<FaceSensorPropertiesInternal> mFaceProps; @Nullable private final List<FaceSensorPropertiesInternal> mFaceProps;
@Nullable private List<FingerprintSensorPropertiesInternal> mFpProps; @Nullable private List<FingerprintSensorPropertiesInternal> mFpProps;
@Nullable private List<FingerprintSensorPropertiesInternal> mUdfpsProps; @Nullable private List<FingerprintSensorPropertiesInternal> mUdfpsProps;
@Nullable private List<FingerprintSensorPropertiesInternal> mSidefpsProps;
private class BiometricTaskStackListener extends TaskStackListener { private class BiometricTaskStackListener extends TaskStackListener {
@Override @Override
@@ -120,15 +124,23 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
} }
mFpProps = sensors; mFpProps = sensors;
List<FingerprintSensorPropertiesInternal> udfpsProps = new ArrayList<>(); List<FingerprintSensorPropertiesInternal> udfpsProps = new ArrayList<>();
List<FingerprintSensorPropertiesInternal> sidefpsProps = new ArrayList<>();
for (FingerprintSensorPropertiesInternal props : mFpProps) { for (FingerprintSensorPropertiesInternal props : mFpProps) {
if (props.isAnyUdfpsType()) { if (props.isAnyUdfpsType()) {
udfpsProps.add(props); udfpsProps.add(props);
} }
if (props.isAnySidefpsType()) {
sidefpsProps.add(props);
}
} }
mUdfpsProps = !udfpsProps.isEmpty() ? udfpsProps : null; mUdfpsProps = !udfpsProps.isEmpty() ? udfpsProps : null;
if (mUdfpsProps != null) { if (mUdfpsProps != null) {
mUdfpsController = mUdfpsControllerFactory.get(); 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, ActivityTaskManager activityTaskManager,
@Nullable FingerprintManager fingerprintManager, @Nullable FingerprintManager fingerprintManager,
@Nullable FaceManager faceManager, @Nullable FaceManager faceManager,
Provider<UdfpsController> udfpsControllerFactory) { Provider<UdfpsController> udfpsControllerFactory,
Provider<SidefpsController> sidefpsControllerFactory) {
super(context); super(context);
mCommandQueue = commandQueue; mCommandQueue = commandQueue;
mStatusBarStateController = statusBarStateController; mStatusBarStateController = statusBarStateController;
@@ -372,6 +385,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
mFingerprintManager = fingerprintManager; mFingerprintManager = fingerprintManager;
mFaceManager = faceManager; mFaceManager = faceManager;
mUdfpsControllerFactory = udfpsControllerFactory; mUdfpsControllerFactory = udfpsControllerFactory;
mSidefpsControllerFactory = sidefpsControllerFactory;
mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null; mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null;
@@ -618,6 +632,10 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
mUdfpsController.onConfigurationChanged(); mUdfpsController.onConfigurationChanged();
} }
if (mSidefpsController != null) {
mSidefpsController.onConfigurationChanged();
}
// Save the state of the current dialog (buttons showing, etc) // Save the state of the current dialog (buttons showing, etc)
if (mCurrentDialog != null) { if (mCurrentDialog != null) {
final Bundle savedState = new Bundle(); final Bundle savedState = new Bundle();

View File

@@ -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;
}
}

View File

@@ -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
}
}

View File

@@ -103,6 +103,8 @@ public class AuthControllerTest extends SysuiTestCase {
private FaceManager mFaceManager; private FaceManager mFaceManager;
@Mock @Mock
private UdfpsController mUdfpsController; private UdfpsController mUdfpsController;
@Mock
private SidefpsController mSidefpsController;
@Captor @Captor
ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mAuthenticatorsRegisteredCaptor; ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mAuthenticatorsRegisteredCaptor;
@@ -149,7 +151,7 @@ public class AuthControllerTest extends SysuiTestCase {
mAuthController = new TestableAuthController(context, mCommandQueue, mAuthController = new TestableAuthController(context, mCommandQueue,
mStatusBarStateController, mActivityTaskManager, mFingerprintManager, mFaceManager, mStatusBarStateController, mActivityTaskManager, mFingerprintManager, mFaceManager,
() -> mUdfpsController); () -> mUdfpsController, () -> mSidefpsController);
mAuthController.start(); mAuthController.start();
verify(mFingerprintManager).addAuthenticatorsRegisteredCallback( verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(
@@ -560,9 +562,11 @@ public class AuthControllerTest extends SysuiTestCase {
ActivityTaskManager activityTaskManager, ActivityTaskManager activityTaskManager,
FingerprintManager fingerprintManager, FingerprintManager fingerprintManager,
FaceManager faceManager, FaceManager faceManager,
Provider<UdfpsController> udfpsControllerFactory) { Provider<UdfpsController> udfpsControllerFactory,
Provider<SidefpsController> sidefpsControllerFactory) {
super(context, commandQueue, statusBarStateController, activityTaskManager, super(context, commandQueue, statusBarStateController, activityTaskManager,
fingerprintManager, faceManager, udfpsControllerFactory); fingerprintManager, faceManager, udfpsControllerFactory,
sidefpsControllerFactory);
} }
@Override @Override

View File

@@ -55,6 +55,7 @@ import android.hardware.fingerprint.IFingerprintClientActiveCallback;
import android.hardware.fingerprint.IFingerprintService; import android.hardware.fingerprint.IFingerprintService;
import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.IFingerprintStateListener; import android.hardware.fingerprint.IFingerprintStateListener;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.Binder; import android.os.Binder;
import android.os.Build; 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 @Override
public void registerFingerprintStateListener(@NonNull IFingerprintStateListener listener) { public void registerFingerprintStateListener(@NonNull IFingerprintStateListener listener) {
FingerprintService.this.registerFingerprintStateListener(listener); FingerprintService.this.registerFingerprintStateListener(listener);

View File

@@ -25,6 +25,7 @@ import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.IBinder; import android.os.IBinder;
import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream;
@@ -144,6 +145,12 @@ public interface ServiceProvider {
void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller); 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, void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
boolean clearSchedulerBuffer); boolean clearSchedulerBuffer);

View File

@@ -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);
}
}
}

View File

@@ -26,6 +26,7 @@ import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.fingerprint.ISession; import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; 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.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.EnrollClient; import com.android.server.biometrics.sensors.EnrollClient;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; 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.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper; 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"; private static final String TAG = "FingerprintEnrollClient";
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController; @Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@Nullable private final ISidefpsController mSidefpsController;
private final @FingerprintManager.EnrollReason int mEnrollReason; private final @FingerprintManager.EnrollReason int mEnrollReason;
@Nullable private ICancellationSignal mCancellationSignal; @Nullable private ICancellationSignal mCancellationSignal;
private final int mMaxTemplatesPerUser; private final int mMaxTemplatesPerUser;
@@ -53,12 +57,14 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
@NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull ClientMonitorCallbackConverter listener, int userId,
@NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull byte[] hardwareAuthToken, @NonNull String owner,
@NonNull BiometricUtils<Fingerprint> utils, int sensorId, @NonNull BiometricUtils<Fingerprint> utils, int sensorId,
@Nullable IUdfpsOverlayController udfpsOvelayController, int maxTemplatesPerUser, @Nullable IUdfpsOverlayController udfpsOvelayController,
@FingerprintManager.EnrollReason int enrollReason) { @Nullable ISidefpsController sidefpsController,
int maxTemplatesPerUser, @FingerprintManager.EnrollReason int enrollReason) {
super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils, super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils,
0 /* timeoutSec */, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId, 0 /* timeoutSec */, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId,
true /* shouldVibrate */); true /* shouldVibrate */);
mUdfpsOverlayController = udfpsOvelayController; mUdfpsOverlayController = udfpsOvelayController;
mSidefpsController = sidefpsController;
mMaxTemplatesPerUser = maxTemplatesPerUser; mMaxTemplatesPerUser = maxTemplatesPerUser;
mEnrollReason = enrollReason; mEnrollReason = enrollReason;
@@ -75,6 +81,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
if (remaining == 0) { if (remaining == 0) {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
} }
} }
@@ -93,6 +100,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
super.onError(errorCode, vendorCode); super.onError(errorCode, vendorCode);
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
} }
@Override @Override
@@ -105,6 +113,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
@Override @Override
protected void stopHalOperation() { protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
if (mCancellationSignal != null) { if (mCancellationSignal != null) {
try { try {
mCancellationSignal.cancel(); mCancellationSignal.cancel();
@@ -122,6 +131,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
UdfpsHelper.showUdfpsOverlay(getSensorId(), UdfpsHelper.showUdfpsOverlay(getSensorId(),
UdfpsHelper.getReasonFromEnrollReason(mEnrollReason), UdfpsHelper.getReasonFromEnrollReason(mEnrollReason),
mUdfpsOverlayController, this); mUdfpsOverlayController, this);
SidefpsHelper.showOverlay(mSidefpsController);
try { try {
mCancellationSignal = getFreshDaemon().enroll( mCancellationSignal = getFreshDaemon().enroll(
HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken)); HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken));

View File

@@ -36,6 +36,7 @@ import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.Binder; import android.os.Binder;
import android.os.Handler; import android.os.Handler;
@@ -90,6 +91,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
@Nullable private IFingerprint mDaemon; @Nullable private IFingerprint mDaemon;
@Nullable private IUdfpsOverlayController mUdfpsOverlayController; @Nullable private IUdfpsOverlayController mUdfpsOverlayController;
@Nullable private ISidefpsController mSidefpsController;
private final class BiometricTaskStackListener extends TaskStackListener { private final class BiometricTaskStackListener extends TaskStackListener {
@Override @Override
@@ -330,7 +332,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
mSensors.get(sensorId).getLazySession(), token, mSensors.get(sensorId).getLazySession(), token,
new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken, new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
opPackageName, FingerprintUtils.getInstance(sensorId), sensorId, opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
mUdfpsOverlayController, maxTemplatesPerUser, enrollReason); mUdfpsOverlayController, mSidefpsController, maxTemplatesPerUser, enrollReason);
scheduleForSensor(sensorId, client, new BaseClientMonitor.Callback() { scheduleForSensor(sensorId, client, new BaseClientMonitor.Callback() {
@Override @Override
@@ -530,6 +532,11 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
mUdfpsOverlayController = controller; mUdfpsOverlayController = controller;
} }
@Override
public void setSidefpsController(@NonNull ISidefpsController controller) {
mSidefpsController = controller;
}
@Override @Override
public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto, public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
boolean clearSchedulerBuffer) { boolean clearSchedulerBuffer) {

View File

@@ -37,6 +37,7 @@ import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
@@ -113,6 +114,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
@Nullable private IBiometricsFingerprint mDaemon; @Nullable private IBiometricsFingerprint mDaemon;
@NonNull private final HalResultController mHalResultController; @NonNull private final HalResultController mHalResultController;
@Nullable private IUdfpsOverlayController mUdfpsOverlayController; @Nullable private IUdfpsOverlayController mUdfpsOverlayController;
@Nullable private ISidefpsController mSidefpsController;
private int mCurrentUserId = UserHandle.USER_NULL; private int mCurrentUserId = UserHandle.USER_NULL;
private final boolean mIsUdfps; private final boolean mIsUdfps;
private final int mSensorId; private final int mSensorId;
@@ -558,7 +560,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId, mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
hardwareAuthToken, opPackageName, FingerprintUtils.getLegacyInstance(mSensorId), hardwareAuthToken, opPackageName, FingerprintUtils.getLegacyInstance(mSensorId),
ENROLL_TIMEOUT_SEC, mSensorProperties.sensorId, mUdfpsOverlayController, ENROLL_TIMEOUT_SEC, mSensorProperties.sensorId, mUdfpsOverlayController,
enrollReason); mSidefpsController, enrollReason);
mScheduler.scheduleClientMonitor(client, new BaseClientMonitor.Callback() { mScheduler.scheduleClientMonitor(client, new BaseClientMonitor.Callback() {
@Override @Override
public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
@@ -753,6 +755,11 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
mUdfpsOverlayController = controller; mUdfpsOverlayController = controller;
} }
@Override
public void setSidefpsController(@NonNull ISidefpsController controller) {
mSidefpsController = controller;
}
@Override @Override
public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto, public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
boolean clearSchedulerBuffer) { boolean clearSchedulerBuffer) {

View File

@@ -25,6 +25,7 @@ import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; 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.BiometricUtils;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.EnrollClient; 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.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper; import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
@@ -47,6 +49,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
private static final String TAG = "FingerprintEnrollClient"; private static final String TAG = "FingerprintEnrollClient";
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController; @Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@Nullable private final ISidefpsController mSidefpsController;
private final @FingerprintManager.EnrollReason int mEnrollReason; private final @FingerprintManager.EnrollReason int mEnrollReason;
FingerprintEnrollClient(@NonNull Context context, FingerprintEnrollClient(@NonNull Context context,
@@ -55,11 +58,13 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
@NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull byte[] hardwareAuthToken, @NonNull String owner,
@NonNull BiometricUtils<Fingerprint> utils, int timeoutSec, int sensorId, @NonNull BiometricUtils<Fingerprint> utils, int timeoutSec, int sensorId,
@Nullable IUdfpsOverlayController udfpsOverlayController, @Nullable IUdfpsOverlayController udfpsOverlayController,
@Nullable ISidefpsController sidefpsController,
@FingerprintManager.EnrollReason int enrollReason) { @FingerprintManager.EnrollReason int enrollReason) {
super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils, super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils,
timeoutSec, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId, timeoutSec, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId,
true /* shouldVibrate */); true /* shouldVibrate */);
mUdfpsOverlayController = udfpsOverlayController; mUdfpsOverlayController = udfpsOverlayController;
mSidefpsController = sidefpsController;
mEnrollReason = enrollReason; mEnrollReason = enrollReason;
if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) { if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) {
@@ -85,6 +90,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
UdfpsHelper.showUdfpsOverlay(getSensorId(), UdfpsHelper.showUdfpsOverlay(getSensorId(),
UdfpsHelper.getReasonFromEnrollReason(mEnrollReason), UdfpsHelper.getReasonFromEnrollReason(mEnrollReason),
mUdfpsOverlayController, this); mUdfpsOverlayController, this);
SidefpsHelper.showOverlay(mSidefpsController);
try { try {
// GroupId was never used. In fact, groupId is always the same as userId. // GroupId was never used. In fact, groupId is always the same as userId.
getFreshDaemon().enroll(mHardwareAuthToken, getTargetUserId(), mTimeoutSec); getFreshDaemon().enroll(mHardwareAuthToken, getTargetUserId(), mTimeoutSec);
@@ -93,6 +99,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE, onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */); 0 /* vendorCode */);
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
mCallback.onClientFinished(this, false /* success */); mCallback.onClientFinished(this, false /* success */);
} }
} }
@@ -100,6 +107,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
@Override @Override
protected void stopHalOperation() { protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
try { try {
getFreshDaemon().cancel(); getFreshDaemon().cancel();
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -118,6 +126,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
if (remaining == 0) { if (remaining == 0) {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
} }
} }
@@ -135,6 +144,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
super.onError(errorCode, vendorCode); super.onError(errorCode, vendorCode);
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
} }
@Override @Override