10f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi/* 20f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Copyright (C) 2015 The Android Open Source Project 30f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * 40f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 50f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * you may not use this file except in compliance with the License. 60f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * You may obtain a copy of the License at 70f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * 80f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 90f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * 100f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Unless required by applicable law or agreed to in writing, software 110f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 120f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * See the License for the specific language governing permissions and 140f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * limitations under the License 150f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 160f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 170f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggipackage android.support.v4.hardware.fingerprint; 180f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 190f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggiimport android.content.Context; 200f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggiimport android.os.Build; 21febf93acf968f1722d3644f356b346987941fd94Jim Millerimport android.os.Handler; 220f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggiimport android.support.annotation.NonNull; 230f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggiimport android.support.annotation.Nullable; 24c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viveretteimport android.support.annotation.RequiresApi; 250f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggiimport android.support.v4.os.CancellationSignal; 260f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 270f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggiimport java.security.Signature; 280f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 290f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggiimport javax.crypto.Cipher; 30e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggiimport javax.crypto.Mac; 310f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 320f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi/** 330f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * A class that coordinates access to the fingerprint hardware. 340f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * <p> 353d7a7c44f6781f8fe5960317959d21e3973aa01aDianne Hackborn * On platforms before {@link android.os.Build.VERSION_CODES#M}, this class behaves as there would 363d7a7c44f6781f8fe5960317959d21e3973aa01aDianne Hackborn * be no fingerprint hardware available. 370f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 38c5847d13e40f5d52459f5c0dab32dc08f1a9a683Chris Banespublic final class FingerprintManagerCompat { 390f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 400f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi private Context mContext; 410f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 420f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** Get a {@link FingerprintManagerCompat} instance for a provided context. */ 430f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public static FingerprintManagerCompat from(Context context) { 440f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return new FingerprintManagerCompat(context); 450f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 460f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 470f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi private FingerprintManagerCompat(Context context) { 480f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi mContext = context; 490f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 500f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 510f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi static final FingerprintManagerCompatImpl IMPL; 520f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi static { 53c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette if (Build.VERSION.SDK_INT >= 23) { 540f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi IMPL = new Api23FingerprintManagerCompatImpl(); 550f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } else { 560f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi IMPL = new LegacyFingerprintManagerCompatImpl(); 570f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 580f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 590f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 600f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 610f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Determine if there is at least one fingerprint enrolled. 620f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * 630f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @return true if at least one fingerprint is enrolled, false otherwise 640f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 650f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public boolean hasEnrolledFingerprints() { 660f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return IMPL.hasEnrolledFingerprints(mContext); 670f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 680f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 690f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 700f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Determine if fingerprint hardware is present and functional. 710f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * 720f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @return true if hardware is present and functional, false otherwise. 730f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 740f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public boolean isHardwareDetected() { 750f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return IMPL.isHardwareDetected(mContext); 760f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 770f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 780f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 790f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Request authentication of a crypto object. This call warms up the fingerprint hardware 800f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * and starts scanning for a fingerprint. It terminates when 810f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or 82377357a8c26c8c54ba8cb876ae775265635a8448Elliot Waite * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at 830f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * which point the object is no longer valid. The operation can be canceled by using the 840f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * provided cancel object. 850f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * 860f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @param crypto object associated with the call or null if none required. 87febf93acf968f1722d3644f356b346987941fd94Jim Miller * @param flags optional flags; should be 0 880f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @param cancel an object that can be used to cancel authentication 890f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @param callback an object to receive authentication events 90febf93acf968f1722d3644f356b346987941fd94Jim Miller * @param handler an optional handler for events 910f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 92febf93acf968f1722d3644f356b346987941fd94Jim Miller public void authenticate(@Nullable CryptoObject crypto, int flags, 930f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Nullable CancellationSignal cancel, @NonNull AuthenticationCallback callback, 94febf93acf968f1722d3644f356b346987941fd94Jim Miller @Nullable Handler handler) { 95febf93acf968f1722d3644f356b346987941fd94Jim Miller IMPL.authenticate(mContext, crypto, flags, cancel, callback, handler); 960f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 970f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 980f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 990f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * A wrapper class for the crypto objects supported by FingerprintManager. Currently the 1000f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * framework supports {@link Signature} and {@link Cipher} objects. 1010f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 1020f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public static class CryptoObject { 1030f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1040f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi private final Signature mSignature; 1050f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi private final Cipher mCipher; 106e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi private final Mac mMac; 1070f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1080f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public CryptoObject(Signature signature) { 1090f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi mSignature = signature; 1100f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi mCipher = null; 111e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi mMac = null; 112e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi 1130f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 1140f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1150f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public CryptoObject(Cipher cipher) { 1160f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi mCipher = cipher; 1170f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi mSignature = null; 118e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi mMac = null; 119e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi } 120e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi 121e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi public CryptoObject(Mac mac) { 122e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi mMac = mac; 123e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi mCipher = null; 124e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi mSignature = null; 1250f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 1260f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1270f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 1280f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Get {@link Signature} object. 1290f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @return {@link Signature} object or null if this doesn't contain one. 1300f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 1310f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public Signature getSignature() { return mSignature; } 1320f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1330f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 1340f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Get {@link Cipher} object. 1350f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @return {@link Cipher} object or null if this doesn't contain one. 1360f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 1370f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public Cipher getCipher() { return mCipher; } 138e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi 139e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi /** 140e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi * Get {@link Mac} object. 141e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi * @return {@link Mac} object or null if this doesn't contain one. 142e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi */ 143e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi public Mac getMac() { return mMac; } 1440f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 1450f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1460f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 1470f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Container for callback data from {@link FingerprintManagerCompat#authenticate(CryptoObject, 148febf93acf968f1722d3644f356b346987941fd94Jim Miller * int, CancellationSignal, AuthenticationCallback, Handler)}. 1490f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 1500f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public static final class AuthenticationResult { 1510f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi private CryptoObject mCryptoObject; 1520f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1530f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public AuthenticationResult(CryptoObject crypto) { 1540f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi mCryptoObject = crypto; 1550f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 1560f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1570f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 1580f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Obtain the crypto object associated with this transaction 1590f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @return crypto object provided to {@link FingerprintManagerCompat#authenticate( 160febf93acf968f1722d3644f356b346987941fd94Jim Miller * CryptoObject, int, CancellationSignal, AuthenticationCallback, Handler)}. 1610f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 1620f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public CryptoObject getCryptoObject() { return mCryptoObject; } 1630f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 1640f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1650f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 1660f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Callback structure provided to {@link FingerprintManagerCompat#authenticate(CryptoObject, 167febf93acf968f1722d3644f356b346987941fd94Jim Miller * int, CancellationSignal, AuthenticationCallback, Handler)}. Users of {@link 168febf93acf968f1722d3644f356b346987941fd94Jim Miller * FingerprintManagerCompat#authenticate(CryptoObject, int, CancellationSignal, 169febf93acf968f1722d3644f356b346987941fd94Jim Miller * AuthenticationCallback, Handler) } must provide an implementation of this for listening to 1700f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * fingerprint events. 1710f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 1720f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public static abstract class AuthenticationCallback { 1730f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 1740f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Called when an unrecoverable error has been encountered and the operation is complete. 1750f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * No further callbacks will be made on this object. 1760f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @param errMsgId An integer identifying the error message 1770f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @param errString A human-readable error string that can be shown in UI 1780f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 1790f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public void onAuthenticationError(int errMsgId, CharSequence errString) { } 1800f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1810f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 1820f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Called when a recoverable error has been encountered during authentication. The help 1830f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * string is provided to give the user guidance for what went wrong, such as 1840f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * "Sensor dirty, please clean it." 1850f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @param helpMsgId An integer identifying the error message 1860f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @param helpString A human-readable string that can be shown in UI 1870f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 1880f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { } 1890f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1900f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 1910f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Called when a fingerprint is recognized. 1920f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * @param result An object containing authentication-related data 1930f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 1940f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public void onAuthenticationSucceeded(AuthenticationResult result) { } 1950f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 1960f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi /** 1970f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi * Called when a fingerprint is valid but not recognized. 1980f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi */ 1990f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public void onAuthenticationFailed() { } 2000f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2010f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2020f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi private interface FingerprintManagerCompatImpl { 2030f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi boolean hasEnrolledFingerprints(Context context); 2040f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi boolean isHardwareDetected(Context context); 205febf93acf968f1722d3644f356b346987941fd94Jim Miller void authenticate(Context context, CryptoObject crypto, int flags, 206febf93acf968f1722d3644f356b346987941fd94Jim Miller CancellationSignal cancel, AuthenticationCallback callback, Handler handler); 2070f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2080f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2090f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi private static class LegacyFingerprintManagerCompatImpl 2100f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi implements FingerprintManagerCompatImpl { 2110f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2120f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public LegacyFingerprintManagerCompatImpl() { 2130f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2140f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2150f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Override 2160f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public boolean hasEnrolledFingerprints(Context context) { 2170f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return false; 2180f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2190f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2200f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Override 2210f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public boolean isHardwareDetected(Context context) { 2220f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return false; 2230f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2240f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2250f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Override 226febf93acf968f1722d3644f356b346987941fd94Jim Miller public void authenticate(Context context, CryptoObject crypto, int flags, 227febf93acf968f1722d3644f356b346987941fd94Jim Miller CancellationSignal cancel, AuthenticationCallback callback, Handler handler) { 2280f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi // TODO: Figure out behavior when there is no fingerprint hardware available 2290f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2300f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2310f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 232c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette @RequiresApi(23) 2330f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi private static class Api23FingerprintManagerCompatImpl implements FingerprintManagerCompatImpl { 2340f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2350f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public Api23FingerprintManagerCompatImpl() { 2360f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2370f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2380f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Override 2390f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public boolean hasEnrolledFingerprints(Context context) { 2400f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return FingerprintManagerCompatApi23.hasEnrolledFingerprints(context); 2410f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2420f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2430f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Override 2440f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public boolean isHardwareDetected(Context context) { 2450f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return FingerprintManagerCompatApi23.isHardwareDetected(context); 2460f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2470f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2480f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Override 249febf93acf968f1722d3644f356b346987941fd94Jim Miller public void authenticate(Context context, CryptoObject crypto, int flags, 250febf93acf968f1722d3644f356b346987941fd94Jim Miller CancellationSignal cancel, AuthenticationCallback callback, Handler handler) { 251febf93acf968f1722d3644f356b346987941fd94Jim Miller FingerprintManagerCompatApi23.authenticate(context, wrapCryptoObject(crypto), flags, 2520f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi cancel != null ? cancel.getCancellationSignalObject() : null, 253febf93acf968f1722d3644f356b346987941fd94Jim Miller wrapCallback(callback), handler); 2540f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2550f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2560f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi private static FingerprintManagerCompatApi23.CryptoObject wrapCryptoObject( 2570f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi CryptoObject cryptoObject) { 25850931369bc45988cfb44760dc3b52012bef56d3aJorim Jaggi if (cryptoObject == null) { 25950931369bc45988cfb44760dc3b52012bef56d3aJorim Jaggi return null; 26050931369bc45988cfb44760dc3b52012bef56d3aJorim Jaggi } else if (cryptoObject.getCipher() != null) { 2610f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return new FingerprintManagerCompatApi23.CryptoObject(cryptoObject.getCipher()); 262e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi } else if (cryptoObject.getSignature() != null) { 2630f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return new FingerprintManagerCompatApi23.CryptoObject(cryptoObject.getSignature()); 264e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi } else if (cryptoObject.getMac() != null) { 265e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi return new FingerprintManagerCompatApi23.CryptoObject(cryptoObject.getMac()); 266e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi } else { 267e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi return null; 2680f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2690f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2700f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 271552766fa685c63ad760c92239faaba12e6ad51f1Aurimas Liutikas static CryptoObject unwrapCryptoObject( 2720f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi FingerprintManagerCompatApi23.CryptoObject cryptoObject) { 27350931369bc45988cfb44760dc3b52012bef56d3aJorim Jaggi if (cryptoObject == null) { 27450931369bc45988cfb44760dc3b52012bef56d3aJorim Jaggi return null; 27550931369bc45988cfb44760dc3b52012bef56d3aJorim Jaggi } else if (cryptoObject.getCipher() != null) { 2760f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return new CryptoObject(cryptoObject.getCipher()); 277e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi } else if (cryptoObject.getSignature() != null) { 2780f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return new CryptoObject(cryptoObject.getSignature()); 279e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi } else if (cryptoObject.getMac() != null) { 280e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi return new CryptoObject(cryptoObject.getMac()); 281e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi } else { 282e70c5387272b23eb09b7324e88b8c5d8e4481b3fJorim Jaggi return null; 2830f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2840f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2850f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2860f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi private static FingerprintManagerCompatApi23.AuthenticationCallback wrapCallback( 2870f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi final AuthenticationCallback callback) { 2880f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi return new FingerprintManagerCompatApi23.AuthenticationCallback() { 2890f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Override 2900f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public void onAuthenticationError(int errMsgId, CharSequence errString) { 2910f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi callback.onAuthenticationError(errMsgId, errString); 2920f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2930f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2940f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Override 2950f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { 2960f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi callback.onAuthenticationHelp(helpMsgId, helpString); 2970f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 2980f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 2990f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Override 3000f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public void onAuthenticationSucceeded( 3010f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi FingerprintManagerCompatApi23.AuthenticationResultInternal result) { 3020f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi callback.onAuthenticationSucceeded(new AuthenticationResult( 3030f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi unwrapCryptoObject(result.getCryptoObject()))); 3040f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 3050f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi 3060f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi @Override 3070f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi public void onAuthenticationFailed() { 3080f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi callback.onAuthenticationFailed(); 3090f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 3100f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi }; 3110f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 3120f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi } 3130f46e110e9edcc92812670b3f4b918a84499265bJorim Jaggi} 314