Create the system service for AVF & hook the manager to it.
Bug: 201696614 Change-Id: I4a7a830ba809ed59a030a87c4f479199685d8a42 Test: atest AttestationVerificationTest
This commit is contained in:
@@ -200,6 +200,8 @@ import android.safetycenter.SafetyCenterFrameworkInitializer;
|
||||
import android.scheduling.SchedulingFrameworkInitializer;
|
||||
import android.security.FileIntegrityManager;
|
||||
import android.security.IFileIntegrityService;
|
||||
import android.security.attestationverification.AttestationVerificationManager;
|
||||
import android.security.attestationverification.IAttestationVerificationManagerService;
|
||||
import android.service.oemlock.IOemLockService;
|
||||
import android.service.oemlock.OemLockManager;
|
||||
import android.service.persistentdata.IPersistentDataBlockService;
|
||||
@@ -1425,6 +1427,19 @@ public final class SystemServiceRegistry {
|
||||
return new FileIntegrityManager(ctx.getOuterContext(),
|
||||
IFileIntegrityService.Stub.asInterface(b));
|
||||
}});
|
||||
|
||||
registerService(Context.ATTESTATION_VERIFICATION_SERVICE,
|
||||
AttestationVerificationManager.class,
|
||||
new CachedServiceFetcher<AttestationVerificationManager>() {
|
||||
@Override
|
||||
public AttestationVerificationManager createService(ContextImpl ctx)
|
||||
throws ServiceNotFoundException {
|
||||
IBinder b = ServiceManager.getServiceOrThrow(
|
||||
Context.ATTESTATION_VERIFICATION_SERVICE);
|
||||
return new AttestationVerificationManager(ctx.getOuterContext(),
|
||||
IAttestationVerificationManagerService.Stub.asInterface(b));
|
||||
}});
|
||||
|
||||
//CHECKSTYLE:ON IndentationCheck
|
||||
registerService(Context.APP_INTEGRITY_SERVICE, AppIntegrityManager.class,
|
||||
new CachedServiceFetcher<AppIntegrityManager>() {
|
||||
|
||||
@@ -26,12 +26,19 @@ import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemService;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelDuration;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
@@ -43,6 +50,12 @@ import java.util.function.BiConsumer;
|
||||
@SystemService(Context.ATTESTATION_VERIFICATION_SERVICE)
|
||||
public class AttestationVerificationManager {
|
||||
|
||||
private static final String TAG = "AVF";
|
||||
private static final Duration MAX_TOKEN_AGE = Duration.ofHours(1);
|
||||
|
||||
private final Context mContext;
|
||||
private final IAttestationVerificationManagerService mService;
|
||||
|
||||
/**
|
||||
* Verifies that {@code attestation} describes a computing environment that meets the
|
||||
* requirements of {@code profile}, {@code localBindingType}, and {@code requirements}.
|
||||
@@ -96,7 +109,21 @@ public class AttestationVerificationManager {
|
||||
@NonNull byte[] attestation,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull BiConsumer<@VerificationResult Integer, VerificationToken> callback) {
|
||||
executor.execute(() -> callback.accept(RESULT_UNKNOWN, null));
|
||||
try {
|
||||
AndroidFuture<IVerificationResult> resultCallback = new AndroidFuture<>();
|
||||
resultCallback.thenAccept(result -> {
|
||||
Log.d(TAG, "verifyAttestation result: " + result.resultCode + " / " + result.token);
|
||||
executor.execute(() -> {
|
||||
callback.accept(result.resultCode, result.token);
|
||||
});
|
||||
});
|
||||
|
||||
mService.verifyAttestation(profile, localBindingType, requirements, attestation,
|
||||
resultCallback);
|
||||
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,12 +161,38 @@ public class AttestationVerificationManager {
|
||||
@LocalBindingType int localBindingType,
|
||||
@NonNull Bundle requirements,
|
||||
@NonNull VerificationToken token,
|
||||
@Nullable java.time.Duration maximumAge) {
|
||||
return RESULT_UNKNOWN;
|
||||
@Nullable Duration maximumAge) {
|
||||
Duration usedMaximumAge;
|
||||
if (maximumAge == null) {
|
||||
usedMaximumAge = MAX_TOKEN_AGE;
|
||||
} else {
|
||||
if (maximumAge.compareTo(MAX_TOKEN_AGE) > 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"maximumAge cannot be greater than " + MAX_TOKEN_AGE + "; was "
|
||||
+ maximumAge);
|
||||
}
|
||||
usedMaximumAge = maximumAge;
|
||||
}
|
||||
|
||||
try {
|
||||
AndroidFuture<Integer> resultCallback = new AndroidFuture<>();
|
||||
resultCallback.orTimeout(5, TimeUnit.SECONDS);
|
||||
|
||||
mService.verifyToken(token, new ParcelDuration(usedMaximumAge), resultCallback);
|
||||
return resultCallback.get(); // block on result callback
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("Error verifying token.", t);
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public AttestationVerificationManager() {
|
||||
public AttestationVerificationManager(
|
||||
@NonNull Context context,
|
||||
@NonNull IAttestationVerificationManagerService service) {
|
||||
this.mContext = context;
|
||||
this.mService = service;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 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 android.security.attestationverification;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelDuration;
|
||||
import android.security.attestationverification.AttestationProfile;
|
||||
import android.security.attestationverification.VerificationToken;
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
|
||||
|
||||
/**
|
||||
* Binder interface to communicate with AttestationVerificationManagerService.
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IAttestationVerificationManagerService {
|
||||
|
||||
void verifyAttestation(
|
||||
in AttestationProfile profile,
|
||||
in int localBindingType,
|
||||
in Bundle requirements,
|
||||
in byte[] attestation,
|
||||
in AndroidFuture resultCallback);
|
||||
|
||||
void verifyToken(
|
||||
in VerificationToken token,
|
||||
in ParcelDuration maximumTokenAge,
|
||||
in AndroidFuture resultCallback);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 android.security.attestationverification;
|
||||
|
||||
import android.os.Bundle;
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
|
||||
|
||||
/**
|
||||
* Binder interface for the system server to communicate with app implementations of
|
||||
* AttestationVerificationService.
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IAttestationVerificationService {
|
||||
void onVerifyAttestation(
|
||||
in Bundle requirements,
|
||||
in byte[] attestation,
|
||||
in AndroidFuture callback);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 android.security.attestationverification;
|
||||
|
||||
import android.security.attestationverification.VerificationToken;
|
||||
|
||||
|
||||
/**
|
||||
* The result of an attestation verification.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
parcelable IVerificationResult {
|
||||
/** The result code corresponding to @VerificationResult. */
|
||||
int resultCode;
|
||||
/** The token for the verification or null. */
|
||||
VerificationToken token;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.security;
|
||||
|
||||
import static android.security.attestationverification.AttestationVerificationManager.RESULT_UNKNOWN;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelDuration;
|
||||
import android.os.RemoteException;
|
||||
import android.security.attestationverification.AttestationProfile;
|
||||
import android.security.attestationverification.IAttestationVerificationManagerService;
|
||||
import android.security.attestationverification.IVerificationResult;
|
||||
import android.security.attestationverification.VerificationToken;
|
||||
import android.util.ExceptionUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
import com.android.server.SystemService;
|
||||
|
||||
/**
|
||||
* A {@link SystemService} which provides functionality related to verifying attestations of
|
||||
* (usually) remote computing environments.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class AttestationVerificationManagerService extends SystemService {
|
||||
|
||||
private static final String TAG = "AVF";
|
||||
|
||||
public AttestationVerificationManagerService(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
private final IBinder mService = new IAttestationVerificationManagerService.Stub() {
|
||||
@Override
|
||||
public void verifyAttestation(
|
||||
AttestationProfile profile,
|
||||
int localBindingType,
|
||||
Bundle requirements,
|
||||
byte[] attestation,
|
||||
AndroidFuture resultCallback) throws RemoteException {
|
||||
try {
|
||||
Slog.d(TAG, "verifyAttestation");
|
||||
verifyAttestationForAllVerifiers(profile, localBindingType, requirements,
|
||||
attestation, resultCallback);
|
||||
} catch (Throwable t) {
|
||||
Slog.e(TAG, "failed to verify attestation", t);
|
||||
throw ExceptionUtils.propagate(t, RemoteException.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyToken(VerificationToken token, ParcelDuration parcelDuration,
|
||||
AndroidFuture resultCallback) throws RemoteException {
|
||||
// TODO(b/201696614): Implement
|
||||
resultCallback.complete(RESULT_UNKNOWN);
|
||||
}
|
||||
};
|
||||
|
||||
private void verifyAttestationForAllVerifiers(
|
||||
AttestationProfile profile, int localBindingType, Bundle requirements,
|
||||
byte[] attestation, AndroidFuture<IVerificationResult> resultCallback) {
|
||||
// TODO(b/201696614): Implement
|
||||
IVerificationResult result = new IVerificationResult();
|
||||
result.resultCode = RESULT_UNKNOWN;
|
||||
result.token = null;
|
||||
resultCallback.complete(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
Slog.d(TAG, "Started");
|
||||
publishBinderService(Context.ATTESTATION_VERIFICATION_SERVICE, mService);
|
||||
}
|
||||
}
|
||||
@@ -176,6 +176,7 @@ import com.android.server.recoverysystem.RecoverySystemService;
|
||||
import com.android.server.restrictions.RestrictionsManagerService;
|
||||
import com.android.server.role.RoleServicePlatformHelper;
|
||||
import com.android.server.rotationresolver.RotationResolverManagerService;
|
||||
import com.android.server.security.AttestationVerificationManagerService;
|
||||
import com.android.server.security.FileIntegrityService;
|
||||
import com.android.server.security.KeyAttestationApplicationIdProviderService;
|
||||
import com.android.server.security.KeyChainSystemService;
|
||||
@@ -2339,6 +2340,10 @@ public final class SystemServer implements Dumpable {
|
||||
t.traceEnd();
|
||||
}
|
||||
|
||||
t.traceBegin("StartAttestationVerificationService");
|
||||
mSystemServiceManager.startService(AttestationVerificationManagerService.class);
|
||||
t.traceEnd();
|
||||
|
||||
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_COMPANION_DEVICE_SETUP)) {
|
||||
t.traceBegin("StartCompanionDeviceManager");
|
||||
mSystemServiceManager.startService(COMPANION_DEVICE_MANAGER_SERVICE_CLASS);
|
||||
|
||||
44
tests/AttestationVerificationTest/Android.bp
Normal file
44
tests/AttestationVerificationTest/Android.bp
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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 {
|
||||
default_applicable_licenses: ["frameworks_base_license"],
|
||||
}
|
||||
|
||||
android_test {
|
||||
name: "AttestationVerificationTest",
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
"src/**/*.kt",
|
||||
],
|
||||
defaults: ["cts_defaults"],
|
||||
manifest: "AndroidManifest.xml",
|
||||
test_config: "AndroidTest.xml",
|
||||
platform_apis: true,
|
||||
certificate: "platform",
|
||||
optimize: {
|
||||
enabled: false,
|
||||
},
|
||||
test_suites: ["device-tests"],
|
||||
libs: [
|
||||
"android.test.runner",
|
||||
"android.test.base",
|
||||
],
|
||||
static_libs: [
|
||||
"compatibility-device-util-axt",
|
||||
"androidx.test.rules",
|
||||
"androidx.test.ext.junit",
|
||||
"platform-test-annotations",
|
||||
],
|
||||
}
|
||||
33
tests/AttestationVerificationTest/AndroidManifest.xml
Executable file
33
tests/AttestationVerificationTest/AndroidManifest.xml
Executable file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="android.security.attestationverification">
|
||||
|
||||
<uses-sdk android:minSdkVersion="30" android:targetSdkVersion="30" />
|
||||
<uses-permission android:name="android.permission.USE_ATTESTATION_VERIFICATION_SERVICE" />
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner"/>
|
||||
<activity android:name=".SystemAttestationVerificationTest$TestActivity" />
|
||||
</application>
|
||||
|
||||
<!-- self-instrumenting test package. -->
|
||||
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
|
||||
android:targetPackage="android.security.attestationverification">
|
||||
</instrumentation>
|
||||
</manifest>
|
||||
27
tests/AttestationVerificationTest/AndroidTest.xml
Normal file
27
tests/AttestationVerificationTest/AndroidTest.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<configuration description="Platform tests for Attestation Verification Framework">
|
||||
<option name="test-tag" value="AttestationVerificationTest" />
|
||||
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
|
||||
<option name="cleanup-apks" value="true" />
|
||||
<option name="test-file-name" value="AttestationVerificationTest.apk" />
|
||||
</target_preparer>
|
||||
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
|
||||
<option name="package" value="android.security.attestationverification" />
|
||||
<option name="hidden-api-checks" value="false" />
|
||||
</test>
|
||||
</configuration>
|
||||
@@ -0,0 +1,90 @@
|
||||
package android.security.attestationverification
|
||||
|
||||
import android.os.Bundle
|
||||
import android.app.Activity
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import org.junit.Assert.assertThrows
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import android.security.attestationverification.AttestationVerificationManager.PROFILE_SELF_TRUSTED
|
||||
import android.security.attestationverification.AttestationVerificationManager.TYPE_PUBLIC_KEY
|
||||
import android.security.attestationverification.AttestationVerificationManager.RESULT_UNKNOWN
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.time.Duration
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/** Test for system-defined attestation verifiers. */
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SystemAttestationVerificationTest {
|
||||
|
||||
@get:Rule
|
||||
val rule = ActivityScenarioRule(TestActivity::class.java)
|
||||
|
||||
private lateinit var activity: Activity
|
||||
private lateinit var avm: AttestationVerificationManager
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
rule.getScenario().onActivity {
|
||||
avm = it.getSystemService(AttestationVerificationManager::class.java)
|
||||
activity = it
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyAttestation_returnsUnknown() {
|
||||
val future = CompletableFuture<Int>()
|
||||
val profile = AttestationProfile(PROFILE_SELF_TRUSTED)
|
||||
avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(), ByteArray(0),
|
||||
activity.mainExecutor) { result, _ ->
|
||||
future.complete(result)
|
||||
}
|
||||
|
||||
assertThat(future.getSoon()).isEqualTo(RESULT_UNKNOWN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyToken_returnsUnknown() {
|
||||
val future = CompletableFuture<Int>()
|
||||
val profile = AttestationProfile(PROFILE_SELF_TRUSTED)
|
||||
avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(), ByteArray(0),
|
||||
activity.mainExecutor) { _, token ->
|
||||
val result = avm.verifyToken(profile, TYPE_PUBLIC_KEY, Bundle(), token, null)
|
||||
future.complete(result)
|
||||
}
|
||||
|
||||
assertThat(future.getSoon()).isEqualTo(RESULT_UNKNOWN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyToken_tooBigMaxAgeThrows() {
|
||||
val future = CompletableFuture<VerificationToken>()
|
||||
val profile = AttestationProfile(PROFILE_SELF_TRUSTED)
|
||||
avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(), ByteArray(0),
|
||||
activity.mainExecutor) { _, token ->
|
||||
future.complete(token)
|
||||
}
|
||||
|
||||
assertThrows(IllegalArgumentException::class.java) {
|
||||
avm.verifyToken(profile, TYPE_PUBLIC_KEY, Bundle(), future.getSoon(),
|
||||
Duration.ofSeconds(3601))
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> CompletableFuture<T>.getSoon(): T {
|
||||
return this.get(1, TimeUnit.SECONDS)
|
||||
}
|
||||
|
||||
class TestActivity : Activity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user