Merge "Warn the user when a streamed app requests authentication" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4ebdfbb31d
@@ -5392,11 +5392,11 @@
|
|||||||
<string name="app_streaming_blocked_message" product="tablet">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your tablet instead.</string>
|
<string name="app_streaming_blocked_message" product="tablet">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your tablet instead.</string>
|
||||||
<!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
|
<!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
|
||||||
<string name="app_streaming_blocked_message" product="default">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your phone instead.</string>
|
<string name="app_streaming_blocked_message" product="default">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your phone instead.</string>
|
||||||
<!-- Message shown when the fingerprint permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
|
<!-- Message shown when an app being streamed to another device requests authentication such as via the biometrics API, and the user needs to complete the on their device. [CHAR LIMIT=NONE] -->
|
||||||
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv">This app is requesting additional security. Try on your Android TV device instead.</string>
|
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv">This app is requesting additional security. Try on your Android TV device instead.</string>
|
||||||
<!-- Message shown when the fingerprint permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
|
<!-- Message shown when an app being streamed to another device requests authentication such as via the biometrics API, and the user needs to complete the on their device. [CHAR LIMIT=NONE] -->
|
||||||
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet">This app is requesting additional security. Try on your tablet instead.</string>
|
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet">This app is requesting additional security. Try on your tablet instead.</string>
|
||||||
<!-- Message shown when the fingerprint permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
|
<!-- Message shown when an app being streamed to another device requests authentication such as via the biometrics API, and the user needs to complete the on their device. [CHAR LIMIT=NONE] -->
|
||||||
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default">This app is requesting additional security. Try on your phone instead.</string>
|
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default">This app is requesting additional security. Try on your phone instead.</string>
|
||||||
<!-- Message shown when the settings is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
|
<!-- Message shown when the settings is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
|
||||||
<string name="app_streaming_blocked_message_for_settings_dialog" product="tv">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g>. Try on your Android TV device instead.</string>
|
<string name="app_streaming_blocked_message_for_settings_dialog" product="tv">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g>. Try on your Android TV device instead.</string>
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import android.util.SparseArray;
|
|||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.android.internal.R;
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.util.DumpUtils;
|
import com.android.internal.util.DumpUtils;
|
||||||
@@ -156,7 +157,7 @@ public class VirtualDeviceManagerService extends SystemService {
|
|||||||
VirtualDeviceImpl virtualDevice = virtualDevicesSnapshot.get(i);
|
VirtualDeviceImpl virtualDevice = virtualDevicesSnapshot.get(i);
|
||||||
virtualDevice.showToastWhereUidIsRunning(appUid,
|
virtualDevice.showToastWhereUidIsRunning(appUid,
|
||||||
getContext().getString(
|
getContext().getString(
|
||||||
com.android.internal.R.string.vdm_camera_access_denied,
|
R.string.vdm_camera_access_denied,
|
||||||
virtualDevice.getDisplayName()),
|
virtualDevice.getDisplayName()),
|
||||||
Toast.LENGTH_LONG, Looper.myLooper());
|
Toast.LENGTH_LONG, Looper.myLooper());
|
||||||
}
|
}
|
||||||
@@ -622,6 +623,18 @@ public class VirtualDeviceManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAuthenticationPrompt(int uid) {
|
||||||
|
synchronized (mVirtualDeviceManagerLock) {
|
||||||
|
for (int i = 0; i < mVirtualDevices.size(); i++) {
|
||||||
|
VirtualDeviceImpl device = mVirtualDevices.valueAt(i);
|
||||||
|
device.showToastWhereUidIsRunning(uid,
|
||||||
|
R.string.app_streaming_blocked_message_for_fingerprint_dialog,
|
||||||
|
Toast.LENGTH_LONG, Looper.getMainLooper());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBaseVirtualDisplayFlags(IVirtualDevice virtualDevice) {
|
public int getBaseVirtualDisplayFlags(IVirtualDevice virtualDevice) {
|
||||||
return ((VirtualDeviceImpl) virtualDevice).getBaseVirtualDisplayFlags();
|
return ((VirtualDeviceImpl) virtualDevice).getBaseVirtualDisplayFlags();
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import com.android.internal.R;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
|
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -262,6 +263,11 @@ public class AuthService extends SystemService {
|
|||||||
|
|
||||||
final long identity = Binder.clearCallingIdentity();
|
final long identity = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
|
VirtualDeviceManagerInternal vdm = getLocalService(
|
||||||
|
VirtualDeviceManagerInternal.class);
|
||||||
|
if (vdm != null) {
|
||||||
|
vdm.onAuthenticationPrompt(callingUid);
|
||||||
|
}
|
||||||
return mBiometricService.authenticate(
|
return mBiometricService.authenticate(
|
||||||
token, sessionId, userId, receiver, opPackageName, promptInfo);
|
token, sessionId, userId, receiver, opPackageName, promptInfo);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ import com.android.server.biometrics.sensors.LockoutTracker;
|
|||||||
import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
|
import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
|
||||||
import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21;
|
import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21;
|
||||||
import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21UdfpsMock;
|
import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21UdfpsMock;
|
||||||
|
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
|
||||||
|
|
||||||
import com.google.android.collect.Lists;
|
import com.google.android.collect.Lists;
|
||||||
|
|
||||||
@@ -329,6 +330,16 @@ public class FingerprintService extends SystemService {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
final long identity2 = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
VirtualDeviceManagerInternal vdm = getLocalService(
|
||||||
|
VirtualDeviceManagerInternal.class);
|
||||||
|
if (vdm != null) {
|
||||||
|
vdm.onAuthenticationPrompt(callingUid);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(identity2);
|
||||||
|
}
|
||||||
return provider.second.scheduleAuthenticate(token, operationId,
|
return provider.second.scheduleAuthenticate(token, operationId,
|
||||||
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options,
|
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options,
|
||||||
restricted, statsClient, isKeyguard);
|
restricted, statsClient, isKeyguard);
|
||||||
|
|||||||
@@ -69,6 +69,11 @@ public abstract class VirtualDeviceManagerInternal {
|
|||||||
*/
|
*/
|
||||||
public abstract void onAppsOnVirtualDeviceChanged();
|
public abstract void onAppsOnVirtualDeviceChanged();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies that an authentication prompt is about to be shown for an app with the given uid.
|
||||||
|
*/
|
||||||
|
public abstract void onAuthenticationPrompt(int uid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the owner uid for a deviceId.
|
* Gets the owner uid for a deviceId.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 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.companion.virtual;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
import android.testing.TestableContext;
|
||||||
|
|
||||||
|
import androidx.test.InstrumentationRegistry;
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
|
||||||
|
import com.android.internal.R;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@Presubmit
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class VirtualDeviceManagerServiceMockingTest {
|
||||||
|
private static final int UID_1 = 0;
|
||||||
|
private static final int DEVICE_ID_1 = 42;
|
||||||
|
private static final int DEVICE_ID_2 = 43;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final TestableContext mContext = new TestableContext(
|
||||||
|
InstrumentationRegistry.getContext());
|
||||||
|
|
||||||
|
private VirtualDeviceManagerService mVdms;
|
||||||
|
private VirtualDeviceManagerInternal mLocalService;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mVdms = new VirtualDeviceManagerService(mContext);
|
||||||
|
mLocalService = mVdms.getLocalServiceInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onAuthenticationPrompt_noDevices_noCrash() {
|
||||||
|
// This should not crash
|
||||||
|
mLocalService.onAuthenticationPrompt(UID_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onAuthenticationPrompt_oneDevice_showToastWhereUidIsRunningIsCalled() {
|
||||||
|
VirtualDeviceImpl device = mock(VirtualDeviceImpl.class);
|
||||||
|
mVdms.addVirtualDevice(device);
|
||||||
|
|
||||||
|
mLocalService.onAuthenticationPrompt(UID_1);
|
||||||
|
|
||||||
|
verify(device).showToastWhereUidIsRunning(eq(UID_1),
|
||||||
|
eq(R.string.app_streaming_blocked_message_for_fingerprint_dialog), anyInt(),
|
||||||
|
any(Looper.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onAuthenticationPrompt_twoDevices_showToastWhereUidIsRunningIsCalledOnBoth() {
|
||||||
|
VirtualDeviceImpl device1 = mock(VirtualDeviceImpl.class);
|
||||||
|
VirtualDeviceImpl device2 = mock(VirtualDeviceImpl.class);
|
||||||
|
when(device1.getDeviceId()).thenReturn(DEVICE_ID_1);
|
||||||
|
when(device2.getDeviceId()).thenReturn(DEVICE_ID_2);
|
||||||
|
mVdms.addVirtualDevice(device1);
|
||||||
|
mVdms.addVirtualDevice(device2);
|
||||||
|
|
||||||
|
mLocalService.onAuthenticationPrompt(UID_1);
|
||||||
|
|
||||||
|
verify(device1).showToastWhereUidIsRunning(eq(UID_1),
|
||||||
|
eq(R.string.app_streaming_blocked_message_for_fingerprint_dialog), anyInt(),
|
||||||
|
any(Looper.class));
|
||||||
|
verify(device2).showToastWhereUidIsRunning(eq(UID_1),
|
||||||
|
eq(R.string.app_streaming_blocked_message_for_fingerprint_dialog), anyInt(),
|
||||||
|
any(Looper.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,6 +58,8 @@ import androidx.test.InstrumentationRegistry;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
|
import com.android.server.LocalServices;
|
||||||
|
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
@@ -102,6 +104,8 @@ public class AuthServiceTest {
|
|||||||
IFaceService mFaceService;
|
IFaceService mFaceService;
|
||||||
@Mock
|
@Mock
|
||||||
AppOpsManager mAppOpsManager;
|
AppOpsManager mAppOpsManager;
|
||||||
|
@Mock
|
||||||
|
private VirtualDeviceManagerInternal mVdmInternal;
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<List<FingerprintSensorPropertiesInternal>> mFingerprintPropsCaptor;
|
private ArgumentCaptor<List<FingerprintSensorPropertiesInternal>> mFingerprintPropsCaptor;
|
||||||
@Captor
|
@Captor
|
||||||
@@ -115,6 +119,8 @@ public class AuthServiceTest {
|
|||||||
"1:4:15", // ID1:Iris:Strong
|
"1:4:15", // ID1:Iris:Strong
|
||||||
"2:8:15", // ID2:Face:Strong
|
"2:8:15", // ID2:Face:Strong
|
||||||
};
|
};
|
||||||
|
LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
|
||||||
|
LocalServices.addService(VirtualDeviceManagerInternal.class, mVdmInternal);
|
||||||
|
|
||||||
when(mResources.getIntArray(eq(R.array.config_udfps_sensor_props))).thenReturn(new int[0]);
|
when(mResources.getIntArray(eq(R.array.config_udfps_sensor_props))).thenReturn(new int[0]);
|
||||||
when(mResources.getBoolean(eq(R.bool.config_is_powerbutton_fps))).thenReturn(false);
|
when(mResources.getBoolean(eq(R.bool.config_is_powerbutton_fps))).thenReturn(false);
|
||||||
@@ -271,6 +277,47 @@ public class AuthServiceTest {
|
|||||||
verify(mReceiver).onError(eq(TYPE_NONE), eq(BIOMETRIC_ERROR_CANCELED), anyInt());
|
verify(mReceiver).onError(eq(TYPE_NONE), eq(BIOMETRIC_ERROR_CANCELED), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuthenticate_noVdmInternalService_noCrash() throws Exception {
|
||||||
|
LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
|
||||||
|
mAuthService = new AuthService(mContext, mInjector);
|
||||||
|
mAuthService.onStart();
|
||||||
|
|
||||||
|
final Binder token = new Binder();
|
||||||
|
|
||||||
|
// This should not crash
|
||||||
|
mAuthService.mImpl.authenticate(
|
||||||
|
token,
|
||||||
|
0, /* sessionId */
|
||||||
|
0, /* userId */
|
||||||
|
mReceiver,
|
||||||
|
TEST_OP_PACKAGE_NAME,
|
||||||
|
new PromptInfo());
|
||||||
|
waitForIdle();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuthenticate_callsVirtualDeviceManagerOnAuthenticationPrompt()
|
||||||
|
throws Exception {
|
||||||
|
mAuthService = new AuthService(mContext, mInjector);
|
||||||
|
mAuthService.onStart();
|
||||||
|
|
||||||
|
final Binder token = new Binder();
|
||||||
|
|
||||||
|
mAuthService.mImpl.authenticate(
|
||||||
|
token,
|
||||||
|
0, /* sessionId */
|
||||||
|
0, /* userId */
|
||||||
|
mReceiver,
|
||||||
|
TEST_OP_PACKAGE_NAME,
|
||||||
|
new PromptInfo());
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
ArgumentCaptor<Integer> uidCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||||
|
verify(mVdmInternal).onAuthenticationPrompt(uidCaptor.capture());
|
||||||
|
assertEquals((int) (uidCaptor.getValue()), Binder.getCallingUid());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticate_throwsWhenUsingTestConfigurations() {
|
public void testAuthenticate_throwsWhenUsingTestConfigurations() {
|
||||||
final PromptInfo promptInfo = mock(PromptInfo.class);
|
final PromptInfo promptInfo = mock(PromptInfo.class);
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFP
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
@@ -44,6 +46,7 @@ import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
|||||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||||
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
|
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
|
||||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
@@ -54,8 +57,10 @@ import androidx.test.platform.app.InstrumentationRegistry;
|
|||||||
|
|
||||||
import com.android.internal.util.test.FakeSettingsProvider;
|
import com.android.internal.util.test.FakeSettingsProvider;
|
||||||
import com.android.internal.util.test.FakeSettingsProviderRule;
|
import com.android.internal.util.test.FakeSettingsProviderRule;
|
||||||
|
import com.android.server.LocalServices;
|
||||||
import com.android.server.biometrics.log.BiometricContext;
|
import com.android.server.biometrics.log.BiometricContext;
|
||||||
import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
|
import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
|
||||||
|
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
@@ -103,6 +108,8 @@ public class FingerprintServiceTest {
|
|||||||
private IFingerprintServiceReceiver mServiceReceiver;
|
private IFingerprintServiceReceiver mServiceReceiver;
|
||||||
@Mock
|
@Mock
|
||||||
private IBinder mToken;
|
private IBinder mToken;
|
||||||
|
@Mock
|
||||||
|
private VirtualDeviceManagerInternal mVdmInternal;
|
||||||
|
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<FingerprintAuthenticateOptions> mAuthenticateOptionsCaptor;
|
private ArgumentCaptor<FingerprintAuthenticateOptions> mAuthenticateOptionsCaptor;
|
||||||
@@ -125,6 +132,9 @@ public class FingerprintServiceTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
|
LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
|
||||||
|
LocalServices.addService(VirtualDeviceManagerInternal.class, mVdmInternal);
|
||||||
|
|
||||||
when(mFingerprintDefault.getSensorProperties()).thenReturn(List.of(mSensorPropsDefault));
|
when(mFingerprintDefault.getSensorProperties()).thenReturn(List.of(mSensorPropsDefault));
|
||||||
when(mFingerprintVirtual.getSensorProperties()).thenReturn(List.of(mSensorPropsVirtual));
|
when(mFingerprintVirtual.getSensorProperties()).thenReturn(List.of(mSensorPropsVirtual));
|
||||||
when(mFingerprintDefault.containsSensor(anyInt()))
|
when(mFingerprintDefault.containsSensor(anyInt()))
|
||||||
@@ -225,6 +235,36 @@ public class FingerprintServiceTest {
|
|||||||
verifyNoAuthenticate(mFingerprintVirtual);
|
verifyNoAuthenticate(mFingerprintVirtual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuthenticate_noVdmInternalService_noCrash() throws Exception {
|
||||||
|
initServiceWithAndWait(NAME_DEFAULT, NAME_VIRTUAL);
|
||||||
|
LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
|
||||||
|
|
||||||
|
final long operationId = 2;
|
||||||
|
|
||||||
|
// This should not crash
|
||||||
|
mService.mServiceWrapper.authenticate(mToken, operationId, mServiceReceiver,
|
||||||
|
new FingerprintAuthenticateOptions.Builder()
|
||||||
|
.setSensorId(SENSOR_ID_ANY)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuthenticate_callsVirtualDeviceManagerOnAuthenticationPrompt()
|
||||||
|
throws Exception {
|
||||||
|
initServiceWithAndWait(NAME_DEFAULT, NAME_VIRTUAL);
|
||||||
|
|
||||||
|
final long operationId = 2;
|
||||||
|
mService.mServiceWrapper.authenticate(mToken, operationId, mServiceReceiver,
|
||||||
|
new FingerprintAuthenticateOptions.Builder()
|
||||||
|
.setSensorId(SENSOR_ID_ANY)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
ArgumentCaptor<Integer> uidCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||||
|
verify(mVdmInternal).onAuthenticationPrompt(uidCaptor.capture());
|
||||||
|
assertEquals((int) (uidCaptor.getValue()), Binder.getCallingUid());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private FingerprintAuthenticateOptions verifyAuthenticateWithNewRequestId(
|
private FingerprintAuthenticateOptions verifyAuthenticateWithNewRequestId(
|
||||||
FingerprintProvider provider, long operationId) {
|
FingerprintProvider provider, long operationId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user