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

Commit 3d87156b authored by chaviw's avatar chaviw
Browse files

Add DisplayHashParams to specify how to generate display hash

When generating a DisplayHash, each algorithm can have different
requirements about how to capture the content. Instead of
trying to adjust the buffer after the content is rendered, we can
let SurfaceFlinger use the specified arguments to render the content.

This can be done by getting the display hash params from ExtServices so
they can be specified per algorithm. Then, system server will render the
content using the specified values, ensuring a more efficient
way to scale and grayscale the final buffer.

Test: DisplayHash is grayscale and scaled.
Bug: 155825630
Change-Id: I657e2f94219baaac9318500134a6cd82cd07af56
parent 6919687f
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -9587,10 +9587,28 @@ package android.service.dataloader {
package android.service.displayhash {
  public final class DisplayHashParams implements android.os.Parcelable {
    method public int describeContents();
    method @Nullable public android.util.Size getBufferSize();
    method public boolean isBufferScaleWithFiltering();
    method public boolean isGrayscaleBuffer();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.service.displayhash.DisplayHashParams> CREATOR;
  }
  public static final class DisplayHashParams.Builder {
    ctor public DisplayHashParams.Builder();
    method @NonNull public android.service.displayhash.DisplayHashParams build();
    method @NonNull public android.service.displayhash.DisplayHashParams.Builder setBufferScaleWithFiltering(boolean);
    method @NonNull public android.service.displayhash.DisplayHashParams.Builder setBufferSize(int, int);
    method @NonNull public android.service.displayhash.DisplayHashParams.Builder setGrayscaleBuffer(boolean);
  }
  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 @NonNull public abstract java.util.Map<java.lang.String,android.service.displayhash.DisplayHashParams> onGetDisplayHashAlgorithms();
    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";
  }
+19 −0
Original line number Diff line number Diff line
/*
 * 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.service.displayhash;

parcelable DisplayHashParams;
+251 −0
Original line number Diff line number Diff line
/*
 * 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.service.displayhash;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.os.Parcelable;
import android.util.Size;
import android.view.displayhash.DisplayHashResultCallback;

import com.android.internal.util.DataClass;

/**
 * Information passed from the {@link DisplayHasherService} to system server about how to get the
 * display data that will be used to generate the {@link android.view.displayhash.DisplayHash}
 *
 * @hide
 */
@SystemApi
@DataClass(genAidl = true, genToString = true, genParcelable = true, genHiddenConstructor = true)
public final class DisplayHashParams implements Parcelable {
    /**
     * The size to scale the buffer to so the hash algorithm can properly generate the hash. The
     * buffer given to the {@link DisplayHasherService#onGenerateDisplayHash(byte[], HardwareBuffer,
     * Rect, String, DisplayHashResultCallback)} will be stretched based on the value set here.
     * If {@code null}, the buffer size will not be changed.
     */
    @Nullable
    private final Size mBufferSize;

    /**
     * Whether the content captured will use filtering when scaling.
     */
    private final boolean mBufferScaleWithFiltering;

    /**
     * Whether the content will be captured in grayscale or color.
     */
    private final boolean mGrayscaleBuffer;

    /**
     * A builder for {@link DisplayHashParams}
     */
    public static final class Builder {
        @Nullable
        private Size mBufferSize;
        private boolean mBufferScaleWithFiltering;
        private boolean mGrayscaleBuffer;

        /**
         * Creates a new Builder.
         */
        public Builder() {
        }

        /**
         * The size to scale the buffer to so the hash algorithm can properly generate the hash.
         */
        @NonNull
        public Builder setBufferSize(int w, int h) {
            mBufferSize = new Size(w, h);
            return this;
        }

        /**
         * Whether the content captured will use filtering when scaling.
         */
        @NonNull
        public Builder setBufferScaleWithFiltering(boolean value) {
            mBufferScaleWithFiltering = value;
            return this;
        }

        /**
         * Whether the content will be captured in grayscale or color.
         */
        @NonNull
        public Builder setGrayscaleBuffer(boolean value) {
            mGrayscaleBuffer = value;
            return this;
        }

        /** Builds the instance. This builder should not be touched after calling this! */
        @NonNull
        public DisplayHashParams build() {
            return new DisplayHashParams(mBufferSize, mBufferScaleWithFiltering, mGrayscaleBuffer);
        }
    }



    // Code below generated by codegen v1.0.22.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
    //
    // To regenerate run:
    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/displayhash/DisplayHashParams.java
    //
    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
    //   Settings > Editor > Code Style > Formatter Control
    //@formatter:off


    /**
     * Creates a new DisplayHashParams.
     *
     * @param bufferSize
     *   The size to scale the buffer to so the hash algorithm can properly generate the hash. The
     *   buffer given to the {@link DisplayHasherService#onGenerateDisplayHash(byte[], HardwareBuffer,
     *   Rect, String, DisplayHashResultCallback)} will be stretched based on the value set here.
     *   If {@code null}, the buffer size will not be changed.
     * @param bufferScaleWithFiltering
     *   Whether the content captured will use filtering when scaling.
     * @param grayscaleBuffer
     *   Whether the content will be captured in grayscale or color.
     * @hide
     */
    @DataClass.Generated.Member
    public DisplayHashParams(
            @Nullable Size bufferSize,
            boolean bufferScaleWithFiltering,
            boolean grayscaleBuffer) {
        this.mBufferSize = bufferSize;
        this.mBufferScaleWithFiltering = bufferScaleWithFiltering;
        this.mGrayscaleBuffer = grayscaleBuffer;

        // onConstructed(); // You can define this method to get a callback
    }

    /**
     * The size to scale the buffer to so the hash algorithm can properly generate the hash. The
     * buffer given to the {@link DisplayHasherService#onGenerateDisplayHash(byte[], HardwareBuffer,
     * Rect, String, DisplayHashResultCallback)} will be stretched based on the value set here.
     * If {@code null}, the buffer size will not be changed.
     */
    @DataClass.Generated.Member
    public @Nullable Size getBufferSize() {
        return mBufferSize;
    }

    /**
     * Whether the content captured will use filtering when scaling.
     */
    @DataClass.Generated.Member
    public boolean isBufferScaleWithFiltering() {
        return mBufferScaleWithFiltering;
    }

    /**
     * Whether the content will be captured in grayscale or color.
     */
    @DataClass.Generated.Member
    public boolean isGrayscaleBuffer() {
        return mGrayscaleBuffer;
    }

    @Override
    @DataClass.Generated.Member
    public String toString() {
        // You can override field toString logic by defining methods like:
        // String fieldNameToString() { ... }

        return "DisplayHashParams { " +
                "bufferSize = " + mBufferSize + ", " +
                "bufferScaleWithFiltering = " + mBufferScaleWithFiltering + ", " +
                "grayscaleBuffer = " + mGrayscaleBuffer +
        " }";
    }

    @Override
    @DataClass.Generated.Member
    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
        // You can override field parcelling by defining methods like:
        // void parcelFieldName(Parcel dest, int flags) { ... }

        byte flg = 0;
        if (mBufferScaleWithFiltering) flg |= 0x2;
        if (mGrayscaleBuffer) flg |= 0x4;
        if (mBufferSize != null) flg |= 0x1;
        dest.writeByte(flg);
        if (mBufferSize != null) dest.writeSize(mBufferSize);
    }

    @Override
    @DataClass.Generated.Member
    public int describeContents() { return 0; }

    /** @hide */
    @SuppressWarnings({"unchecked", "RedundantCast"})
    @DataClass.Generated.Member
    /* package-private */ DisplayHashParams(@NonNull android.os.Parcel in) {
        // You can override field unparcelling by defining methods like:
        // static FieldType unparcelFieldName(Parcel in) { ... }

        byte flg = in.readByte();
        boolean bufferScaleWithFiltering = (flg & 0x2) != 0;
        boolean grayscaleBuffer = (flg & 0x4) != 0;
        Size bufferSize = (flg & 0x1) == 0 ? null : (Size) in.readSize();

        this.mBufferSize = bufferSize;
        this.mBufferScaleWithFiltering = bufferScaleWithFiltering;
        this.mGrayscaleBuffer = grayscaleBuffer;

        // onConstructed(); // You can define this method to get a callback
    }

    @DataClass.Generated.Member
    public static final @NonNull Parcelable.Creator<DisplayHashParams> CREATOR
            = new Parcelable.Creator<DisplayHashParams>() {
        @Override
        public DisplayHashParams[] newArray(int size) {
            return new DisplayHashParams[size];
        }

        @Override
        public DisplayHashParams createFromParcel(@NonNull android.os.Parcel in) {
            return new DisplayHashParams(in);
        }
    };

    @DataClass.Generated(
            time = 1615565493989L,
            codegenVersion = "1.0.22",
            sourceFile = "frameworks/base/core/java/android/service/displayhash/DisplayHashParams.java",
            inputSignatures = "private final @android.annotation.Nullable android.util.Size mBufferSize\nprivate final  boolean mBufferScaleWithFiltering\nprivate final  boolean mGrayscaleBuffer\nclass DisplayHashParams extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.Nullable android.util.Size mBufferSize\nprivate  boolean mBufferScaleWithFiltering\nprivate  boolean mGrayscaleBuffer\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setBufferSize(int,int)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setBufferScaleWithFiltering(boolean)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setGrayscaleBuffer(boolean)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams build()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genAidl=true, genToString=true, genParcelable=true, genHiddenConstructor=true)")
    @Deprecated
    private void __metadata() {}


    //@formatter:on
    // End of generated code

}
+24 −10
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ import android.view.displayhash.DisplayHash;
import android.view.displayhash.DisplayHashResultCallback;
import android.view.displayhash.VerifiedDisplayHash;

import java.util.Map;

/**
 * A service that handles generating and verify {@link DisplayHash}.
 *
@@ -49,15 +51,6 @@ public abstract class DisplayHasherService extends Service {
    public static final String EXTRA_VERIFIED_DISPLAY_HASH =
            "android.service.displayhash.extra.VERIFIED_DISPLAY_HASH";

    /**
     * Manifest metadata key for the resource string array containing the names of all hashing
     * algorithms provided by the service.
     *
     * @hide
     */
    public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS =
            "android.displayhash.available_algorithms";

    /**
     * The {@link Intent} action that must be declared as handled by a service in its manifest
     * for the system to recognize it as a DisplayHash providing service.
@@ -96,7 +89,7 @@ public abstract class DisplayHasherService extends Service {
     * @param buffer        The buffer for the content to generate the hash for.
     * @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
     *                      {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS)}.
     *                      {@link #getDisplayHashAlgorithms(RemoteCallback)}.
     * @param callback      The callback to invoke
     *                      {@link DisplayHashResultCallback#onDisplayHashResult(DisplayHash)}
     *                      if successfully generated a DisplayHash or {@link
@@ -107,6 +100,12 @@ public abstract class DisplayHasherService extends Service {
            @NonNull HardwareBuffer buffer, @NonNull Rect bounds,
            @NonNull String hashAlgorithm, @NonNull DisplayHashResultCallback callback);

    /**
     * Returns a map of supported algorithms and their {@link DisplayHashParams}
     */
    @NonNull
    public abstract Map<String, DisplayHashParams> onGetDisplayHashAlgorithms();

    /**
     * Call to verify that the DisplayHash passed in was generated by the system.
     *
@@ -132,6 +131,15 @@ public abstract class DisplayHasherService extends Service {
        callback.sendResult(data);
    }

    private void getDisplayHashAlgorithms(RemoteCallback callback) {
        Map<String, DisplayHashParams> displayHashParams = onGetDisplayHashAlgorithms();
        final Bundle data = new Bundle();
        for (Map.Entry<String, DisplayHashParams> entry : displayHashParams.entrySet()) {
            data.putParcelable(entry.getKey(), entry.getValue());
        }
        callback.sendResult(data);
    }

    private final class DisplayHasherServiceWrapper extends IDisplayHasherService.Stub {
        @Override
        public void generateDisplayHash(byte[] salt, HardwareBuffer buffer, Rect bounds,
@@ -164,5 +172,11 @@ public abstract class DisplayHasherService extends Service {
                    obtainMessage(DisplayHasherService::verifyDisplayHash,
                            DisplayHasherService.this, salt, displayHash, callback));
        }

        @Override
        public void getDisplayHashAlgorithms(RemoteCallback callback) {
            mHandler.sendMessage(obtainMessage(DisplayHasherService::getDisplayHashAlgorithms,
                    DisplayHasherService.this, callback));
        }
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -51,4 +51,11 @@ oneway interface IDisplayHasherService {
     * @param callback The callback invoked to send back the VerifiedDisplayHash.
     */
    void verifyDisplayHash(in byte[] salt, in DisplayHash displayHash, in RemoteCallback callback);

    /**
     * Call to get a map of supported algorithms and their {@link DisplayHashParams}
     *
     * @param callback The callback invoked to send back the map of algorithms to DisplayHashParams.
     */
    void getDisplayHashAlgorithms(in RemoteCallback callback);
}
Loading