Merge "Use IBinder to compare callbacks in remote provisioning service"
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.security.rkp;
|
package com.android.server.security.rkp;
|
||||||
|
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.OperationCanceledException;
|
import android.os.OperationCanceledException;
|
||||||
import android.os.OutcomeReceiver;
|
import android.os.OutcomeReceiver;
|
||||||
import android.security.rkp.IGetKeyCallback;
|
import android.security.rkp.IGetKeyCallback;
|
||||||
@@ -39,23 +40,23 @@ import java.util.concurrent.Executor;
|
|||||||
*/
|
*/
|
||||||
final class RemoteProvisioningRegistration extends IRegistration.Stub {
|
final class RemoteProvisioningRegistration extends IRegistration.Stub {
|
||||||
static final String TAG = RemoteProvisioningService.TAG;
|
static final String TAG = RemoteProvisioningService.TAG;
|
||||||
private final ConcurrentHashMap<IGetKeyCallback, CancellationSignal> mGetKeyOperations =
|
private final ConcurrentHashMap<IBinder, CancellationSignal> mGetKeyOperations =
|
||||||
new ConcurrentHashMap<>();
|
new ConcurrentHashMap<>();
|
||||||
private final Set<IStoreUpgradedKeyCallback> mStoreUpgradedKeyOperations =
|
private final Set<IBinder> mStoreUpgradedKeyOperations = ConcurrentHashMap.newKeySet();
|
||||||
ConcurrentHashMap.newKeySet();
|
|
||||||
private final RegistrationProxy mRegistration;
|
private final RegistrationProxy mRegistration;
|
||||||
private final Executor mExecutor;
|
private final Executor mExecutor;
|
||||||
|
|
||||||
private class GetKeyReceiver implements OutcomeReceiver<RemotelyProvisionedKey, Exception> {
|
private class GetKeyReceiver implements OutcomeReceiver<RemotelyProvisionedKey, Exception> {
|
||||||
IGetKeyCallback mCallback;
|
IGetKeyCallback mCallback;
|
||||||
|
|
||||||
GetKeyReceiver(IGetKeyCallback callback) {
|
GetKeyReceiver(IGetKeyCallback callback) {
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResult(RemotelyProvisionedKey result) {
|
public void onResult(RemotelyProvisionedKey result) {
|
||||||
mGetKeyOperations.remove(mCallback);
|
mGetKeyOperations.remove(mCallback.asBinder());
|
||||||
Log.i(TAG, "Successfully fetched key for client " + mCallback.hashCode());
|
Log.i(TAG, "Successfully fetched key for client " + mCallback.asBinder().hashCode());
|
||||||
android.security.rkp.RemotelyProvisionedKey parcelable =
|
android.security.rkp.RemotelyProvisionedKey parcelable =
|
||||||
new android.security.rkp.RemotelyProvisionedKey();
|
new android.security.rkp.RemotelyProvisionedKey();
|
||||||
parcelable.keyBlob = result.getKeyBlob();
|
parcelable.keyBlob = result.getKeyBlob();
|
||||||
@@ -65,19 +66,21 @@ final class RemoteProvisioningRegistration extends IRegistration.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Exception e) {
|
public void onError(Exception e) {
|
||||||
mGetKeyOperations.remove(mCallback);
|
mGetKeyOperations.remove(mCallback.asBinder());
|
||||||
if (e instanceof OperationCanceledException) {
|
if (e instanceof OperationCanceledException) {
|
||||||
Log.i(TAG, "Operation cancelled for client " + mCallback.hashCode());
|
Log.i(TAG, "Operation cancelled for client " + mCallback.asBinder().hashCode());
|
||||||
wrapCallback(mCallback::onCancel);
|
wrapCallback(mCallback::onCancel);
|
||||||
} else if (e instanceof RkpProxyException) {
|
} else if (e instanceof RkpProxyException) {
|
||||||
Log.e(TAG, "RKP error fetching key for client " + mCallback.hashCode() + ": "
|
Log.e(TAG, "RKP error fetching key for client " + mCallback.asBinder().hashCode()
|
||||||
|
+ ": "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
RkpProxyException rkpException = (RkpProxyException) e;
|
RkpProxyException rkpException = (RkpProxyException) e;
|
||||||
wrapCallback(() -> mCallback.onError(toGetKeyError(rkpException),
|
wrapCallback(() -> mCallback.onError(toGetKeyError(rkpException),
|
||||||
e.getMessage()));
|
e.getMessage()));
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Unknown error fetching key for client " + mCallback.hashCode() + ": "
|
Log.e(TAG,
|
||||||
+ e.getMessage());
|
"Unknown error fetching key for client " + mCallback.asBinder().hashCode()
|
||||||
|
+ ": " + e.getMessage());
|
||||||
wrapCallback(() -> mCallback.onError(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN,
|
wrapCallback(() -> mCallback.onError(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN,
|
||||||
e.getMessage()));
|
e.getMessage()));
|
||||||
}
|
}
|
||||||
@@ -108,20 +111,23 @@ final class RemoteProvisioningRegistration extends IRegistration.Stub {
|
|||||||
@Override
|
@Override
|
||||||
public void getKey(int keyId, IGetKeyCallback callback) {
|
public void getKey(int keyId, IGetKeyCallback callback) {
|
||||||
CancellationSignal cancellationSignal = new CancellationSignal();
|
CancellationSignal cancellationSignal = new CancellationSignal();
|
||||||
if (mGetKeyOperations.putIfAbsent(callback, cancellationSignal) != null) {
|
if (mGetKeyOperations.putIfAbsent(callback.asBinder(), cancellationSignal) != null) {
|
||||||
Log.e(TAG, "Client can only request one call at a time " + callback.hashCode());
|
Log.e(TAG,
|
||||||
|
"Client can only request one call at a time " + callback.asBinder().hashCode());
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Callback is already associated with an existing operation: "
|
"Callback is already associated with an existing operation: "
|
||||||
+ callback.hashCode());
|
+ callback.asBinder().hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Log.i(TAG, "Fetching key " + keyId + " for client " + callback.hashCode());
|
Log.i(TAG, "Fetching key " + keyId + " for client " + callback.asBinder().hashCode());
|
||||||
mRegistration.getKeyAsync(keyId, cancellationSignal, mExecutor,
|
mRegistration.getKeyAsync(keyId, cancellationSignal, mExecutor,
|
||||||
new GetKeyReceiver(callback));
|
new GetKeyReceiver(callback));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "getKeyAsync threw an exception for client " + callback.hashCode(), e);
|
Log.e(TAG,
|
||||||
mGetKeyOperations.remove(callback);
|
"getKeyAsync threw an exception for client " + callback.asBinder().hashCode(),
|
||||||
|
e);
|
||||||
|
mGetKeyOperations.remove(callback.asBinder());
|
||||||
wrapCallback(() -> callback.onError(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN,
|
wrapCallback(() -> callback.onError(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN,
|
||||||
e.getMessage()));
|
e.getMessage()));
|
||||||
}
|
}
|
||||||
@@ -129,23 +135,23 @@ final class RemoteProvisioningRegistration extends IRegistration.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancelGetKey(IGetKeyCallback callback) {
|
public void cancelGetKey(IGetKeyCallback callback) {
|
||||||
CancellationSignal cancellationSignal = mGetKeyOperations.remove(callback);
|
CancellationSignal cancellationSignal = mGetKeyOperations.remove(callback.asBinder());
|
||||||
if (cancellationSignal == null) {
|
if (cancellationSignal == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Invalid client in cancelGetKey: " + callback.hashCode());
|
"Invalid client in cancelGetKey: " + callback.asBinder().hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.i(TAG, "Requesting cancellation for client " + callback.hashCode());
|
Log.i(TAG, "Requesting cancellation for client " + callback.asBinder().hashCode());
|
||||||
cancellationSignal.cancel();
|
cancellationSignal.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void storeUpgradedKeyAsync(byte[] oldKeyBlob, byte[] newKeyBlob,
|
public void storeUpgradedKeyAsync(byte[] oldKeyBlob, byte[] newKeyBlob,
|
||||||
IStoreUpgradedKeyCallback callback) {
|
IStoreUpgradedKeyCallback callback) {
|
||||||
if (!mStoreUpgradedKeyOperations.add(callback)) {
|
if (!mStoreUpgradedKeyOperations.add(callback.asBinder())) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Callback is already associated with an existing operation: "
|
"Callback is already associated with an existing operation: "
|
||||||
+ callback.hashCode());
|
+ callback.asBinder().hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -153,20 +159,20 @@ final class RemoteProvisioningRegistration extends IRegistration.Stub {
|
|||||||
new OutcomeReceiver<>() {
|
new OutcomeReceiver<>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(Void result) {
|
public void onResult(Void result) {
|
||||||
mStoreUpgradedKeyOperations.remove(callback);
|
mStoreUpgradedKeyOperations.remove(callback.asBinder());
|
||||||
wrapCallback(callback::onSuccess);
|
wrapCallback(callback::onSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Exception e) {
|
public void onError(Exception e) {
|
||||||
mStoreUpgradedKeyOperations.remove(callback);
|
mStoreUpgradedKeyOperations.remove(callback.asBinder());
|
||||||
wrapCallback(() -> callback.onError(e.getMessage()));
|
wrapCallback(() -> callback.onError(e.getMessage()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "storeUpgradedKeyAsync threw an exception for client "
|
Log.e(TAG, "storeUpgradedKeyAsync threw an exception for client "
|
||||||
+ callback.hashCode(), e);
|
+ callback.asBinder().hashCode(), e);
|
||||||
mStoreUpgradedKeyOperations.remove(callback);
|
mStoreUpgradedKeyOperations.remove(callback.asBinder());
|
||||||
wrapCallback(() -> callback.onError(e.getMessage()));
|
wrapCallback(() -> callback.onError(e.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class RemoteProvisioningService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
mCallback.onSuccess(new RemoteProvisioningRegistration(registration, mExecutor));
|
mCallback.onSuccess(new RemoteProvisioningRegistration(registration, mExecutor));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Error calling success callback " + mCallback.hashCode(), e);
|
Log.e(TAG, "Error calling success callback " + mCallback.asBinder().hashCode(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ public class RemoteProvisioningService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
mCallback.onError(error.toString());
|
mCallback.onError(error.toString());
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Error calling error callback " + mCallback.hashCode(), e);
|
Log.e(TAG, "Error calling error callback " + mCallback.asBinder().hashCode(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ import static org.mockito.AdditionalAnswers.answerVoid;
|
|||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.argThat;
|
import static org.mockito.Mockito.argThat;
|
||||||
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.contains;
|
import static org.mockito.Mockito.contains;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.eq;
|
import static org.mockito.Mockito.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -32,6 +34,7 @@ import static org.mockito.Mockito.times;
|
|||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.OperationCanceledException;
|
import android.os.OperationCanceledException;
|
||||||
import android.os.OutcomeReceiver;
|
import android.os.OutcomeReceiver;
|
||||||
@@ -101,8 +104,10 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
.when(mRegistrationProxy).getKeyAsync(eq(42), any(), any(), any());
|
.when(mRegistrationProxy).getKeyAsync(eq(42), any(), any(), any());
|
||||||
|
|
||||||
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
mRegistration.getKey(42, callback);
|
mRegistration.getKey(42, callback);
|
||||||
verify(callback).onSuccess(matches(expectedKey));
|
verify(callback).onSuccess(matches(expectedKey));
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,8 +119,10 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
executor.execute(() -> receiver.onError(expectedException))))
|
executor.execute(() -> receiver.onError(expectedException))))
|
||||||
.when(mRegistrationProxy).getKeyAsync(eq(0), any(), any(), any());
|
.when(mRegistrationProxy).getKeyAsync(eq(0), any(), any(), any());
|
||||||
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
mRegistration.getKey(0, callback);
|
mRegistration.getKey(0, callback);
|
||||||
verify(callback).onError(eq(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN), eq("oops!"));
|
verify(callback).onError(eq(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN), eq("oops!"));
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,18 +147,28 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
executor.execute(() -> receiver.onError(expectedException))))
|
executor.execute(() -> receiver.onError(expectedException))))
|
||||||
.when(mRegistrationProxy).getKeyAsync(eq(0), any(), any(), any());
|
.when(mRegistrationProxy).getKeyAsync(eq(0), any(), any(), any());
|
||||||
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
mRegistration.getKey(0, callback);
|
mRegistration.getKey(0, callback);
|
||||||
verify(callback).onError(eq(error), contains(errorField.getName()));
|
verify(callback).onError(eq(error), contains(errorField.getName()));
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getKeyCancelDuringProxyOperation() throws Exception {
|
public void getKeyCancelDuringProxyOperation() throws Exception {
|
||||||
|
final Binder theBinder = new Binder();
|
||||||
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
||||||
|
doReturn(theBinder).when(callback).asBinder();
|
||||||
doAnswer(
|
doAnswer(
|
||||||
answerGetKeyAsync((keyId, cancelSignal, executor, receiver) -> {
|
answerGetKeyAsync((keyId, cancelSignal, executor, receiver) -> {
|
||||||
mRegistration.cancelGetKey(callback);
|
// Use a different callback object to ensure that the callback equivalence
|
||||||
|
// relies on the actual IBinder object.
|
||||||
|
IGetKeyCallback differentCallback = mock(IGetKeyCallback.class);
|
||||||
|
doReturn(theBinder).when(differentCallback).asBinder();
|
||||||
|
mRegistration.cancelGetKey(differentCallback);
|
||||||
|
verify(differentCallback, atLeastOnce()).asBinder();
|
||||||
|
verifyNoMoreInteractions(differentCallback);
|
||||||
assertThat(cancelSignal.isCanceled()).isTrue();
|
assertThat(cancelSignal.isCanceled()).isTrue();
|
||||||
executor.execute(() -> receiver.onError(new OperationCanceledException()));
|
executor.execute(() -> receiver.onError(new OperationCanceledException()));
|
||||||
}))
|
}))
|
||||||
@@ -159,18 +176,21 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
|
|
||||||
mRegistration.getKey(Integer.MAX_VALUE, callback);
|
mRegistration.getKey(Integer.MAX_VALUE, callback);
|
||||||
verify(callback).onCancel();
|
verify(callback).onCancel();
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void cancelGetKeyWithInvalidCallback() throws Exception {
|
public void cancelGetKeyWithInvalidCallback() throws Exception {
|
||||||
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
assertThrows(IllegalArgumentException.class, () -> mRegistration.cancelGetKey(callback));
|
assertThrows(IllegalArgumentException.class, () -> mRegistration.cancelGetKey(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getKeyRejectsDuplicateCallback() throws Exception {
|
public void getKeyRejectsDuplicateCallback() throws Exception {
|
||||||
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
doAnswer(
|
doAnswer(
|
||||||
answerGetKeyAsync((keyId, cancelSignal, executor, receiver) -> {
|
answerGetKeyAsync((keyId, cancelSignal, executor, receiver) -> {
|
||||||
assertThrows(IllegalArgumentException.class, () ->
|
assertThrows(IllegalArgumentException.class, () ->
|
||||||
@@ -181,12 +201,14 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
|
|
||||||
mRegistration.getKey(0, callback);
|
mRegistration.getKey(0, callback);
|
||||||
verify(callback, times(1)).onSuccess(any());
|
verify(callback, times(1)).onSuccess(any());
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getKeyCancelAfterCompleteFails() throws Exception {
|
public void getKeyCancelAfterCompleteFails() throws Exception {
|
||||||
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
doAnswer(
|
doAnswer(
|
||||||
answerGetKeyAsync((keyId, cancelSignal, executor, receiver) ->
|
answerGetKeyAsync((keyId, cancelSignal, executor, receiver) ->
|
||||||
executor.execute(() ->
|
executor.execute(() ->
|
||||||
@@ -197,6 +219,7 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
mRegistration.getKey(Integer.MIN_VALUE, callback);
|
mRegistration.getKey(Integer.MIN_VALUE, callback);
|
||||||
verify(callback).onSuccess(any());
|
verify(callback).onSuccess(any());
|
||||||
assertThrows(IllegalArgumentException.class, () -> mRegistration.cancelGetKey(callback));
|
assertThrows(IllegalArgumentException.class, () -> mRegistration.cancelGetKey(callback));
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,10 +231,12 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
.getKeyAsync(anyInt(), any(), any(), any());
|
.getKeyAsync(anyInt(), any(), any(), any());
|
||||||
|
|
||||||
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
IGetKeyCallback callback = mock(IGetKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
mRegistration.getKey(0, callback);
|
mRegistration.getKey(0, callback);
|
||||||
verify(callback).onError(eq(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN),
|
verify(callback).onError(eq(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN),
|
||||||
eq(expectedException.getMessage()));
|
eq(expectedException.getMessage()));
|
||||||
assertThrows(IllegalArgumentException.class, () -> mRegistration.cancelGetKey(callback));
|
assertThrows(IllegalArgumentException.class, () -> mRegistration.cancelGetKey(callback));
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,8 +249,10 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
.storeUpgradedKeyAsync(any(), any(), any(), any());
|
.storeUpgradedKeyAsync(any(), any(), any(), any());
|
||||||
|
|
||||||
IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
|
IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
|
mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
|
||||||
verify(callback).onSuccess();
|
verify(callback).onSuccess();
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,8 +266,10 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
.storeUpgradedKeyAsync(any(), any(), any(), any());
|
.storeUpgradedKeyAsync(any(), any(), any(), any());
|
||||||
|
|
||||||
IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
|
IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
|
mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
|
||||||
verify(callback).onError(errorString);
|
verify(callback).onError(errorString);
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,14 +281,17 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
.storeUpgradedKeyAsync(any(), any(), any(), any());
|
.storeUpgradedKeyAsync(any(), any(), any(), any());
|
||||||
|
|
||||||
IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
|
IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
|
mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
|
||||||
verify(callback).onError(errorString);
|
verify(callback).onError(errorString);
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void storeUpgradedKeyDuplicateCallback() throws Exception {
|
public void storeUpgradedKeyDuplicateCallback() throws Exception {
|
||||||
IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
|
IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
|
||||||
|
doReturn(new Binder()).when(callback).asBinder();
|
||||||
|
|
||||||
doAnswer(
|
doAnswer(
|
||||||
answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) -> {
|
answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) -> {
|
||||||
@@ -273,6 +305,7 @@ public class RemoteProvisioningRegistrationTest {
|
|||||||
|
|
||||||
mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
|
mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
|
||||||
verify(callback).onSuccess();
|
verify(callback).onSuccess();
|
||||||
|
verify(callback, atLeastOnce()).asBinder();
|
||||||
verifyNoMoreInteractions(callback);
|
verifyNoMoreInteractions(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user