Merge "transcoding: Do not throw exception in registerClient." into sc-dev
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 4ca3105..5b28e00 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -237,7 +237,8 @@
public BiometricTestSession createTestSession(int sensorId) {
try {
return new BiometricTestSession(mContext, sensorId,
- mService.createTestSession(sensorId, mContext.getOpPackageName()));
+ (context, sensorId1, callback) -> mService
+ .createTestSession(sensorId1, callback, context.getOpPackageName()));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/hardware/biometrics/BiometricTestSession.java b/core/java/android/hardware/biometrics/BiometricTestSession.java
index 1c35608..ff1a17e 100644
--- a/core/java/android/hardware/biometrics/BiometricTestSession.java
+++ b/core/java/android/hardware/biometrics/BiometricTestSession.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.TEST_BIOMETRIC;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.content.Context;
@@ -27,6 +28,9 @@
import android.util.ArraySet;
import android.util.Log;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
/**
* Common set of interfaces to test biometric-related APIs, including {@link BiometricPrompt} and
* {@link android.hardware.fingerprint.FingerprintManager}.
@@ -36,22 +40,58 @@
public class BiometricTestSession implements AutoCloseable {
private static final String TAG = "BiometricTestSession";
+ /**
+ * @hide
+ */
+ public interface TestSessionProvider {
+ @NonNull
+ ITestSession createTestSession(@NonNull Context context, int sensorId,
+ @NonNull ITestSessionCallback callback) throws RemoteException;
+ }
+
private final Context mContext;
private final int mSensorId;
private final ITestSession mTestSession;
// Keep track of users that were tested, which need to be cleaned up when finishing.
- private final ArraySet<Integer> mTestedUsers;
+ @NonNull private final ArraySet<Integer> mTestedUsers;
+
+ // Track the users currently cleaning up, and provide a latch that gets notified when all
+ // users have finished cleaning up. This is an imperfect system, as there can technically be
+ // multiple cleanups per user. Theoretically we should track the cleanup's BaseClientMonitor's
+ // unique ID, but it's complicated to plumb it through. This should be fine for now.
+ @Nullable private CountDownLatch mCloseLatch;
+ @NonNull private final ArraySet<Integer> mUsersCleaningUp;
+
+ private final ITestSessionCallback mCallback = new ITestSessionCallback.Stub() {
+ @Override
+ public void onCleanupStarted(int userId) {
+ Log.d(TAG, "onCleanupStarted, sensor: " + mSensorId + ", userId: " + userId);
+ }
+
+ @Override
+ public void onCleanupFinished(int userId) {
+ Log.d(TAG, "onCleanupFinished, sensor: " + mSensorId
+ + ", userId: " + userId
+ + ", remaining users: " + mUsersCleaningUp.size());
+ mUsersCleaningUp.remove(userId);
+
+ if (mUsersCleaningUp.isEmpty() && mCloseLatch != null) {
+ mCloseLatch.countDown();
+ }
+ }
+ };
/**
* @hide
*/
public BiometricTestSession(@NonNull Context context, int sensorId,
- @NonNull ITestSession testSession) {
+ @NonNull TestSessionProvider testSessionProvider) throws RemoteException {
mContext = context;
mSensorId = sensorId;
- mTestSession = testSession;
+ mTestSession = testSessionProvider.createTestSession(context, sensorId, mCallback);
mTestedUsers = new ArraySet<>();
+ mUsersCleaningUp = new ArraySet<>();
setTestHalEnabled(true);
}
@@ -176,6 +216,11 @@
@RequiresPermission(TEST_BIOMETRIC)
public void cleanupInternalState(int userId) {
try {
+ if (mUsersCleaningUp.contains(userId)) {
+ Log.w(TAG, "Cleanup already in progress for user: " + userId);
+ }
+
+ mUsersCleaningUp.add(userId);
mTestSession.cleanupInternalState(userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -185,12 +230,24 @@
@Override
@RequiresPermission(TEST_BIOMETRIC)
public void close() {
- // Disable the test HAL first, so that enumerate is run on the real HAL, which should have
- // no enrollments. Test-only framework enrollments will be deleted.
- setTestHalEnabled(false);
+ // Cleanup can be performed using the test HAL, since it always responds to enumerate with
+ // zero enrollments.
+ if (!mTestedUsers.isEmpty()) {
+ mCloseLatch = new CountDownLatch(1);
+ for (int user : mTestedUsers) {
+ cleanupInternalState(user);
+ }
- for (int user : mTestedUsers) {
- cleanupInternalState(user);
+ try {
+ Log.d(TAG, "Awaiting latch...");
+ mCloseLatch.await(10, TimeUnit.SECONDS);
+ Log.d(TAG, "Finished awaiting");
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Latch interrupted", e);
+ }
}
+
+ // Disable the test HAL after the sensor becomes idle.
+ setTestHalEnabled(false);
}
}
diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl
index 0dfd5db..d8c9dbc 100644
--- a/core/java/android/hardware/biometrics/IAuthService.aidl
+++ b/core/java/android/hardware/biometrics/IAuthService.aidl
@@ -20,6 +20,7 @@
import android.hardware.biometrics.IBiometricServiceReceiver;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorPropertiesInternal;
@@ -32,7 +33,7 @@
*/
interface IAuthService {
// Creates a test session with the specified sensorId
- ITestSession createTestSession(int sensorId, String opPackageName);
+ ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
// Retrieve static sensor properties for all biometric sensors
List<SensorPropertiesInternal> getSensorProperties(String opPackageName);
diff --git a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
index c854ac98..7639c5d 100644
--- a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
@@ -20,6 +20,7 @@
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.face.IFaceServiceReceiver;
import android.hardware.face.Face;
@@ -32,7 +33,7 @@
interface IBiometricAuthenticator {
// Creates a test session
- ITestSession createTestSession(String opPackageName);
+ ITestSession createTestSession(ITestSessionCallback callback, String opPackageName);
// Retrieve static sensor properties
SensorPropertiesInternal getSensorProperties(String opPackageName);
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index a14a910..2433186 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -21,6 +21,7 @@
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorPropertiesInternal;
@@ -30,7 +31,7 @@
*/
interface IBiometricService {
// Creates a test session with the specified sensorId
- ITestSession createTestSession(int sensorId, String opPackageName);
+ ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
// Retrieve static sensor properties for all biometric sensors
List<SensorPropertiesInternal> getSensorProperties(String opPackageName);
diff --git a/core/java/android/hardware/biometrics/ITestSession.aidl b/core/java/android/hardware/biometrics/ITestSession.aidl
index fa7a62c..f8395a1 100644
--- a/core/java/android/hardware/biometrics/ITestSession.aidl
+++ b/core/java/android/hardware/biometrics/ITestSession.aidl
@@ -18,7 +18,7 @@
import android.hardware.biometrics.SensorPropertiesInternal;
/**
- * A test service for FingerprintManager and BiometricPrompt.
+ * A test service for FingerprintManager and BiometricManager.
* @hide
*/
interface ITestSession {
diff --git a/core/java/android/hardware/biometrics/ITestSessionCallback.aidl b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl
new file mode 100644
index 0000000..3d9517f
--- /dev/null
+++ b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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 android.hardware.biometrics;
+
+/**
+ * ITestSession callback for FingerprintManager and BiometricManager.
+ * @hide
+ */
+interface ITestSessionCallback {
+ void onCleanupStarted(int userId);
+ void onCleanupFinished(int userId);
+}
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 886a8c1..a9bcdeff 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -574,12 +574,23 @@
mService.remove(mToken, face.getBiometricId(), userId, mServiceReceiver,
mContext.getOpPackageName());
} catch (RemoteException e) {
- Slog.w(TAG, "Remote exception in remove: ", e);
- if (callback != null) {
- callback.onRemovalError(face, FACE_ERROR_HW_UNAVAILABLE,
- getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE,
- 0 /* vendorCode */));
- }
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Removes all face templates for the given user.
+ * @hide
+ */
+ @RequiresPermission(MANAGE_BIOMETRIC)
+ public void removeAll(int userId, @NonNull RemovalCallback callback) {
+ if (mService != null) {
+ try {
+ mRemovalCallback = callback;
+ mService.removeAll(mToken, userId, mServiceReceiver, mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index a3e7e2d..6e7c701 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -19,6 +19,7 @@
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.face.IFaceServiceReceiver;
import android.hardware.face.Face;
import android.hardware.face.FaceSensorPropertiesInternal;
@@ -32,7 +33,7 @@
interface IFaceService {
// Creates a test session with the specified sensorId
- ITestSession createTestSession(int sensorId, String opPackageName);
+ ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
// Requests a proto dump of the specified sensor
byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer);
@@ -83,10 +84,13 @@
// Cancel enrollment in progress
void cancelEnrollment(IBinder token);
- // Any errors resulting from this call will be returned to the listener
+ // Removes the specified face enrollment for the specified userId.
void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver,
String opPackageName);
+ // Removes all face enrollments for the specified userId.
+ void removeAll(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName);
+
// Get the enrolled face for user.
List<Face> getEnrolledFaces(int sensorId, int userId, String opPackageName);
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index a614ebf..fc795d8 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -114,6 +114,21 @@
*/
public static final int SENSOR_ID_ANY = -1;
+ private static class RemoveTracker {
+ static final int REMOVE_SINGLE = 1;
+ static final int REMOVE_ALL = 2;
+ @IntDef({REMOVE_SINGLE, REMOVE_ALL})
+ @interface RemoveRequest {}
+
+ final @RemoveRequest int mRemoveRequest;
+ @Nullable final Fingerprint mSingleFingerprint;
+
+ RemoveTracker(@RemoveRequest int request, @Nullable Fingerprint fingerprint) {
+ mRemoveRequest = request;
+ mSingleFingerprint = fingerprint;
+ }
+ }
+
private IFingerprintService mService;
private Context mContext;
private IBinder mToken = new Binder();
@@ -123,10 +138,9 @@
private RemovalCallback mRemovalCallback;
private GenerateChallengeCallback mGenerateChallengeCallback;
private CryptoObject mCryptoObject;
- private Fingerprint mRemovalFingerprint;
+ @Nullable private RemoveTracker mRemoveTracker;
private Handler mHandler;
-
/**
* Retrieves a list of properties for all fingerprint sensors on the device.
* @hide
@@ -154,7 +168,8 @@
public BiometricTestSession createTestSession(int sensorId) {
try {
return new BiometricTestSession(mContext, sensorId,
- mService.createTestSession(sensorId, mContext.getOpPackageName()));
+ (context, sensorId1, callback) -> mService
+ .createTestSession(sensorId1, callback, context.getOpPackageName()));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -735,15 +750,27 @@
public void remove(Fingerprint fp, int userId, RemovalCallback callback) {
if (mService != null) try {
mRemovalCallback = callback;
- mRemovalFingerprint = fp;
+ mRemoveTracker = new RemoveTracker(RemoveTracker.REMOVE_SINGLE, fp);
mService.remove(mToken, fp.getBiometricId(), userId, mServiceReceiver,
mContext.getOpPackageName());
} catch (RemoteException e) {
- Slog.w(TAG, "Remote exception in remove: ", e);
- if (callback != null) {
- callback.onRemovalError(fp, FINGERPRINT_ERROR_HW_UNAVAILABLE,
- getErrorString(mContext, FINGERPRINT_ERROR_HW_UNAVAILABLE,
- 0 /* vendorCode */));
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Removes all face templates for the given user.
+ * @hide
+ */
+ @RequiresPermission(MANAGE_FINGERPRINT)
+ public void removeAll(int userId, @NonNull RemovalCallback callback) {
+ if (mService != null) {
+ try {
+ mRemovalCallback = callback;
+ mRemoveTracker = new RemoveTracker(RemoveTracker.REMOVE_ALL, null /* fp */);
+ mService.removeAll(mToken, userId, mServiceReceiver, mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -1044,16 +1071,29 @@
if (mRemovalCallback == null) {
return;
}
- if (fingerprint == null) {
- Slog.e(TAG, "Received MSG_REMOVED, but fingerprint is null");
+
+ if (mRemoveTracker == null) {
+ Slog.w(TAG, "Removal tracker is null");
return;
}
- int fingerId = fingerprint.getBiometricId();
- int reqFingerId = mRemovalFingerprint.getBiometricId();
- if (reqFingerId != 0 && fingerId != 0 && fingerId != reqFingerId) {
- Slog.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
- return;
+ if (mRemoveTracker.mRemoveRequest == RemoveTracker.REMOVE_SINGLE) {
+ if (fingerprint == null) {
+ Slog.e(TAG, "Received MSG_REMOVED, but fingerprint is null");
+ return;
+ }
+
+ if (mRemoveTracker.mSingleFingerprint == null) {
+ Slog.e(TAG, "Missing fingerprint");
+ return;
+ }
+
+ final int fingerId = fingerprint.getBiometricId();
+ int reqFingerId = mRemoveTracker.mSingleFingerprint.getBiometricId();
+ if (reqFingerId != 0 && fingerId != 0 && fingerId != reqFingerId) {
+ Slog.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
+ return;
+ }
}
mRemovalCallback.onRemovalSucceeded(fingerprint, remaining);
@@ -1110,7 +1150,9 @@
mAuthenticationCallback.onAuthenticationError(clientErrMsgId,
getErrorString(mContext, errMsgId, vendorCode));
} else if (mRemovalCallback != null) {
- mRemovalCallback.onRemovalError(mRemovalFingerprint, clientErrMsgId,
+ final Fingerprint fp = mRemoveTracker != null
+ ? mRemoveTracker.mSingleFingerprint : null;
+ mRemovalCallback.onRemovalError(fp, clientErrMsgId,
getErrorString(mContext, errMsgId, vendorCode));
}
}
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 8888247..054c0d0 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -19,6 +19,7 @@
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.fingerprint.IFingerprintClientActiveCallback;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.IUdfpsOverlayController;
@@ -33,7 +34,7 @@
interface IFingerprintService {
// Creates a test session with the specified sensorId
- ITestSession createTestSession(int sensorId, String opPackageName);
+ ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
// Requests a proto dump of the specified sensor
byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer);
@@ -87,6 +88,9 @@
void remove(IBinder token, int fingerId, int userId, IFingerprintServiceReceiver receiver,
String opPackageName);
+ // Removes all face enrollments for the specified userId.
+ void removeAll(IBinder token, int userId, IFingerprintServiceReceiver receiver, String opPackageName);
+
// Rename the fingerprint specified by fingerId and userId to the given name
void rename(int fingerId, int userId, String name);
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 33dedda..874add5 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -24,7 +24,6 @@
import android.net.NetworkStats;
import android.net.RouteInfo;
import android.net.UidRange;
-import android.os.INetworkActivityListener;
/**
* @hide
@@ -294,25 +293,6 @@
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
boolean isBandwidthControlEnabled();
- /**
- * Sets idletimer for an interface.
- *
- * This either initializes a new idletimer or increases its
- * reference-counting if an idletimer already exists for given
- * {@code iface}.
- *
- * {@code type} is the type of the interface, such as TYPE_MOBILE.
- *
- * Every {@code addIdleTimer} should be paired with a
- * {@link removeIdleTimer} to cleanup when the network disconnects.
- */
- void addIdleTimer(String iface, int timeout, int type);
-
- /**
- * Removes idletimer for an interface.
- */
- void removeIdleTimer(String iface);
-
void setFirewallEnabled(boolean enabled);
boolean isFirewallEnabled();
void setFirewallInterfaceRule(String iface, boolean allow);
@@ -320,21 +300,6 @@
void setFirewallUidRules(int chain, in int[] uids, in int[] rules);
void setFirewallChainEnabled(int chain, boolean enable);
- /**
- * Start listening for mobile activity state changes.
- */
- void registerNetworkActivityListener(INetworkActivityListener listener);
-
- /**
- * Stop listening for mobile activity state changes.
- */
- void unregisterNetworkActivityListener(INetworkActivityListener listener);
-
- /**
- * Check whether the mobile radio is currently active.
- */
- boolean isNetworkActive();
-
void addLegacyRouteForNetId(int netId, in RouteInfo routeInfo, int uid);
/**
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index d7c8291..4ddae53 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -49,8 +49,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
-import android.os.INetworkActivityListener;
-import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
@@ -835,7 +833,6 @@
private final Context mContext;
- private INetworkManagementService mNMService;
private INetworkPolicyManager mNPManager;
private final TetheringManager mTetheringManager;
@@ -2211,17 +2208,6 @@
void onNetworkActive();
}
- private INetworkManagementService getNetworkManagementService() {
- synchronized (this) {
- if (mNMService != null) {
- return mNMService;
- }
- IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
- mNMService = INetworkManagementService.Stub.asInterface(b);
- return mNMService;
- }
- }
-
private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
mNetworkActivityListeners = new ArrayMap<>();
@@ -2246,7 +2232,7 @@
};
try {
- getNetworkManagementService().registerNetworkActivityListener(rl);
+ mService.registerNetworkActivityListener(rl);
mNetworkActivityListeners.put(l, rl);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -2263,7 +2249,7 @@
INetworkActivityListener rl = mNetworkActivityListeners.get(l);
Preconditions.checkArgument(rl != null, "Listener was not registered.");
try {
- getNetworkManagementService().unregisterNetworkActivityListener(rl);
+ mService.registerNetworkActivityListener(rl);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2279,7 +2265,7 @@
*/
public boolean isDefaultNetworkActive() {
try {
- return getNetworkManagementService().isNetworkActive();
+ return mService.isDefaultNetworkActive();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
index 6391802..160338d 100644
--- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
@@ -21,6 +21,7 @@
import android.net.ConnectivityDiagnosticsManager;
import android.net.IConnectivityDiagnosticsCallback;
import android.net.IOnSetOemNetworkPreferenceListener;
+import android.net.INetworkActivityListener;
import android.net.IQosCallback;
import android.net.ISocketKeepaliveCallback;
import android.net.LinkProperties;
@@ -36,7 +37,6 @@
import android.net.QosSocketInfo;
import android.os.Bundle;
import android.os.IBinder;
-import android.os.INetworkActivityListener;
import android.os.Messenger;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
diff --git a/core/java/android/os/INetworkActivityListener.aidl b/packages/Connectivity/framework/src/android/net/INetworkActivityListener.aidl
similarity index 96%
rename from core/java/android/os/INetworkActivityListener.aidl
rename to packages/Connectivity/framework/src/android/net/INetworkActivityListener.aidl
index 24e6e55..79687dd 100644
--- a/core/java/android/os/INetworkActivityListener.aidl
+++ b/packages/Connectivity/framework/src/android/net/INetworkActivityListener.aidl
@@ -13,7 +13,7 @@
** limitations under the License.
*/
-package android.os;
+package android.net;
/**
* @hide
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 6e2398c..eb95d16 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -56,6 +56,7 @@
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
import android.media.AudioManager;
+import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Handler;
import android.os.IRemoteCallback;
@@ -851,6 +852,17 @@
assertThat(mKeyguardUpdateMonitor.shouldListenForUdfps()).isEqualTo(false);
}
+ @Test
+ public void testRequireUnlockForNfc_Broadcast() {
+ KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class);
+ mKeyguardUpdateMonitor.registerCallback(callback);
+ Intent intent = new Intent(NfcAdapter.ACTION_REQUIRE_UNLOCK_FOR_NFC);
+ mKeyguardUpdateMonitor.mBroadcastAllReceiver.onReceive(getContext(), intent);
+ mTestableLooper.processAllMessages();
+
+ verify(callback, atLeastOnce()).onRequireUnlockForNfc();
+ }
+
private void setKeyguardBouncerVisibility(boolean isVisible) {
mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(isVisible);
mTestableLooper.processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 0cae6742..ce14bca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -609,6 +609,16 @@
assertThat(mTextView.getText()).isEqualTo(percentage);
}
+ @Test
+ public void onRequireUnlockForNfc_showsRequireUnlockForNfcIndication() {
+ createController();
+ String message = mContext.getString(R.string.require_unlock_for_nfc);
+ mController.getKeyguardCallback().onRequireUnlockForNfc();
+ mController.setVisible(true);
+
+ assertThat(mTextView.getText()).isEqualTo(message);
+ }
+
private void sendUpdateDisclosureBroadcast() {
mBroadcastReceiver.onReceive(mContext, new Intent());
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5077cc6..f54551e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -90,6 +90,7 @@
import android.net.IConnectivityManager;
import android.net.IDnsResolver;
import android.net.INetd;
+import android.net.INetworkActivityListener;
import android.net.INetworkManagementEventObserver;
import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks;
@@ -147,13 +148,13 @@
import android.net.shared.PrivateDnsConfig;
import android.net.util.MultinetworkPolicyTracker;
import android.net.util.NetdService;
+import android.os.BatteryStatsManager;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
-import android.os.INetworkActivityListener;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
@@ -163,6 +164,7 @@
import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.Process;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.os.SystemClock;
@@ -172,6 +174,7 @@
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Log;
@@ -559,6 +562,11 @@
private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48;
/**
+ * Used to indicate the system default network becomes active.
+ */
+ private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49;
+
+ /**
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown.
*/
@@ -1192,7 +1200,7 @@
mUserAllContext.registerReceiver(mIntentReceiver, intentFilter,
null /* broadcastPermission */, mHandler);
- mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mNMS);
+ mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNMS, mNetd);
mSettingsObserver = new SettingsObserver(mContext, mHandler);
registerSettingsCallbacks();
@@ -2404,7 +2412,7 @@
*/
@Override
public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
- // TODO: Replace network activity listener registry in ConnectivityManager from NMS to here
+ mNetworkActivityTracker.registerNetworkActivityListener(l);
}
/**
@@ -2412,7 +2420,7 @@
*/
@Override
public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
- // TODO: Replace network activity listener registry in ConnectivityManager from NMS to here
+ mNetworkActivityTracker.unregisterNetworkActivityListener(l);
}
/**
@@ -2420,8 +2428,7 @@
*/
@Override
public boolean isDefaultNetworkActive() {
- // TODO: Replace isNetworkActive() in NMS.
- return false;
+ return mNetworkActivityTracker.isDefaultNetworkActive();
}
/**
@@ -2686,6 +2693,12 @@
pw.increaseIndent();
mPermissionMonitor.dump(pw);
pw.decreaseIndent();
+
+ pw.println();
+ pw.println("Legacy network activity:");
+ pw.increaseIndent();
+ mNetworkActivityTracker.dump(pw);
+ pw.decreaseIndent();
}
private void dumpNetworks(IndentingPrintWriter pw) {
@@ -4452,6 +4465,9 @@
loge("handleMessage.EVENT_SET_OEM_NETWORK_PREFERENCE failed", e);
}
break;
+ case EVENT_REPORT_NETWORK_ACTIVITY:
+ mNetworkActivityTracker.handleReportNetworkActivity();
+ break;
}
}
}
@@ -8639,13 +8655,35 @@
* changes.
*/
private static final class LegacyNetworkActivityTracker {
+ private static final int NO_UID = -1;
private final Context mContext;
+ private final INetd mNetd;
private final INetworkManagementService mNMS;
+ private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
+ new RemoteCallbackList<>();
+ // Indicate the current system default network activity is active or not.
+ @GuardedBy("mActiveIdleTimers")
+ private boolean mNetworkActive;
+ @GuardedBy("mActiveIdleTimers")
+ private final ArrayMap<String, IdleTimerParams> mActiveIdleTimers = new ArrayMap();
+ private final Handler mHandler;
- LegacyNetworkActivityTracker(@NonNull Context context,
- @NonNull INetworkManagementService nms) {
+ private class IdleTimerParams {
+ public final int timeout;
+ public final int transportType;
+
+ IdleTimerParams(int timeout, int transport) {
+ this.timeout = timeout;
+ this.transportType = transport;
+ }
+ }
+
+ LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler,
+ @NonNull INetworkManagementService nms, @NonNull INetd netd) {
mContext = context;
mNMS = nms;
+ mNetd = netd;
+ mHandler = handler;
try {
mNMS.registerObserver(mDataActivityObserver);
} catch (RemoteException e) {
@@ -8661,9 +8699,50 @@
long tsNanos, int uid) {
sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active,
tsNanos);
+ synchronized (mActiveIdleTimers) {
+ mNetworkActive = active;
+ // If there are no idle timers, it means that system is not monitoring
+ // activity, so the system default network for those default network
+ // unspecified apps is always considered active.
+ //
+ // TODO: If the mActiveIdleTimers is empty, netd will actually not send
+ // any network activity change event. Whenever this event is received,
+ // the mActiveIdleTimers should be always not empty. The legacy behavior
+ // is no-op. Remove to refer to mNetworkActive only.
+ if (mNetworkActive || mActiveIdleTimers.isEmpty()) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY));
+ }
+ }
}
};
+ // The network activity should only be updated from ConnectivityService handler thread
+ // when mActiveIdleTimers lock is held.
+ @GuardedBy("mActiveIdleTimers")
+ private void reportNetworkActive() {
+ final int length = mNetworkActivityListeners.beginBroadcast();
+ if (DDBG) log("reportNetworkActive, notify " + length + " listeners");
+ try {
+ for (int i = 0; i < length; i++) {
+ try {
+ mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
+ } catch (RemoteException | RuntimeException e) {
+ loge("Fail to send network activie to listener " + e);
+ }
+ }
+ } finally {
+ mNetworkActivityListeners.finishBroadcast();
+ }
+ }
+
+ @GuardedBy("mActiveIdleTimers")
+ public void handleReportNetworkActivity() {
+ synchronized (mActiveIdleTimers) {
+ reportNetworkActive();
+ }
+ }
+
// This is deprecated and only to support legacy use cases.
private int transportTypeToLegacyType(int type) {
switch (type) {
@@ -8728,10 +8807,17 @@
return; // do not track any other networks
}
+ updateRadioPowerState(true /* isActive */, type);
+
if (timeout > 0 && iface != null) {
try {
- // TODO: Access INetd directly instead of NMS
- mNMS.addIdleTimer(iface, timeout, type);
+ synchronized (mActiveIdleTimers) {
+ // Networks start up.
+ mNetworkActive = true;
+ mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
+ mNetd.idletimerAddInterface(iface, timeout, Integer.toString(type));
+ reportNetworkActive();
+ }
} catch (Exception e) {
// You shall not crash!
loge("Exception in setupDataActivityTracking " + e);
@@ -8746,16 +8832,28 @@
final String iface = networkAgent.linkProperties.getInterfaceName();
final NetworkCapabilities caps = networkAgent.networkCapabilities;
- if (iface != null && (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
- || caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) {
- try {
- // the call fails silently if no idle timer setup for this interface
- // TODO: Access INetd directly instead of NMS
- mNMS.removeIdleTimer(iface);
- } catch (Exception e) {
- // You shall not crash!
- loge("Exception in removeDataActivityTracking " + e);
+ if (iface == null) return;
+
+ final int type;
+ if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+ type = NetworkCapabilities.TRANSPORT_CELLULAR;
+ } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
+ type = NetworkCapabilities.TRANSPORT_WIFI;
+ } else {
+ return; // do not track any other networks
+ }
+
+ try {
+ updateRadioPowerState(false /* isActive */, type);
+ synchronized (mActiveIdleTimers) {
+ final IdleTimerParams params = mActiveIdleTimers.remove(iface);
+ // The call fails silently if no idle timer setup for this interface
+ mNetd.idletimerRemoveInterface(iface, params.timeout,
+ Integer.toString(params.transportType));
}
+ } catch (Exception e) {
+ // You shall not crash!
+ loge("Exception in removeDataActivityTracking " + e);
}
}
@@ -8771,6 +8869,53 @@
removeDataActivityTracking(oldNetwork);
}
}
+
+ private void updateRadioPowerState(boolean isActive, int transportType) {
+ final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class);
+ switch (transportType) {
+ case NetworkCapabilities.TRANSPORT_CELLULAR:
+ bs.reportMobileRadioPowerState(isActive, NO_UID);
+ break;
+ case NetworkCapabilities.TRANSPORT_WIFI:
+ bs.reportWifiRadioPowerState(isActive, NO_UID);
+ break;
+ default:
+ logw("Untracked transport type:" + transportType);
+ }
+ }
+
+ public boolean isDefaultNetworkActive() {
+ synchronized (mActiveIdleTimers) {
+ // If there are no idle timers, it means that system is not monitoring activity,
+ // so the default network is always considered active.
+ //
+ // TODO : Distinguish between the cases where mActiveIdleTimers is empty because
+ // tracking is disabled (negative idle timer value configured), or no active default
+ // network. In the latter case, this reports active but it should report inactive.
+ return mNetworkActive || mActiveIdleTimers.isEmpty();
+ }
+ }
+
+ public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
+ mNetworkActivityListeners.register(l);
+ }
+
+ public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
+ mNetworkActivityListeners.unregister(l);
+ }
+
+ public void dump(IndentingPrintWriter pw) {
+ synchronized (mActiveIdleTimers) {
+ pw.print("mNetworkActive="); pw.println(mNetworkActive);
+ pw.println("Idle timers:");
+ for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
+ pw.print(" "); pw.print(ent.getKey()); pw.println(":");
+ final IdleTimerParams params = ent.getValue();
+ pw.print(" timeout="); pw.print(params.timeout);
+ pw.print(" type="); pw.println(params.transportType);
+ }
+ }
+ }
}
/**
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index d30a640..4405408 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -69,7 +69,6 @@
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
-import android.os.INetworkActivityListener;
import android.os.INetworkManagementService;
import android.os.Process;
import android.os.RemoteCallbackList;
@@ -80,7 +79,6 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
-import android.telephony.DataConnectionRealTimeInfo;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -229,32 +227,9 @@
@GuardedBy("mQuotaLock")
private volatile boolean mDataSaverMode;
- private final Object mIdleTimerLock = new Object();
- /** Set of interfaces with active idle timers. */
- private static class IdleTimerParams {
- public final int timeout;
- public final int type;
- public int networkCount;
-
- IdleTimerParams(int timeout, int type) {
- this.timeout = timeout;
- this.type = type;
- this.networkCount = 1;
- }
- }
- private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
-
private volatile boolean mFirewallEnabled;
private volatile boolean mStrictEnabled;
- private boolean mMobileActivityFromRadio = false;
- private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
- private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
-
- private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
- new RemoteCallbackList<>();
- private boolean mNetworkActive;
-
/**
* Constructs a new NetworkManagementService instance
*
@@ -397,55 +372,8 @@
*/
private void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos,
int uid) {
- final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type);
- int powerState = isActive
- ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
- : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
- if (isMobile) {
- if (mLastPowerStateFromRadio != powerState) {
- mLastPowerStateFromRadio = powerState;
- try {
- // TODO: The interface changes that comes from netd are handled by BSS itself.
- // There are still events caused by setting or removing idle timer, so keep
- // reporting from here until setting idler timer moved to CS.
- getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid);
- } catch (RemoteException e) {
- }
- }
- }
-
- if (ConnectivityManager.isNetworkTypeWifi(type)) {
- if (mLastPowerStateFromWifi != powerState) {
- mLastPowerStateFromWifi = powerState;
- try {
- // TODO: The interface changes that comes from netd are handled by BSS itself.
- // There are still events caused by setting or removing idle timer, so keep
- // reporting from here until setting idler timer moved to CS.
- getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid);
- } catch (RemoteException e) {
- }
- }
- }
-
- final boolean active = isActive;
invokeForAllObservers(o -> o.interfaceClassDataActivityChanged(
- type, active, tsNanos, uid));
-
- boolean report = false;
- synchronized (mIdleTimerLock) {
- if (mActiveIdleTimers.isEmpty()) {
- // If there are no idle timers, we are not monitoring activity, so we
- // are always considered active.
- isActive = true;
- }
- if (mNetworkActive != isActive) {
- mNetworkActive = isActive;
- report = isActive;
- }
- }
- if (report) {
- reportNetworkActive();
- }
+ type, isActive, tsNanos, uid));
}
@Override
@@ -1122,60 +1050,6 @@
}
@Override
- public void addIdleTimer(String iface, int timeout, final int type) {
- NetworkStack.checkNetworkStackPermission(mContext);
-
- if (DBG) Slog.d(TAG, "Adding idletimer");
-
- synchronized (mIdleTimerLock) {
- IdleTimerParams params = mActiveIdleTimers.get(iface);
- if (params != null) {
- // the interface already has idletimer, update network count
- params.networkCount++;
- return;
- }
-
- try {
- mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type));
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
-
- // Networks start up.
- if (ConnectivityManager.isNetworkTypeMobile(type)) {
- mNetworkActive = false;
- }
- mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true,
- SystemClock.elapsedRealtimeNanos(), -1));
- }
- }
-
- @Override
- public void removeIdleTimer(String iface) {
- NetworkStack.checkNetworkStackPermission(mContext);
-
- if (DBG) Slog.d(TAG, "Removing idletimer");
-
- synchronized (mIdleTimerLock) {
- final IdleTimerParams params = mActiveIdleTimers.get(iface);
- if (params == null || --(params.networkCount) > 0) {
- return;
- }
-
- try {
- mNetdService.idletimerRemoveInterface(iface,
- params.timeout, Integer.toString(params.type));
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- mActiveIdleTimers.remove(iface);
- mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false,
- SystemClock.elapsedRealtimeNanos(), -1));
- }
- }
-
- @Override
public void setInterfaceQuota(String iface, long quotaBytes) {
NetworkStack.checkNetworkStackPermission(mContext);
@@ -1813,44 +1687,9 @@
}
@Override
- public void registerNetworkActivityListener(INetworkActivityListener listener) {
- mNetworkActivityListeners.register(listener);
- }
-
- @Override
- public void unregisterNetworkActivityListener(INetworkActivityListener listener) {
- mNetworkActivityListeners.unregister(listener);
- }
-
- @Override
- public boolean isNetworkActive() {
- synchronized (mNetworkActivityListeners) {
- return mNetworkActive || mActiveIdleTimers.isEmpty();
- }
- }
-
- private void reportNetworkActive() {
- final int length = mNetworkActivityListeners.beginBroadcast();
- try {
- for (int i = 0; i < length; i++) {
- try {
- mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
- } catch (RemoteException | RuntimeException e) {
- }
- }
- } finally {
- mNetworkActivityListeners.finishBroadcast();
- }
- }
-
- @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
- pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio);
- pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio);
- pw.print("mNetworkActive="); pw.println(mNetworkActive);
-
synchronized (mQuotaLock) {
pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
@@ -1882,17 +1721,6 @@
mUidFirewallRestrictedRules);
}
- synchronized (mIdleTimerLock) {
- pw.println("Idle timers:");
- for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
- pw.print(" "); pw.print(ent.getKey()); pw.println(":");
- IdleTimerParams params = ent.getValue();
- pw.print(" timeout="); pw.print(params.timeout);
- pw.print(" type="); pw.print(params.type);
- pw.print(" networkCount="); pw.println(params.networkCount);
- }
- }
-
pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
pw.print("Netd service status: " );
if (mNetdService == null) {
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index b15a886..e19745e 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -40,6 +40,7 @@
import android.hardware.biometrics.IBiometricServiceReceiver;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.face.IFaceService;
@@ -144,13 +145,14 @@
private final class AuthServiceImpl extends IAuthService.Stub {
@Override
- public ITestSession createTestSession(int sensorId, @NonNull String opPackageName)
- throws RemoteException {
+ public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) throws RemoteException {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
final long identity = Binder.clearCallingIdentity();
try {
- return mInjector.getBiometricService().createTestSession(sensorId, opPackageName);
+ return mInjector.getBiometricService()
+ .createTestSession(sensorId, callback, opPackageName);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 614c5f1..00a4e43 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -44,6 +44,7 @@
import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
@@ -570,13 +571,13 @@
*/
private final class BiometricServiceWrapper extends IBiometricService.Stub {
@Override // Binder call
- public ITestSession createTestSession(int sensorId, @NonNull String opPackageName)
- throws RemoteException {
+ public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) throws RemoteException {
checkInternalPermission();
for (BiometricSensor sensor : mSensors) {
if (sensor.id == sensorId) {
- return sensor.impl.createTestSession(opPackageName);
+ return sensor.impl.createTestSession(callback, opPackageName);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
index 57efd22..8197edc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
@@ -37,18 +37,16 @@
private static final String TAG = "Biometrics/RemovalClient";
- protected final int mBiometricId;
private final BiometricUtils<S> mBiometricUtils;
private final Map<Integer, Long> mAuthenticatorIds;
public RemovalClient(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon,
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
- int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils<S> utils,
- int sensorId, @NonNull Map<Integer, Long> authenticatorIds, int statsModality) {
+ int userId, @NonNull String owner, @NonNull BiometricUtils<S> utils, int sensorId,
+ @NonNull Map<Integer, Long> authenticatorIds, int statsModality) {
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
statsModality, BiometricsProtoEnums.ACTION_REMOVE,
BiometricsProtoEnums.CLIENT_UNKNOWN);
- mBiometricId = biometricId;
mBiometricUtils = utils;
mAuthenticatorIds = authenticatorIds;
}
@@ -68,6 +66,7 @@
@Override
public void onRemoved(@Nullable BiometricAuthenticator.Identifier identifier, int remaining) {
+ Slog.d(TAG, "onRemoved: " + identifier.getBiometricId() + " remaining: " + remaining);
if (identifier != null) {
mBiometricUtils.removeBiometricForUser(getContext(), getTargetUserId(),
identifier.getBiometricId());
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
index f37cf18..06b049b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
@@ -21,6 +21,7 @@
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.face.IFaceService;
import android.os.IBinder;
@@ -41,8 +42,9 @@
}
@Override
- public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException {
- return mFaceService.createTestSession(mSensorId, opPackageName);
+ public ITestSession createTestSession(@NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) throws RemoteException {
+ return mFaceService.createTestSession(mSensorId, callback, opPackageName);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 8253927..6dbd590 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -31,6 +31,7 @@
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.face.IFace;
import android.hardware.biometrics.face.SensorProps;
import android.hardware.face.Face;
@@ -133,7 +134,8 @@
*/
private final class FaceServiceWrapper extends IFaceService.Stub {
@Override
- public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) {
+ public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -143,7 +145,7 @@
return null;
}
- return provider.createTestSession(sensorId, opPackageName);
+ return provider.createTestSession(sensorId, callback, opPackageName);
}
@Override
@@ -386,7 +388,22 @@
opPackageName);
}
- @Override
+ @Override // Binder call
+ public void removeAll(final IBinder token, final int userId,
+ final IFaceServiceReceiver receiver, final String opPackageName) {
+ Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+ if (provider == null) {
+ Slog.w(TAG, "Null provider for removeAll");
+ return;
+ }
+
+ provider.second.scheduleRemoveAll(provider.first, token, userId, receiver,
+ opPackageName);
+ }
+
+ @Override // Binder call
public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
final String opPackageName) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
index cc24b89..88edfbf 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.face.Face;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
@@ -28,6 +29,7 @@
import android.os.NativeHandle;
import android.util.proto.ProtoOutputStream;
+import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutTracker;
@@ -109,6 +111,9 @@
void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId,
@NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName);
+ void scheduleRemoveAll(int sensorId, @NonNull IBinder token, int userId,
+ @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName);
+
void scheduleResetLockout(int sensorId, int userId, @NonNull byte[] hardwareAuthToken);
void scheduleSetFeature(int sensorId, @NonNull IBinder token, int userId, int feature,
@@ -120,7 +125,8 @@
void startPreparedClient(int sensorId, int cookie);
- void scheduleInternalCleanup(int sensorId, int userId);
+ void scheduleInternalCleanup(int sensorId, int userId,
+ @Nullable BaseClientMonitor.Callback callback);
void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
boolean clearSchedulerBuffer);
@@ -130,7 +136,8 @@
void dumpInternal(int sensorId, @NonNull PrintWriter pw);
@NonNull
- ITestSession createTestSession(int sensorId, @NonNull String opPackageName);
+ ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName);
void dumpHal(int sensorId, @NonNull FileDescriptor fd, @NonNull String[] args);
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
index 897ebd7..a5e6ddb 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.face.AuthenticationFrame;
import android.hardware.biometrics.face.BaseFrame;
import android.hardware.face.Face;
@@ -28,10 +29,12 @@
import android.hardware.face.FaceEnrollFrame;
import android.hardware.face.IFaceServiceReceiver;
import android.os.Binder;
+import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.Utils;
+import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.face.FaceUtils;
import java.util.HashSet;
@@ -49,6 +52,7 @@
@NonNull private final Context mContext;
private final int mSensorId;
+ @NonNull private final ITestSessionCallback mCallback;
@NonNull private final FaceProvider mProvider;
@NonNull private final Sensor mSensor;
@NonNull private final Set<Integer> mEnrollmentIds;
@@ -132,9 +136,11 @@
};
BiometricTestSessionImpl(@NonNull Context context, int sensorId,
+ @NonNull ITestSessionCallback callback,
@NonNull FaceProvider provider, @NonNull Sensor sensor) {
mContext = context;
mSensorId = sensorId;
+ mCallback = callback;
mProvider = provider;
mSensor = sensor;
mEnrollmentIds = new HashSet<>();
@@ -224,6 +230,25 @@
public void cleanupInternalState(int userId) {
Utils.checkPermission(mContext, TEST_BIOMETRIC);
- mProvider.scheduleInternalCleanup(mSensorId, userId);
+ mProvider.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() {
+ @Override
+ public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
+ try {
+ mCallback.onCleanupStarted(clientMonitor.getTargetUserId());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+ }
+
+ @Override
+ public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
+ boolean success) {
+ try {
+ mCallback.onCleanupFinished(clientMonitor.getTargetUserId());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+ }
+ });
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java
index 9680e4e..c6696aed 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java
@@ -61,7 +61,7 @@
// Internal remove does not need to send results to anyone. Cleanup (enumerate + remove)
// is all done internally.
return new FaceRemovalClient(context, lazyDaemon, token,
- null /* ClientMonitorCallbackConverter */, biometricId, userId, owner, utils,
- sensorId, authenticatorIds);
+ null /* ClientMonitorCallbackConverter */, new int[] {biometricId}, userId, owner,
+ utils, sensorId, authenticatorIds);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 1b6b9d7..1d8f210 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -25,6 +25,7 @@
import android.content.pm.UserInfo;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.face.IFace;
import android.hardware.biometrics.face.SensorProps;
import android.hardware.face.Face;
@@ -177,7 +178,8 @@
for (int i = 0; i < mSensors.size(); i++) {
final int sensorId = mSensors.keyAt(i);
scheduleLoadAuthenticatorIds(sensorId);
- scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser());
+ scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser(),
+ null /* callback */);
}
return mDaemon;
@@ -468,6 +470,25 @@
@Override
public void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId,
@NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
+ scheduleRemoveSpecifiedIds(sensorId, token, new int[] {faceId}, userId, receiver,
+ opPackageName);
+ }
+
+ @Override
+ public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, int userId,
+ @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
+ final List<Face> faces = FaceUtils.getInstance(sensorId)
+ .getBiometricsForUser(mContext, userId);
+ final int[] faceIds = new int[faces.size()];
+ for (int i = 0; i < faces.size(); i++) {
+ faceIds[i] = faces.get(i).getBiometricId();
+ }
+
+ scheduleRemoveSpecifiedIds(sensorId, token, faceIds, userId, receiver, opPackageName);
+ }
+
+ private void scheduleRemoveSpecifiedIds(int sensorId, @NonNull IBinder token, int[] faceIds,
+ int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
mHandler.post(() -> {
final IFace daemon = getHalInstance();
if (daemon == null) {
@@ -485,7 +506,7 @@
final FaceRemovalClient client = new FaceRemovalClient(mContext,
mSensors.get(sensorId).getLazySession(), token,
- new ClientMonitorCallbackConverter(receiver), faceId, userId,
+ new ClientMonitorCallbackConverter(receiver), faceIds, userId,
opPackageName, FaceUtils.getInstance(sensorId), sensorId,
mSensors.get(sensorId).getAuthenticatorIds());
@@ -543,7 +564,8 @@
}
@Override
- public void scheduleInternalCleanup(int sensorId, int userId) {
+ public void scheduleInternalCleanup(int sensorId, int userId,
+ @Nullable BaseClientMonitor.Callback callback) {
mHandler.post(() -> {
final IFace daemon = getHalInstance();
if (daemon == null) {
@@ -564,7 +586,7 @@
FaceUtils.getInstance(sensorId),
mSensors.get(sensorId).getAuthenticatorIds());
- mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
+ mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback);
} catch (RemoteException e) {
Slog.e(getTag(), "Remote exception when scheduling internal cleanup", e);
}
@@ -627,8 +649,9 @@
@NonNull
@Override
- public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) {
- return mSensors.get(sensorId).createTestSession();
+ public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) {
+ return mSensors.get(sensorId).createTestSession(callback);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java
index 1cb5031..48796c1 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java
@@ -38,19 +38,22 @@
class FaceRemovalClient extends RemovalClient<Face, ISession> {
private static final String TAG = "FaceRemovalClient";
+ final int[] mBiometricIds;
+
FaceRemovalClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon,
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
- int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils<Face> utils,
- int sensorId, @NonNull Map<Integer, Long> authenticatorIds) {
- super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId,
+ int[] biometricIds, int userId, @NonNull String owner,
+ @NonNull BiometricUtils<Face> utils, int sensorId,
+ @NonNull Map<Integer, Long> authenticatorIds) {
+ super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId,
authenticatorIds, BiometricsProtoEnums.MODALITY_FACE);
+ mBiometricIds = biometricIds;
}
@Override
protected void startHalOperation() {
try {
- final int[] ids = new int[]{mBiometricId};
- getFreshDaemon().removeEnrollments(mSequentialId, ids);
+ getFreshDaemon().removeEnrollments(mSequentialId, mBiometricIds);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting remove", e);
mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
index 4925ce0..3434acb 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
@@ -22,6 +22,7 @@
import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.face.AuthenticationFrame;
import android.hardware.biometrics.face.EnrollmentFrame;
import android.hardware.biometrics.face.Error;
@@ -459,8 +460,9 @@
}
}
- @NonNull ITestSession createTestSession() {
- return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, mProvider, this);
+ @NonNull ITestSession createTestSession(@NonNull ITestSessionCallback callback) {
+ return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback,
+ mProvider, this);
}
void createNewSession(@NonNull IFace daemon, int sensorId, int userId)
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
index d519d60..e8668ed 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
@@ -21,14 +21,17 @@
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.face.Face;
import android.hardware.face.FaceAuthenticationFrame;
import android.hardware.face.FaceEnrollFrame;
import android.hardware.face.IFaceServiceReceiver;
import android.os.Binder;
+import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.Utils;
+import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.face.FaceUtils;
import java.util.ArrayList;
@@ -43,6 +46,7 @@
@NonNull private final Context mContext;
private final int mSensorId;
+ @NonNull private final ITestSessionCallback mCallback;
@NonNull private final Face10 mFace10;
@NonNull private final Face10.HalResultController mHalResultController;
@NonNull private final Set<Integer> mEnrollmentIds;
@@ -120,10 +124,12 @@
}
};
- BiometricTestSessionImpl(@NonNull Context context, int sensorId, @NonNull Face10 face10,
+ BiometricTestSessionImpl(@NonNull Context context, int sensorId,
+ @NonNull ITestSessionCallback callback, @NonNull Face10 face10,
@NonNull Face10.HalResultController halResultController) {
mContext = context;
mSensorId = sensorId;
+ mCallback = callback;
mFace10 = face10;
mHalResultController = halResultController;
mEnrollmentIds = new HashSet<>();
@@ -201,6 +207,25 @@
public void cleanupInternalState(int userId) {
Utils.checkPermission(mContext, TEST_BIOMETRIC);
- mFace10.scheduleInternalCleanup(mSensorId, userId);
+ mFace10.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() {
+ @Override
+ public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
+ try {
+ mCallback.onCleanupStarted(clientMonitor.getTargetUserId());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+ }
+
+ @Override
+ public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
+ boolean success) {
+ try {
+ mCallback.onCleanupFinished(clientMonitor.getTargetUserId());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+ }
+ });
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index e46661a..ee8823e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -29,6 +29,7 @@
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback;
import android.hardware.face.Face;
@@ -123,7 +124,7 @@
private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() {
@Override
public void onUserSwitching(int newUserId) {
- scheduleInternalCleanup(newUserId);
+ scheduleInternalCleanup(newUserId, null /* callback */);
scheduleGetFeature(mSensorId, new Binder(), newUserId,
BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION,
null, mContext.getOpPackageName());
@@ -437,7 +438,7 @@
Slog.d(TAG, "Face HAL ready, HAL ID: " + halId);
if (halId != 0) {
scheduleLoadAuthenticatorIds();
- scheduleInternalCleanup(ActivityManager.getCurrentUser());
+ scheduleInternalCleanup(ActivityManager.getCurrentUser(), null /* callback */);
scheduleGetFeature(mSensorId, new Binder(),
ActivityManager.getCurrentUser(),
BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION, null,
@@ -671,6 +672,20 @@
});
}
+ @Override
+ public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, int userId,
+ @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
+ mHandler.post(() -> {
+ scheduleUpdateActiveUserWithoutHandler(userId);
+
+ // For IBiometricsFace@1.0, remove(0) means remove all enrollments
+ final FaceRemovalClient client = new FaceRemovalClient(mContext, mLazyDaemon, token,
+ new ClientMonitorCallbackConverter(receiver), 0 /* faceId */, userId,
+ opPackageName,
+ FaceUtils.getLegacyInstance(mSensorId), mSensorId, mAuthenticatorIds);
+ mScheduler.scheduleClientMonitor(client);
+ });
+ }
@Override
public void scheduleResetLockout(int sensorId, int userId, @NonNull byte[] hardwareAuthToken) {
@@ -742,7 +757,8 @@
});
}
- private void scheduleInternalCleanup(int userId) {
+ private void scheduleInternalCleanup(int userId,
+ @Nullable BaseClientMonitor.Callback callback) {
mHandler.post(() -> {
scheduleUpdateActiveUserWithoutHandler(userId);
@@ -750,13 +766,14 @@
final FaceInternalCleanupClient client = new FaceInternalCleanupClient(mContext,
mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId, enrolledList,
FaceUtils.getLegacyInstance(mSensorId), mAuthenticatorIds);
- mScheduler.scheduleClientMonitor(client);
+ mScheduler.scheduleClientMonitor(client, callback);
});
}
@Override
- public void scheduleInternalCleanup(int sensorId, int userId) {
- scheduleInternalCleanup(userId);
+ public void scheduleInternalCleanup(int sensorId, int userId,
+ @Nullable BaseClientMonitor.Callback callback) {
+ scheduleInternalCleanup(userId, callback);
}
@Override
@@ -930,7 +947,9 @@
@NonNull
@Override
- public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) {
- return new BiometricTestSessionImpl(mContext, mSensorId, this, mHalResultController);
+ public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) {
+ return new BiometricTestSessionImpl(mContext, mSensorId, callback, this,
+ mHalResultController);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java
index d63791c..3ae2011 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java
@@ -38,12 +38,15 @@
class FaceRemovalClient extends RemovalClient<Face, IBiometricsFace> {
private static final String TAG = "FaceRemovalClient";
+ private final int mBiometricId;
+
FaceRemovalClient(@NonNull Context context, @NonNull LazyDaemon<IBiometricsFace> lazyDaemon,
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils<Face> utils,
int sensorId, @NonNull Map<Integer, Long> authenticatorIds) {
- super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId,
+ super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId,
authenticatorIds, BiometricsProtoEnums.MODALITY_FACE);
+ mBiometricId = biometricId;
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
index 34a9099..32e9409 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
@@ -21,6 +21,7 @@
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintService;
import android.os.IBinder;
@@ -42,8 +43,9 @@
}
@Override
- public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException {
- return mFingerprintService.createTestSession(mSensorId, opPackageName);
+ public ITestSession createTestSession(@NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) throws RemoteException {
+ return mFingerprintService.createTestSession(mSensorId, callback, opPackageName);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index b0e42cd..396dd5f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -43,6 +43,7 @@
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.SensorProps;
import android.hardware.fingerprint.Fingerprint;
@@ -109,7 +110,8 @@
*/
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
@Override
- public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) {
+ public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -119,7 +121,7 @@
return null;
}
- return provider.createTestSession(sensorId, opPackageName);
+ return provider.createTestSession(sensorId, callback, opPackageName);
}
@Override
@@ -499,7 +501,21 @@
opPackageName);
}
- @Override
+ @Override // Binder call
+ public void removeAll(final IBinder token, final int userId,
+ final IFingerprintServiceReceiver receiver, final String opPackageName) {
+ Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
+
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+ if (provider == null) {
+ Slog.w(TAG, "Null provider for removeAll");
+ return;
+ }
+ provider.second.scheduleRemoveAll(provider.first, token, receiver, userId,
+ opPackageName);
+ }
+
+ @Override // Binder call
public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
final String opPackageName) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
index f672ae5..dfec2e3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -28,6 +29,7 @@
import android.os.IBinder;
import android.util.proto.ProtoOutputStream;
+import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutTracker;
@@ -98,7 +100,12 @@
@NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId,
@NonNull String opPackageName);
- void scheduleInternalCleanup(int sensorId, int userId);
+ void scheduleRemoveAll(int sensorId, @NonNull IBinder token,
+ @NonNull IFingerprintServiceReceiver receiver, int userId,
+ @NonNull String opPackageName);
+
+ void scheduleInternalCleanup(int sensorId, int userId,
+ @Nullable BaseClientMonitor.Callback callback);
boolean isHardwareDetected(int sensorId);
@@ -133,5 +140,6 @@
void dumpInternal(int sensorId, @NonNull PrintWriter pw);
@NonNull
- ITestSession createTestSession(int sensorId, @NonNull String opPackageName);
+ ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName);
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
index ea9c709..20b3254 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
@@ -21,14 +21,17 @@
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.os.Binder;
+import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.Utils;
+import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import java.util.HashSet;
@@ -46,6 +49,7 @@
@NonNull private final Context mContext;
private final int mSensorId;
+ @NonNull private final ITestSessionCallback mCallback;
@NonNull private final FingerprintProvider mProvider;
@NonNull private final Sensor mSensor;
@NonNull private final Set<Integer> mEnrollmentIds;
@@ -110,9 +114,11 @@
};
BiometricTestSessionImpl(@NonNull Context context, int sensorId,
- @NonNull FingerprintProvider provider, @NonNull Sensor sensor) {
+ @NonNull ITestSessionCallback callback, @NonNull FingerprintProvider provider,
+ @NonNull Sensor sensor) {
mContext = context;
mSensorId = sensorId;
+ mCallback = callback;
mProvider = provider;
mSensor = sensor;
mEnrollmentIds = new HashSet<>();
@@ -192,6 +198,25 @@
public void cleanupInternalState(int userId) {
Utils.checkPermission(mContext, TEST_BIOMETRIC);
- mProvider.scheduleInternalCleanup(mSensorId, userId);
+ mProvider.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() {
+ @Override
+ public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
+ try {
+ mCallback.onCleanupStarted(clientMonitor.getTargetUserId());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+ }
+
+ @Override
+ public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
+ boolean success) {
+ try {
+ mCallback.onCleanupFinished(clientMonitor.getTargetUserId());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+ }
+ });
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java
index 2a0e984..0de3f4f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java
@@ -60,7 +60,7 @@
String owner, BiometricUtils<Fingerprint> utils, int sensorId,
Map<Integer, Long> authenticatorIds) {
return new FingerprintRemovalClient(context, lazyDaemon, token,
- null /* ClientMonitorCallbackConverter */, biometricId, userId, owner, utils,
- sensorId, authenticatorIds);
+ null /* ClientMonitorCallbackConverter */, new int[] {biometricId}, userId, owner,
+ utils, sensorId, authenticatorIds);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 0bd2f24..598cc89 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -25,6 +25,7 @@
import android.content.pm.UserInfo;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.SensorProps;
import android.hardware.fingerprint.Fingerprint;
@@ -185,7 +186,8 @@
for (int i = 0; i < mSensors.size(); i++) {
final int sensorId = mSensors.keyAt(i);
scheduleLoadAuthenticatorIds(sensorId);
- scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser());
+ scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser(),
+ null /* callback */);
}
return mDaemon;
@@ -490,6 +492,27 @@
public void scheduleRemove(int sensorId, @NonNull IBinder token,
@NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId,
@NonNull String opPackageName) {
+ scheduleRemoveSpecifiedIds(sensorId, token, new int[] {fingerId}, userId, receiver,
+ opPackageName);
+ }
+
+ @Override
+ public void scheduleRemoveAll(int sensorId, @NonNull IBinder token,
+ @NonNull IFingerprintServiceReceiver receiver, int userId,
+ @NonNull String opPackageName) {
+ final List<Fingerprint> fingers = FingerprintUtils.getInstance(sensorId)
+ .getBiometricsForUser(mContext, userId);
+ final int[] fingerIds = new int[fingers.size()];
+ for (int i = 0; i < fingers.size(); i++) {
+ fingerIds[i] = fingers.get(i).getBiometricId();
+ }
+
+ scheduleRemoveSpecifiedIds(sensorId, token, fingerIds, userId, receiver, opPackageName);
+ }
+
+ private void scheduleRemoveSpecifiedIds(int sensorId, @NonNull IBinder token,
+ int[] fingerprintIds, int userId, @NonNull IFingerprintServiceReceiver receiver,
+ @NonNull String opPackageName) {
mHandler.post(() -> {
final IFingerprint daemon = getHalInstance();
if (daemon == null) {
@@ -507,7 +530,7 @@
final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext,
mSensors.get(sensorId).getLazySession(), token,
- new ClientMonitorCallbackConverter(receiver), fingerId, userId,
+ new ClientMonitorCallbackConverter(receiver), fingerprintIds, userId,
opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
mSensors.get(sensorId).getAuthenticatorIds());
mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
@@ -518,7 +541,8 @@
}
@Override
- public void scheduleInternalCleanup(int sensorId, int userId) {
+ public void scheduleInternalCleanup(int sensorId, int userId,
+ @Nullable BaseClientMonitor.Callback callback) {
mHandler.post(() -> {
final IFingerprint daemon = getHalInstance();
if (daemon == null) {
@@ -538,7 +562,7 @@
mContext.getOpPackageName(), sensorId, enrolledList,
FingerprintUtils.getInstance(sensorId),
mSensors.get(sensorId).getAuthenticatorIds());
- mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
+ mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback);
} catch (RemoteException e) {
Slog.e(getTag(), "Remote exception when scheduling internal cleanup", e);
}
@@ -683,8 +707,9 @@
@NonNull
@Override
- public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) {
- return mSensors.get(sensorId).createTestSession();
+ public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) {
+ return mSensors.get(sensorId).createTestSession(callback);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java
index 4a99a7b..c622208 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java
@@ -39,20 +39,22 @@
class FingerprintRemovalClient extends RemovalClient<Fingerprint, ISession> {
private static final String TAG = "FingerprintRemovalClient";
+ private final int[] mBiometricIds;
+
FingerprintRemovalClient(@NonNull Context context,
@NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token,
- @Nullable ClientMonitorCallbackConverter listener, int biometricId, int userId,
+ @Nullable ClientMonitorCallbackConverter listener, int[] biometricIds, int userId,
@NonNull String owner, @NonNull BiometricUtils<Fingerprint> utils, int sensorId,
@NonNull Map<Integer, Long> authenticatorIds) {
- super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId,
+ super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId,
authenticatorIds, BiometricsProtoEnums.MODALITY_FINGERPRINT);
+ mBiometricIds = biometricIds;
}
@Override
protected void startHalOperation() {
try {
- final int[] ids = new int[] {mBiometricId};
- getFreshDaemon().removeEnrollments(mSequentialId, ids);
+ getFreshDaemon().removeEnrollments(mSequentialId, mBiometricIds);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting remove", e);
mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
index c83c0fb..a98e7db 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
@@ -22,6 +22,7 @@
import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.fingerprint.Error;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.ISession;
@@ -439,8 +440,9 @@
}
}
- @NonNull ITestSession createTestSession() {
- return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, mProvider, this);
+ @NonNull ITestSession createTestSession(@NonNull ITestSessionCallback callback) {
+ return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback,
+ mProvider, this);
}
void createNewSession(@NonNull IFingerprint daemon, int sensorId, int userId)
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
index 312ee0a..766a882 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
@@ -21,13 +21,16 @@
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.os.Binder;
+import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.Utils;
+import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import java.util.ArrayList;
@@ -47,6 +50,7 @@
@NonNull private final Context mContext;
private final int mSensorId;
+ @NonNull private final ITestSessionCallback mCallback;
@NonNull private final Fingerprint21 mFingerprint21;
@NonNull private final Fingerprint21.HalResultController mHalResultController;
@NonNull private final Set<Integer> mEnrollmentIds;
@@ -111,10 +115,12 @@
};
BiometricTestSessionImpl(@NonNull Context context, int sensorId,
+ @NonNull ITestSessionCallback callback,
@NonNull Fingerprint21 fingerprint21,
@NonNull Fingerprint21.HalResultController halResultController) {
mContext = context;
mSensorId = sensorId;
+ mCallback = callback;
mFingerprint21 = fingerprint21;
mHalResultController = halResultController;
mEnrollmentIds = new HashSet<>();
@@ -191,6 +197,25 @@
public void cleanupInternalState(int userId) {
Utils.checkPermission(mContext, TEST_BIOMETRIC);
- mFingerprint21.scheduleInternalCleanup(mSensorId, userId);
+ mFingerprint21.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() {
+ @Override
+ public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
+ try {
+ mCallback.onCleanupStarted(clientMonitor.getTargetUserId());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+ }
+
+ @Override
+ public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
+ boolean success) {
+ try {
+ mCallback.onCleanupFinished(clientMonitor.getTargetUserId());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+ }
+ });
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 554e3d4..6e22a79 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -30,6 +30,7 @@
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback;
import android.hardware.fingerprint.Fingerprint;
@@ -158,7 +159,7 @@
private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() {
@Override
public void onUserSwitching(int newUserId) {
- scheduleInternalCleanup(newUserId);
+ scheduleInternalCleanup(newUserId, null /* callback */);
}
};
@@ -437,7 +438,7 @@
Slog.d(TAG, "Fingerprint HAL ready, HAL ID: " + halId);
if (halId != 0) {
scheduleLoadAuthenticatorIds();
- scheduleInternalCleanup(ActivityManager.getCurrentUser());
+ scheduleInternalCleanup(ActivityManager.getCurrentUser(), null /* callback */);
} else {
Slog.e(TAG, "Unable to set callback");
mDaemon = null;
@@ -644,7 +645,25 @@
});
}
- private void scheduleInternalCleanup(int userId) {
+ @Override
+ public void scheduleRemoveAll(int sensorId, @NonNull IBinder token,
+ @NonNull IFingerprintServiceReceiver receiver, int userId,
+ @NonNull String opPackageName) {
+ mHandler.post(() -> {
+ scheduleUpdateActiveUserWithoutHandler(userId);
+
+ // For IBiometricsFingerprint@2.1, remove(0) means remove all enrollments
+ final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext,
+ mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver),
+ 0 /* fingerprintId */, userId, opPackageName,
+ FingerprintUtils.getLegacyInstance(mSensorId),
+ mSensorProperties.sensorId, mAuthenticatorIds);
+ mScheduler.scheduleClientMonitor(client);
+ });
+ }
+
+ private void scheduleInternalCleanup(int userId,
+ @Nullable BaseClientMonitor.Callback callback) {
mHandler.post(() -> {
scheduleUpdateActiveUserWithoutHandler(userId);
@@ -654,13 +673,14 @@
mContext, mLazyDaemon, userId, mContext.getOpPackageName(),
mSensorProperties.sensorId, enrolledList,
FingerprintUtils.getLegacyInstance(mSensorId), mAuthenticatorIds);
- mScheduler.scheduleClientMonitor(client);
+ mScheduler.scheduleClientMonitor(client, callback);
});
}
@Override
- public void scheduleInternalCleanup(int sensorId, int userId) {
- scheduleInternalCleanup(userId);
+ public void scheduleInternalCleanup(int sensorId, int userId,
+ @Nullable BaseClientMonitor.Callback callback) {
+ scheduleInternalCleanup(userId, callback);
}
@Override
@@ -840,8 +860,9 @@
@NonNull
@Override
- public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) {
- return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, this,
+ public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) {
+ return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback, this,
mHalResultController);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java
index f6a22f5..2f360f3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java
@@ -39,13 +39,16 @@
class FingerprintRemovalClient extends RemovalClient<Fingerprint, IBiometricsFingerprint> {
private static final String TAG = "FingerprintRemovalClient";
+ private final int mBiometricId;
+
FingerprintRemovalClient(@NonNull Context context,
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter listener, int biometricId, int userId,
@NonNull String owner, @NonNull BiometricUtils<Fingerprint> utils, int sensorId,
@NonNull Map<Integer, Long> authenticatorIds) {
- super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId,
+ super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId,
authenticatorIds, BiometricsProtoEnums.MODALITY_FINGERPRINT);
+ mBiometricId = biometricId;
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
index 8e84613..f44e069 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
@@ -21,6 +21,7 @@
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
+import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.iris.IIrisService;
import android.os.IBinder;
@@ -39,7 +40,8 @@
}
@Override
- public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException {
+ public ITestSession createTestSession(@NonNull ITestSessionCallback callback,
+ @NonNull String opPackageName) throws RemoteException {
return null;
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 685e9e6..8da2d67 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -2902,11 +2902,8 @@
FingerprintManager mFingerprintManager = mInjector.getFingerprintManager();
if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
if (mFingerprintManager.hasEnrolledFingerprints(userId)) {
- CountDownLatch latch = new CountDownLatch(1);
- // For the purposes of M and N, groupId is the same as userId.
- Fingerprint finger = new Fingerprint(null, userId, 0, 0);
- mFingerprintManager.remove(finger, userId,
- fingerprintManagerRemovalCallback(latch));
+ final CountDownLatch latch = new CountDownLatch(1);
+ mFingerprintManager.removeAll(userId, fingerprintManagerRemovalCallback(latch));
try {
latch.await(10000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
@@ -2920,9 +2917,8 @@
FaceManager mFaceManager = mInjector.getFaceManager();
if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
if (mFaceManager.hasEnrolledTemplates(userId)) {
- CountDownLatch latch = new CountDownLatch(1);
- Face face = new Face(null, 0, 0);
- mFaceManager.remove(face, userId, faceManagerRemovalCallback(latch));
+ final CountDownLatch latch = new CountDownLatch(1);
+ mFaceManager.removeAll(userId, faceManagerRemovalCallback(latch));
try {
latch.await(10000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
@@ -2936,10 +2932,8 @@
CountDownLatch latch) {
return new FingerprintManager.RemovalCallback() {
@Override
- public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence err) {
- Slog.e(TAG, String.format(
- "Can't remove fingerprint %d in group %d. Reason: %s",
- fp.getBiometricId(), fp.getGroupId(), err));
+ public void onRemovalError(@Nullable Fingerprint fp, int errMsgId, CharSequence err) {
+ Slog.e(TAG, "Unable to remove fingerprint, error: " + err);
latch.countDown();
}
@@ -2955,9 +2949,8 @@
private FaceManager.RemovalCallback faceManagerRemovalCallback(CountDownLatch latch) {
return new FaceManager.RemovalCallback() {
@Override
- public void onRemovalError(Face face, int errMsgId, CharSequence err) {
- Slog.e(TAG, String.format("Can't remove face %d. Reason: %s",
- face.getBiometricId(), err));
+ public void onRemovalError(@Nullable Face face, int errMsgId, CharSequence err) {
+ Slog.e(TAG, "Unable to remove face, error: " + err);
latch.countDown();
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 1f66c7c..67d6929 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -339,11 +339,11 @@
mService.setLockCredential(nonePassword(), newPattern("123654"), PRIMARY_USER_ID);
// Verify fingerprint is removed
- verify(mFingerprintManager).remove(any(), eq(PRIMARY_USER_ID), any());
- verify(mFaceManager).remove(any(), eq(PRIMARY_USER_ID), any());
+ verify(mFingerprintManager).removeAll(eq(PRIMARY_USER_ID), any());
+ verify(mFaceManager).removeAll(eq(PRIMARY_USER_ID), any());
- verify(mFingerprintManager).remove(any(), eq(MANAGED_PROFILE_USER_ID), any());
- verify(mFaceManager).remove(any(), eq(MANAGED_PROFILE_USER_ID), any());
+ verify(mFingerprintManager).removeAll(eq(MANAGED_PROFILE_USER_ID), any());
+ verify(mFaceManager).removeAll(eq(MANAGED_PROFILE_USER_ID), any());
}
@Test
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index f687e4b..7669883 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -430,25 +430,17 @@
// Eventually it will be an error to not specify this.
setCurInteractor(new ComponentName(curInteractorInfo.getServiceInfo().packageName,
curInteractorInfo.getServiceInfo().name), userHandle);
- if (curInteractorInfo.getRecognitionService() != null) {
- setCurRecognizer(
- new ComponentName(curInteractorInfo.getServiceInfo().packageName,
- curInteractorInfo.getRecognitionService()), userHandle);
- return;
- }
+ } else {
+ // No voice interactor, so clear the setting.
+ setCurInteractor(null, userHandle);
}
- // No voice interactor, we'll just set up a simple recognizer.
- initSimpleRecognizer(curInteractorInfo, userHandle);
+ initRecognizer(userHandle);
}
- public void initSimpleRecognizer(VoiceInteractionServiceInfo curInteractorInfo,
- int userHandle) {
+ public void initRecognizer(int userHandle) {
ComponentName curRecognizer = findAvailRecognizer(null, userHandle);
if (curRecognizer != null) {
- if (curInteractorInfo == null) {
- setCurInteractor(null, userHandle);
- }
setCurRecognizer(curRecognizer, userHandle);
}
}
@@ -1772,7 +1764,9 @@
synchronized (VoiceInteractionManagerServiceStub.this) {
Slog.i(TAG, "Force stopping current voice recognizer: "
+ getCurRecognizer(userHandle));
- initSimpleRecognizer(null, userHandle);
+ // TODO: Figure out why the interactor was being cleared and document it.
+ setCurInteractor(null, userHandle);
+ initRecognizer(userHandle);
}
}
return hitInt || hitRec;
@@ -1793,6 +1787,9 @@
if (isPackageAppearing(pkgName) != PACKAGE_UNCHANGED) {
return;
}
+ if (getCurRecognizer(mCurUser) == null) {
+ initRecognizer(mCurUser);
+ }
final String curInteractorStr = Settings.Secure.getStringForUser(
mContext.getContentResolver(),
Settings.Secure.VOICE_INTERACTION_SERVICE, mCurUser);
@@ -1807,12 +1804,6 @@
availInteractorInfo.getServiceInfo().packageName,
availInteractorInfo.getServiceInfo().name);
setCurInteractor(availInteractor, mCurUser);
- if (getCurRecognizer(mCurUser) == null &&
- availInteractorInfo.getRecognitionService() != null) {
- setCurRecognizer(new ComponentName(
- availInteractorInfo.getServiceInfo().packageName,
- availInteractorInfo.getRecognitionService()), mCurUser);
- }
}
} else {
if (didSomePackagesChange()) {
@@ -1843,10 +1834,7 @@
if (curRecognizer == null) {
// Could a new recognizer appear when we don't have one pre-installed?
if (anyPackagesAppearing()) {
- curRecognizer = findAvailRecognizer(null, userHandle);
- if (curRecognizer != null) {
- setCurRecognizer(curRecognizer, userHandle);
- }
+ initRecognizer(userHandle);
}
return;
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 495311c..ad2b3a1 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -8222,8 +8222,8 @@
reset(mNetworkManagementService);
mCellNetworkAgent.connect(true);
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
- verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
- eq(NetworkCapabilities.TRANSPORT_CELLULAR));
+ verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_CELLULAR)));
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
final LinkProperties wifiLp = new LinkProperties();
@@ -8231,25 +8231,27 @@
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
// Network switch
- reset(mNetworkManagementService);
mWiFiNetworkAgent.connect(true);
networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
- verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(),
- eq(NetworkCapabilities.TRANSPORT_WIFI));
- verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(MOBILE_IFNAME));
+ verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_WIFI)));
+ verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_CELLULAR)));
// Disconnect wifi and switch back to cell
- reset(mNetworkManagementService);
+ reset(mMockNetd);
mWiFiNetworkAgent.disconnect();
networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
assertNoCallbacks(networkCallback);
- verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
- verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
- eq(NetworkCapabilities.TRANSPORT_CELLULAR));
+ verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_WIFI)));
+ verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_CELLULAR)));
// reconnect wifi
+ reset(mMockNetd);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
wifiLp.setInterfaceName(WIFI_IFNAME);
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
@@ -8257,9 +8259,12 @@
networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+ verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_WIFI)));
+ verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_CELLULAR)));
// Disconnect cell
- reset(mNetworkManagementService);
reset(mMockNetd);
mCellNetworkAgent.disconnect();
networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
@@ -8267,17 +8272,18 @@
// sent as network being switched. Ensure rule removal for cell will not be triggered
// unexpectedly before network being removed.
waitForIdle();
- verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
+ verify(mMockNetd, times(0)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_CELLULAR)));
verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId));
verify(mMockDnsResolver, times(1))
.destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId));
// Disconnect wifi
ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
- reset(mNetworkManagementService);
mWiFiNetworkAgent.disconnect();
b.expectBroadcast();
- verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
+ verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(),
+ eq(Integer.toString(TRANSPORT_WIFI)));
// Clean up
mCm.unregisterNetworkCallback(networkCallback);