Merge "Initial commit for ImpressionAttestationService"

This commit is contained in:
Chavi Weingarten
2020-11-10 17:01:03 +00:00
committed by Android (Google) Code Review
7 changed files with 532 additions and 0 deletions

View File

@@ -10059,6 +10059,32 @@ package android.service.attention {
}
package android.service.attestation {
public abstract class ImpressionAttestationService extends android.app.Service {
ctor public ImpressionAttestationService();
method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
method @Nullable public abstract android.service.attestation.ImpressionToken onGenerateImpressionToken(@NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String);
method public abstract int onVerifyImpressionToken(@NonNull android.service.attestation.ImpressionToken);
field public static final int VERIFICATION_STATUS_APP_DECLARED = 2; // 0x2
field public static final int VERIFICATION_STATUS_OS_VERIFIED = 1; // 0x1
field public static final int VERIFICATION_STATUS_UNKNOWN = 0; // 0x0
}
public final class ImpressionToken implements android.os.Parcelable {
ctor public ImpressionToken(long, @NonNull android.graphics.Rect, @NonNull String, @NonNull byte[], @NonNull byte[]);
method public int describeContents();
method @NonNull public android.graphics.Rect getBoundsInWindow();
method @NonNull public String getHashingAlgorithm();
method @NonNull public byte[] getHmac();
method @NonNull public byte[] getImageHash();
method public long getScreenshotTimeMillis();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.attestation.ImpressionToken> CREATOR;
}
}
package android.service.autofill {
public abstract class AutofillFieldClassificationService extends android.app.Service {

View File

@@ -8900,6 +8900,32 @@ package android.service.attention {
}
package android.service.attestation {
public abstract class ImpressionAttestationService extends android.app.Service {
ctor public ImpressionAttestationService();
method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
method @Nullable public abstract android.service.attestation.ImpressionToken onGenerateImpressionToken(@NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String);
method public abstract int onVerifyImpressionToken(@NonNull android.service.attestation.ImpressionToken);
field public static final int VERIFICATION_STATUS_APP_DECLARED = 2; // 0x2
field public static final int VERIFICATION_STATUS_OS_VERIFIED = 1; // 0x1
field public static final int VERIFICATION_STATUS_UNKNOWN = 0; // 0x0
}
public final class ImpressionToken implements android.os.Parcelable {
ctor public ImpressionToken(long, @NonNull android.graphics.Rect, @NonNull String, @NonNull byte[], @NonNull byte[]);
method public int describeContents();
method @NonNull public android.graphics.Rect getBoundsInWindow();
method @NonNull public String getHashingAlgorithm();
method @NonNull public byte[] getHmac();
method @NonNull public byte[] getImageHash();
method public long getScreenshotTimeMillis();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.attestation.ImpressionToken> CREATOR;
}
}
package android.service.autofill {
public abstract class AutofillFieldClassificationService extends android.app.Service {

View File

@@ -0,0 +1,52 @@
/*
* 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.service.attestation;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.service.attestation.ImpressionToken;
import android.os.RemoteCallback;
/**
* Service used to handle impression attestation requests.
*
* @hide
*/
oneway interface IImpressionAttestationService {
/**
* Generates the impression token that can be used to validate that the system generated the
* token.
*
* @param screenshot The token for the window where the view is shown.
* @param bounds The size and position of the content being attested in the window.
* @param hashAlgorithm The String for the hashing algorithm to use based on values in
* {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS}.
* @param Callback The callback invoked to send back the impression token.
*/
void generateImpressionToken(in HardwareBuffer screenshot, in Rect bounds,
in String hashAlgorithm, in RemoteCallback callback);
/**
* Call to verify that the impressionToken passed in was generated by the system. The result
* will be sent in the callback as an integer with the key {@link #EXTRA_VERIFICATION_STATUS}
* and will be one of the values in {@link VerificationStatus}.
*
* @param impressionToken The token to verify that it was generated by the system.
* @param callback The callback invoked to send back the verification status.
*/
void verifyImpressionToken(in ImpressionToken impressionToken, in RemoteCallback callback);
}

View File

@@ -0,0 +1,152 @@
/*
* 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.service.attestation;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteCallback;
/**
* A service that handles generating and verify ImpressionTokens.
*
* The service will generate an ImpressionToken based on arguments passed in. Then later that same
* ImpressionToken can be verified to determine that it was created by the system.
*
* @hide
*/
@SystemApi
public abstract class ImpressionAttestationService extends Service {
/** @hide **/
public static final String EXTRA_IMPRESSION_TOKEN =
"android.service.attestation.extra.IMPRESSION_TOKEN";
/** @hide **/
public static final String EXTRA_VERIFICATION_STATUS =
"android.service.attestation.extra.VERIFICATION_STATUS";
/** @hide */
@IntDef(prefix = {"VERIFICATION_STATUS_"}, value = {
VERIFICATION_STATUS_UNKNOWN,
VERIFICATION_STATUS_OS_VERIFIED,
VERIFICATION_STATUS_APP_DECLARED
})
public @interface VerificationStatus {
}
public static final int VERIFICATION_STATUS_UNKNOWN = 0;
public static final int VERIFICATION_STATUS_OS_VERIFIED = 1;
public static final int VERIFICATION_STATUS_APP_DECLARED = 2;
/**
* Manifest metadata key for the resource string array containing the names of all impression
* attestation algorithms provided by the service.
* @hide
*/
public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS =
"android.attestation.available_algorithms";
private ImpressionAttestationServiceWrapper mWrapper;
private Handler mHandler;
public ImpressionAttestationService() {
}
@Override
public void onCreate() {
super.onCreate();
mWrapper = new ImpressionAttestationServiceWrapper();
mHandler = new Handler(Looper.getMainLooper(), null, true);
}
@NonNull
@Override
public final IBinder onBind(@NonNull Intent intent) {
return mWrapper;
}
/**
* Generates the impression token that can be used to validate that the system
* generated the token.
*
* @param screenshot The screenshot buffer for the content to attest.
* @param bounds The size and position of the content being attested in the window.
* @param hashAlgorithm The String for the hashing algorithm to use based values in
* {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS)}.
* @return An impression token that can be used to validate information about the content.
* Returns null when the arguments sent are invalid.
*/
@Nullable
public abstract ImpressionToken onGenerateImpressionToken(@NonNull HardwareBuffer screenshot,
@NonNull Rect bounds, @NonNull String hashAlgorithm);
/**
* Call to verify that the impressionToken passed in was generated by the system.
*
* @param impressionToken The token to verify that it was generated by the system.
* @return A {@link VerificationStatus} about whether the token was generated by the system.
*/
public abstract @VerificationStatus int onVerifyImpressionToken(
@NonNull ImpressionToken impressionToken);
private void generateImpressionToken(HardwareBuffer screenshot, Rect bounds,
String hashAlgorithm, RemoteCallback callback) {
ImpressionToken impressionToken = onGenerateImpressionToken(screenshot, bounds,
hashAlgorithm);
final Bundle data = new Bundle();
data.putParcelable(EXTRA_IMPRESSION_TOKEN, impressionToken);
callback.sendResult(data);
}
private void verifyImpressionToken(ImpressionToken impressionToken,
RemoteCallback callback) {
@VerificationStatus int verificationStatus = onVerifyImpressionToken(impressionToken);
final Bundle data = new Bundle();
data.putInt(EXTRA_VERIFICATION_STATUS, verificationStatus);
callback.sendResult(data);
}
private final class ImpressionAttestationServiceWrapper extends
IImpressionAttestationService.Stub {
@Override
public void generateImpressionToken(HardwareBuffer screenshot, Rect bounds,
String hashAlgorithm, RemoteCallback callback) {
mHandler.sendMessage(
obtainMessage(ImpressionAttestationService::generateImpressionToken,
ImpressionAttestationService.this, screenshot, bounds, hashAlgorithm,
callback));
}
@Override
public void verifyImpressionToken(ImpressionToken impressionToken,
RemoteCallback callback) {
mHandler.sendMessage(obtainMessage(ImpressionAttestationService::verifyImpressionToken,
ImpressionAttestationService.this, impressionToken, callback));
}
}
}

View File

@@ -0,0 +1,19 @@
/*
* 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.service.attestation;
parcelable ImpressionToken;

View File

@@ -0,0 +1,250 @@
/*
* 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.service.attestation;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.DataClass;
/**
* The ads impression token used to validate information about what was present on screen.
* @hide
*
* TODO: Remove hide and SystemAPI since this will be a public class
*/
@SystemApi
@DataClass(genToString = true, genAidl = true)
public final class ImpressionToken implements Parcelable {
/**
* The timestamp when the screenshot was generated.
*/
private final long mScreenshotTimeMillis;
/**
* The bounds of the requested area to take the screenshot. This is in window space passed in
* by the client.
*/
private @NonNull final Rect mBoundsInWindow;
/**
* The selected hashing algorithm that generated the image hash.
*/
private @NonNull final String mHashingAlgorithm;
/**
* The image hash generated when creating the impression token from the screenshot taken.
*/
private @NonNull final byte[] mImageHash;
/**
* The hmac generated by the system and used to verify whether this token was generated by
* the system. This should only be accessed by a system process.
*/
private @NonNull final byte[] mHmac;
/**
* The hmac generated by the system and used to verify whether this token was generated by
* the system. This should only be accessed by a system process.
*
* @hide
*/
@SystemApi
public @NonNull byte[] getHmac() {
return mHmac;
}
// Code below generated by codegen v1.0.18.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
//
// To regenerate run:
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/attestation/ImpressionToken.java
//
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
// Settings > Editor > Code Style > Formatter Control
//@formatter:off
/**
* Creates a new ImpressionToken.
*
* @param screenshotTimeMillis
* The timestamp when the screenshot was generated.
* @param boundsInWindow
* The bounds of the requested area to take the screenshot. This is in window space passed in
* by the client.
* @param hashingAlgorithm
* The selected hashing algorithm that generated the image hash.
* @param imageHash
* The image hash generated when creating the impression token from the screenshot taken.
* @param hmac
* The hmac generated by the system and used to verify whether this token was generated by
* the system. This should only be accessed by a system process.
*/
@DataClass.Generated.Member
public ImpressionToken(
long screenshotTimeMillis,
@NonNull Rect boundsInWindow,
@NonNull String hashingAlgorithm,
@NonNull byte[] imageHash,
@NonNull byte[] hmac) {
this.mScreenshotTimeMillis = screenshotTimeMillis;
this.mBoundsInWindow = boundsInWindow;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mBoundsInWindow);
this.mHashingAlgorithm = hashingAlgorithm;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mHashingAlgorithm);
this.mImageHash = imageHash;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mImageHash);
this.mHmac = hmac;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mHmac);
// onConstructed(); // You can define this method to get a callback
}
/**
* The timestamp when the screenshot was generated.
*/
@DataClass.Generated.Member
public long getScreenshotTimeMillis() {
return mScreenshotTimeMillis;
}
/**
* The bounds of the requested area to take the screenshot. This is in window space passed in
* by the client.
*/
@DataClass.Generated.Member
public @NonNull Rect getBoundsInWindow() {
return mBoundsInWindow;
}
/**
* The selected hashing algorithm that generated the image hash.
*/
@DataClass.Generated.Member
public @NonNull String getHashingAlgorithm() {
return mHashingAlgorithm;
}
/**
* The image hash generated when creating the impression token from the screenshot taken.
*/
@DataClass.Generated.Member
public @NonNull byte[] getImageHash() {
return mImageHash;
}
@Override
@DataClass.Generated.Member
public String toString() {
// You can override field toString logic by defining methods like:
// String fieldNameToString() { ... }
return "ImpressionToken { " +
"screenshotTimeMillis = " + mScreenshotTimeMillis + ", " +
"boundsInWindow = " + mBoundsInWindow + ", " +
"hashingAlgorithm = " + mHashingAlgorithm + ", " +
"imageHash = " + java.util.Arrays.toString(mImageHash) + ", " +
"hmac = " + java.util.Arrays.toString(mHmac) +
" }";
}
@Override
@DataClass.Generated.Member
public void writeToParcel(@NonNull Parcel dest, int flags) {
// You can override field parcelling by defining methods like:
// void parcelFieldName(Parcel dest, int flags) { ... }
dest.writeLong(mScreenshotTimeMillis);
dest.writeTypedObject(mBoundsInWindow, flags);
dest.writeString(mHashingAlgorithm);
dest.writeByteArray(mImageHash);
dest.writeByteArray(mHmac);
}
@Override
@DataClass.Generated.Member
public int describeContents() { return 0; }
/** @hide */
@SuppressWarnings({"unchecked", "RedundantCast"})
@DataClass.Generated.Member
/* package-private */ ImpressionToken(@NonNull Parcel in) {
// You can override field unparcelling by defining methods like:
// static FieldType unparcelFieldName(Parcel in) { ... }
long screenshotTimeMillis = in.readLong();
Rect boundsInWindow = (Rect) in.readTypedObject(Rect.CREATOR);
String hashingAlgorithm = in.readString();
byte[] imageHash = in.createByteArray();
byte[] hmac = in.createByteArray();
this.mScreenshotTimeMillis = screenshotTimeMillis;
this.mBoundsInWindow = boundsInWindow;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mBoundsInWindow);
this.mHashingAlgorithm = hashingAlgorithm;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mHashingAlgorithm);
this.mImageHash = imageHash;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mImageHash);
this.mHmac = hmac;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mHmac);
// onConstructed(); // You can define this method to get a callback
}
@DataClass.Generated.Member
public static final @NonNull Parcelable.Creator<ImpressionToken> CREATOR
= new Parcelable.Creator<ImpressionToken>() {
@Override
public ImpressionToken[] newArray(int size) {
return new ImpressionToken[size];
}
@Override
public ImpressionToken createFromParcel(@NonNull Parcel in) {
return new ImpressionToken(in);
}
};
@DataClass.Generated(
time = 1604539951959L,
codegenVersion = "1.0.18",
sourceFile = "frameworks/base/core/java/android/service/attestation/ImpressionToken.java",
inputSignatures = "private final long mScreenshotTimeMillis\nprivate final @android.annotation.NonNull android.graphics.Rect mBoundsInWindow\nprivate final @android.annotation.NonNull java.lang.String mHashingAlgorithm\nprivate final @android.annotation.NonNull byte[] mImageHash\nprivate final @android.annotation.NonNull byte[] mHmac\npublic @android.annotation.SystemApi @android.annotation.NonNull byte[] getHmac()\nclass ImpressionToken extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genAidl=true)")
@Deprecated
private void __metadata() {}
//@formatter:on
// End of generated code
}

View File

@@ -5195,6 +5195,13 @@
<permission android:name="android.permission.CONTROL_DEVICE_STATE"
android:protectionLevel="signature" />
<!-- Must be required by an {@link android.service.attestation.ImpressionAttestationService}
to ensure that only the system can bind to it.
@hide This is not a third-party API (intended for OEMs and system apps).
-->
<permission android:name="android.permission.BIND_IMPRESSION_ATTESTATION_SERVICE"
android:protectionLevel="signature" />
<!-- Attribution for Geofencing service. -->
<attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
<!-- Attribution for Country Detector. -->