Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ebe6a96 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Automerger Merge Worker
Browse files

Merge "Added public APIs to generate and validate a DisplayHash." into sc-dev am: c14465c2

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13429136

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Iecbd79812c4d905035dc68bde44a4416a02a9022
parents 5ac08d9c c14465c2
Loading
Loading
Loading
Loading
+37 −0
Original line number Original line Diff line number Diff line
@@ -10444,6 +10444,7 @@ package android.content {
    field public static final int CONTEXT_RESTRICTED = 4; // 0x4
    field public static final int CONTEXT_RESTRICTED = 4; // 0x4
    field public static final String CROSS_PROFILE_APPS_SERVICE = "crossprofileapps";
    field public static final String CROSS_PROFILE_APPS_SERVICE = "crossprofileapps";
    field public static final String DEVICE_POLICY_SERVICE = "device_policy";
    field public static final String DEVICE_POLICY_SERVICE = "device_policy";
    field public static final String DISPLAY_HASH_SERVICE = "display_hash";
    field public static final String DISPLAY_SERVICE = "display";
    field public static final String DISPLAY_SERVICE = "display";
    field public static final String DOWNLOAD_SERVICE = "download";
    field public static final String DOWNLOAD_SERVICE = "download";
    field public static final String DROPBOX_SERVICE = "dropbox";
    field public static final String DROPBOX_SERVICE = "dropbox";
@@ -48244,6 +48245,7 @@ package android.view {
    method public android.view.View focusSearch(int);
    method public android.view.View focusSearch(int);
    method public void forceHasOverlappingRendering(boolean);
    method public void forceHasOverlappingRendering(boolean);
    method public void forceLayout();
    method public void forceLayout();
    method @Nullable public void generateDisplayHash(@NonNull String, @Nullable android.graphics.Rect, @NonNull java.util.concurrent.Executor, @NonNull android.view.displayhash.DisplayHashResultCallback);
    method public static int generateViewId();
    method public static int generateViewId();
    method public CharSequence getAccessibilityClassName();
    method public CharSequence getAccessibilityClassName();
    method public android.view.View.AccessibilityDelegate getAccessibilityDelegate();
    method public android.view.View.AccessibilityDelegate getAccessibilityDelegate();
@@ -51199,6 +51201,41 @@ package android.view.contentcapture {
}
}
package android.view.displayhash {
  public final class DisplayHash implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.view.displayhash.DisplayHash> CREATOR;
  }
  public final class DisplayHashManager {
    method @NonNull public java.util.Set<java.lang.String> getSupportedHashAlgorithms();
    method @Nullable public android.view.displayhash.VerifiedDisplayHash verifyDisplayHash(@NonNull android.view.displayhash.DisplayHash);
  }
  public interface DisplayHashResultCallback {
    method public void onDisplayHashError(int);
    method public void onDisplayHashResult(@NonNull android.view.displayhash.DisplayHash);
    field public static final int DISPLAY_HASH_ERROR_INVALID_BOUNDS = -2; // 0xfffffffe
    field public static final int DISPLAY_HASH_ERROR_MISSING_WINDOW = -3; // 0xfffffffd
    field public static final int DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN = -4; // 0xfffffffc
    field public static final int DISPLAY_HASH_ERROR_UNKNOWN = -1; // 0xffffffff
  }
  public final class VerifiedDisplayHash implements android.os.Parcelable {
    ctor public VerifiedDisplayHash(long, @NonNull android.graphics.Rect, @NonNull String, @NonNull byte[]);
    method public int describeContents();
    method @NonNull public android.graphics.Rect getBoundsInWindow();
    method @NonNull public String getHashAlgorithm();
    method @NonNull public byte[] getImageHash();
    method public long getTimeMillis();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.view.displayhash.VerifiedDisplayHash> CREATOR;
  }
}
package android.view.inputmethod {
package android.view.inputmethod {
  public class BaseInputConnection implements android.view.inputmethod.InputConnection {
  public class BaseInputConnection implements android.view.inputmethod.InputConnection {
+27 −24
Original line number Original line Diff line number Diff line
@@ -9985,6 +9985,18 @@ package android.service.dataloader {
}
}
package android.service.displayhash {
  public abstract class DisplayHasherService extends android.app.Service {
    ctor public DisplayHasherService();
    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
    method @Nullable public abstract void onGenerateDisplayHash(@NonNull byte[], @NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String, @NonNull android.view.displayhash.DisplayHashResultCallback);
    method @Nullable public abstract android.view.displayhash.VerifiedDisplayHash onVerifyDisplayHash(@NonNull byte[], @NonNull android.view.displayhash.DisplayHash);
    field public static final String SERVICE_INTERFACE = "android.service.displayhash.DisplayHasherService";
  }
}
package android.service.euicc {
package android.service.euicc {
  public final class DownloadSubscriptionResult implements android.os.Parcelable {
  public final class DownloadSubscriptionResult implements android.os.Parcelable {
@@ -10345,30 +10357,6 @@ package android.service.rotationresolver {
}
}
package android.service.screenshot {
  public final class ScreenshotHash implements android.os.Parcelable {
    ctor public ScreenshotHash(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.screenshot.ScreenshotHash> CREATOR;
  }
  public abstract class ScreenshotHasherService extends android.app.Service {
    ctor public ScreenshotHasherService();
    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
    method @Nullable public abstract android.service.screenshot.ScreenshotHash onGenerateScreenshotHash(@NonNull byte[], @NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String);
    method public abstract boolean onVerifyScreenshotHash(@NonNull byte[], @NonNull android.service.screenshot.ScreenshotHash);
    field public static final String SERVICE_INTERFACE = "android.service.screenshot.ScreenshotHasherService";
  }
}
package android.service.search {
package android.service.search {
  public abstract class SearchUiService extends android.app.Service {
  public abstract class SearchUiService extends android.app.Service {
@@ -14400,6 +14388,21 @@ package android.view.contentcapture {
}
}
package android.view.displayhash {
  public final class DisplayHash implements android.os.Parcelable {
    ctor public DisplayHash(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 getHashAlgorithm();
    method @NonNull public byte[] getHmac();
    method @NonNull public byte[] getImageHash();
    method public long getTimeMillis();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
  }
}
package android.view.translation {
package android.view.translation {
  public final class UiTranslationManager {
  public final class UiTranslationManager {
+8 −0
Original line number Original line Diff line number Diff line
@@ -211,6 +211,7 @@ import android.view.autofill.AutofillManager;
import android.view.autofill.IAutoFillManager;
import android.view.autofill.IAutoFillManager;
import android.view.contentcapture.ContentCaptureManager;
import android.view.contentcapture.ContentCaptureManager;
import android.view.contentcapture.IContentCaptureManager;
import android.view.contentcapture.IContentCaptureManager;
import android.view.displayhash.DisplayHashManager;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodManager;
import android.view.textclassifier.TextClassificationManager;
import android.view.textclassifier.TextClassificationManager;
import android.view.textservice.TextServicesManager;
import android.view.textservice.TextServicesManager;
@@ -1426,6 +1427,13 @@ public final class SystemServiceRegistry {
                    }
                    }
                });
                });


        registerService(Context.DISPLAY_HASH_SERVICE, DisplayHashManager.class,
                new CachedServiceFetcher<DisplayHashManager>() {
                    @Override
                    public DisplayHashManager createService(ContextImpl ctx) {
                        return new DisplayHashManager();
                    }});

        sInitializing = true;
        sInitializing = true;
        try {
        try {
            // Note: the following functions need to be @SystemApis, once they become mainline
            // Note: the following functions need to be @SystemApis, once they become mainline
+8 −0
Original line number Original line Diff line number Diff line
@@ -5490,6 +5490,14 @@ public abstract class Context {
    @SystemApi
    @SystemApi
    public static final String DOMAIN_VERIFICATION_SERVICE = "domain_verification";
    public static final String DOMAIN_VERIFICATION_SERVICE = "domain_verification";


    /**
     * Use with {@link #getSystemService(String)} to access
     * {@link android.view.displayhash.DisplayHashManager} to handle display hashes.
     *
     * @see #getSystemService(String)
     */
    public static final String DISPLAY_HASH_SERVICE = "display_hash";

    /**
    /**
     * Determine whether the given permission is allowed for a particular
     * Determine whether the given permission is allowed for a particular
     * process and user ID running in the system.
     * process and user ID running in the system.
+168 −0
Original line number Original line Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


package android.service.screenshot;
package android.service.displayhash;


import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;


@@ -30,24 +30,24 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder;
import android.os.Looper;
import android.os.Looper;
import android.os.RemoteCallback;
import android.os.RemoteCallback;
import android.view.displayhash.DisplayHash;
import android.view.displayhash.DisplayHashResultCallback;
import android.view.displayhash.VerifiedDisplayHash;


/**
/**
 * A service that handles generating and verify {@link ScreenshotHash}.
 * A service that handles generating and verify {@link DisplayHash}.
 *
 *
 * The service will generate a ScreenshotHash based on arguments passed in. Then later that
 * The service will generate a DisplayHash based on arguments passed in. Then later that
 * same ScreenshotHash can be verified to determine that it was created by the system.
 * same DisplayHash can be verified to determine that it was created by the system.
 *
 *
 * @hide
 * @hide
 */
 */
@SystemApi
@SystemApi
public abstract class ScreenshotHasherService extends Service {
public abstract class DisplayHasherService extends Service {
    /** @hide **/
    public static final String EXTRA_SCREENSHOT_HASH =
            "android.service.screenshot.extra.SCREENSHOT_HASH";


    /** @hide **/
    /** @hide **/
    public static final String EXTRA_VERIFICATION_STATUS =
    public static final String EXTRA_VERIFIED_DISPLAY_HASH =
            "android.service.screenshot.extra.VERIFICATION_STATUS";
            "android.service.displayhash.extra.VERIFIED_DISPLAY_HASH";


    /**
    /**
     * Manifest metadata key for the resource string array containing the names of all hashing
     * Manifest metadata key for the resource string array containing the names of all hashing
@@ -56,28 +56,28 @@ public abstract class ScreenshotHasherService extends Service {
     * @hide
     * @hide
     */
     */
    public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS =
    public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS =
            "android.screenshot.available_algorithms";
            "android.displayhash.available_algorithms";


    /**
    /**
     * The {@link Intent} action that must be declared as handled by a service in its manifest
     * The {@link Intent} action that must be declared as handled by a service in its manifest
     * for the system to recognize it as a ScreenshotHash providing service.
     * for the system to recognize it as a DisplayHash providing service.
     *
     *
     * @hide
     * @hide
     */
     */
    @SystemApi
    @SystemApi
    public static final String SERVICE_INTERFACE =
    public static final String SERVICE_INTERFACE =
            "android.service.screenshot.ScreenshotHasherService";
            "android.service.displayhash.DisplayHasherService";


    private ScreenshotHasherServiceWrapper mWrapper;
    private DisplayHasherServiceWrapper mWrapper;
    private Handler mHandler;
    private Handler mHandler;


    public ScreenshotHasherService() {
    public DisplayHasherService() {
    }
    }


    @Override
    @Override
    public void onCreate() {
    public void onCreate() {
        super.onCreate();
        super.onCreate();
        mWrapper = new ScreenshotHasherServiceWrapper();
        mWrapper = new DisplayHasherServiceWrapper();
        mHandler = new Handler(Looper.getMainLooper(), null, true);
        mHandler = new Handler(Looper.getMainLooper(), null, true);
    }
    }


@@ -88,73 +88,81 @@ public abstract class ScreenshotHasherService extends Service {
    }
    }


    /**
    /**
     * Generates the ScreenshotHash that can be used to validate that the system generated the
     * Generates the DisplayHash that can be used to validate that the system generated the
     * token.
     * token.
     *
     *
     * @param salt          The salt to use when generating the hmac. This should be unique to the
     * @param salt          The salt to use when generating the hmac. This should be unique to the
     *                      caller so the token cannot be verified by any other process.
     *                      caller so the token cannot be verified by any other process.
     * @param screenshot    The screenshot buffer for the content.
     * @param buffer        The buffer for the content to generate the hash for.
     * @param bounds        The size and position of the content being screenshot in the window.
     * @param bounds        The size and position of the content in window space.
     * @param hashAlgorithm The String for the hashing algorithm to use based values in
     * @param hashAlgorithm The String for the hashing algorithm to use based values in
     *                      {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS)}.
     *                      {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS)}.
     * @return A ScreenshotHash that can be used to validate information about the content.
     * @param callback      The callback to invoke
     * Returns null when the arguments sent are invalid.
     *                      {@link DisplayHashResultCallback#onDisplayHashResult(DisplayHash)}
     *                      if successfully generated a DisplayHash or {@link
     *                      DisplayHashResultCallback#onDisplayHashError(int)} if failed.
     */
     */
    @Nullable
    @Nullable
    public abstract ScreenshotHash onGenerateScreenshotHash(@NonNull byte[] salt,
    public abstract void onGenerateDisplayHash(@NonNull byte[] salt,
            @NonNull HardwareBuffer screenshot, @NonNull Rect bounds,
            @NonNull HardwareBuffer buffer, @NonNull Rect bounds,
            @NonNull String hashAlgorithm);
            @NonNull String hashAlgorithm, @NonNull DisplayHashResultCallback callback);


    /**
    /**
     * Call to verify that the ScreenshotHash passed in was generated by the system.
     * Call to verify that the DisplayHash passed in was generated by the system.
     *
     *
     * @param salt        The salt value to use when verifying the hmac. This should be the
     * @param salt        The salt value to use when verifying the hmac. This should be the
     *                    same value that was passed to
     *                    same value that was passed to
     *                           {@link #onGenerateScreenshotHash(byte[],
     *                    {@link #onGenerateDisplayHash(byte[],
     *                           HardwareBuffer, Rect, String)} to
     *                    HardwareBuffer, Rect, String, DisplayHashResultCallback)} to
     *                    generate the token.
     *                    generate the token.
     * @param screenshotHash The token to verify that it was generated by the system.
     * @param displayHash The token to verify that it was generated by the system.
     * @return true if the token can be verified that it was generated by the system.
     * @return a {@link VerifiedDisplayHash} if the token was generated by the system or null
     * if the token cannot be verified.
     */
     */
    public abstract boolean onVerifyScreenshotHash(@NonNull byte[] salt,
    @Nullable
            @NonNull ScreenshotHash screenshotHash);
    public abstract VerifiedDisplayHash onVerifyDisplayHash(@NonNull byte[] salt,

            @NonNull DisplayHash displayHash);
    private void generateScreenshotHash(byte[] salt, HardwareBuffer screenshot, Rect bounds,
            String hashAlgorithm, RemoteCallback callback) {
        ScreenshotHash screenshotHash = onGenerateScreenshotHash(salt, screenshot,
                bounds,
                hashAlgorithm);
        final Bundle data = new Bundle();
        data.putParcelable(EXTRA_SCREENSHOT_HASH, screenshotHash);
        callback.sendResult(data);
    }


    private void verifyScreenshotHash(byte[] salt, ScreenshotHash screenshotHash,
    private void verifyDisplayHash(byte[] salt, DisplayHash displayHash,
            RemoteCallback callback) {
            RemoteCallback callback) {
        boolean verificationStatus = onVerifyScreenshotHash(salt, screenshotHash);
        VerifiedDisplayHash verifiedDisplayHash = onVerifyDisplayHash(salt,
                displayHash);
        final Bundle data = new Bundle();
        final Bundle data = new Bundle();
        data.putBoolean(EXTRA_VERIFICATION_STATUS, verificationStatus);
        data.putParcelable(EXTRA_VERIFIED_DISPLAY_HASH, verifiedDisplayHash);
        callback.sendResult(data);
        callback.sendResult(data);
    }
    }


    private final class ScreenshotHasherServiceWrapper extends
    private final class DisplayHasherServiceWrapper extends IDisplayHasherService.Stub {
            IScreenshotHasherService.Stub {
        @Override
        @Override
        public void generateScreenshotHash(byte[] salt, HardwareBuffer screenshot, Rect bounds,
        public void generateDisplayHash(byte[] salt, HardwareBuffer buffer, Rect bounds,
                String hashAlgorithm, RemoteCallback callback) {
                String hashAlgorithm, RemoteCallback callback) {
            mHandler.sendMessage(
            mHandler.sendMessage(
                    obtainMessage(ScreenshotHasherService::generateScreenshotHash,
                    obtainMessage(DisplayHasherService::onGenerateDisplayHash,
                            ScreenshotHasherService.this, salt, screenshot, bounds,
                            DisplayHasherService.this, salt, buffer, bounds,
                            hashAlgorithm, callback));
                            hashAlgorithm, new DisplayHashResultCallback() {
                                @Override
                                public void onDisplayHashResult(
                                        @NonNull DisplayHash displayHash) {
                                    Bundle result = new Bundle();
                                    result.putParcelable(EXTRA_DISPLAY_HASH, displayHash);
                                    callback.sendResult(result);
                                }

                                @Override
                                public void onDisplayHashError(int errorCode) {
                                    Bundle result = new Bundle();
                                    result.putInt(EXTRA_DISPLAY_HASH_ERROR_CODE, errorCode);
                                    callback.sendResult(result);
                                }
                            }));
        }
        }


        @Override
        @Override
        public void verifyScreenshotHash(byte[] salt, ScreenshotHash screenshotHash,
        public void verifyDisplayHash(byte[] salt, DisplayHash displayHash,
                RemoteCallback callback) {
                RemoteCallback callback) {
            mHandler.sendMessage(
            mHandler.sendMessage(
                    obtainMessage(ScreenshotHasherService::verifyScreenshotHash,
                    obtainMessage(DisplayHasherService::verifyDisplayHash,
                            ScreenshotHasherService.this, salt, screenshotHash,
                            DisplayHasherService.this, salt, displayHash, callback));
                            callback));
        }
        }
    }
    }
}
}
Loading