Prevent crash on death.
Fix: 212599471 bug: 208303000 Test: atest LockoutResetDispatcherTest Change-Id: Iedc772be7649ba2559ad45b946c5bd947680baf6
This commit is contained in:
@@ -25,7 +25,11 @@ import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Allows clients (such as keyguard) to register for notifications on when biometric lockout
|
||||
@@ -37,7 +41,8 @@ public class LockoutResetDispatcher implements IBinder.DeathRecipient {
|
||||
private static final String TAG = "LockoutResetTracker";
|
||||
|
||||
private final Context mContext;
|
||||
private final ArrayList<ClientCallback> mClientCallbacks;
|
||||
@VisibleForTesting
|
||||
final List<ClientCallback> mClientCallbacks = new ArrayList<>();
|
||||
|
||||
private static class ClientCallback {
|
||||
private static final long WAKELOCK_TIMEOUT_MS = 2000;
|
||||
@@ -81,7 +86,6 @@ public class LockoutResetDispatcher implements IBinder.DeathRecipient {
|
||||
|
||||
public LockoutResetDispatcher(Context context) {
|
||||
mContext = context;
|
||||
mClientCallbacks = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addCallback(IBiometricServiceLockoutResetCallback callback, String opPackageName) {
|
||||
@@ -106,11 +110,13 @@ public class LockoutResetDispatcher implements IBinder.DeathRecipient {
|
||||
@Override
|
||||
public void binderDied(IBinder who) {
|
||||
Slog.e(TAG, "Callback binder died: " + who);
|
||||
for (ClientCallback callback : mClientCallbacks) {
|
||||
final Iterator<ClientCallback> iterator = mClientCallbacks.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ClientCallback callback = iterator.next();
|
||||
if (callback.mCallback.asBinder().equals(who)) {
|
||||
Slog.e(TAG, "Removing dead callback for: " + callback.mOpPackageName);
|
||||
callback.releaseWakelock();
|
||||
mClientCallbacks.remove(callback);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.biometrics.sensors;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.testing.TestableContext;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@Presubmit
|
||||
@SmallTest
|
||||
public class LockoutResetDispatcherTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Rule
|
||||
public final TestableContext mContext = new TestableContext(
|
||||
InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
|
||||
|
||||
@Mock
|
||||
private IBinder mBinder;
|
||||
@Mock
|
||||
private IBiometricServiceLockoutResetCallback mCallback;
|
||||
|
||||
private LockoutResetDispatcher mDispatcher;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
when(mCallback.asBinder()).thenReturn(mBinder);
|
||||
mDispatcher = new LockoutResetDispatcher(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void linksToDeath() throws Exception {
|
||||
mDispatcher.addCallback(mCallback, "package");
|
||||
verify(mBinder).linkToDeath(eq(mDispatcher), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notifyLockoutReset() throws Exception {
|
||||
final int sensorId = 24;
|
||||
|
||||
mDispatcher.addCallback(mCallback, "some.package");
|
||||
mDispatcher.notifyLockoutResetCallbacks(sensorId);
|
||||
|
||||
final ArgumentCaptor<IRemoteCallback> captor =
|
||||
ArgumentCaptor.forClass(IRemoteCallback.class);
|
||||
verify(mCallback).onLockoutReset(eq(sensorId), captor.capture());
|
||||
captor.getValue().sendResult(new Bundle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void releaseWakeLockOnDeath() {
|
||||
mDispatcher.addCallback(mCallback, "a.b.cee");
|
||||
mDispatcher.binderDied(mBinder);
|
||||
|
||||
// would be better to check the wake lock
|
||||
// but this project lacks the extended mockito support to do it
|
||||
assertThat(mDispatcher.mClientCallbacks).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void releaseCorrectWakeLockOnDeath() {
|
||||
mDispatcher.addCallback(mCallback, "a.b");
|
||||
mDispatcher.binderDied(mock(IBinder.class));
|
||||
|
||||
assertThat(mDispatcher.mClientCallbacks).hasSize(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user