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

Commit 11244bbb authored by Oluwarotimi Adesina's avatar Oluwarotimi Adesina Committed by Android (Google) Code Review
Browse files

Merge "Allow Parcelling GD over binder limit" into main

parents 0c2df0e6 d73e7d79
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -40,8 +40,8 @@ public final class ExecuteAppFunctionRequest implements Parcelable {
                public ExecuteAppFunctionRequest createFromParcel(Parcel parcel) {
                    String targetPackageName = parcel.readString8();
                    String functionIdentifier = parcel.readString8();
                    GenericDocument parameters;
                    parameters = GenericDocument.createFromParcel(parcel);
                    GenericDocumentWrapper parameters = GenericDocumentWrapper
                            .CREATOR.createFromParcel(parcel);
                    Bundle extras = parcel.readBundle(Bundle.class.getClassLoader());
                    return new ExecuteAppFunctionRequest(
                            targetPackageName, functionIdentifier, extras, parameters);
@@ -75,17 +75,17 @@ public final class ExecuteAppFunctionRequest implements Parcelable {
     *
     * <p>The document may have missing parameters. Developers are advised to implement defensive
     * handling measures.
     *
     * <p>
     * TODO(b/357551503): Document how function parameters can be obtained for function execution
     */
    @NonNull
    private final GenericDocument mParameters;
    private final GenericDocumentWrapper mParameters;

    private ExecuteAppFunctionRequest(
            @NonNull String targetPackageName,
            @NonNull String functionIdentifier,
            @NonNull Bundle extras,
            @NonNull GenericDocument parameters) {
            @NonNull GenericDocumentWrapper parameters) {
        mTargetPackageName = Objects.requireNonNull(targetPackageName);
        mFunctionIdentifier = Objects.requireNonNull(functionIdentifier);
        mExtras = Objects.requireNonNull(extras);
@@ -117,7 +117,7 @@ public final class ExecuteAppFunctionRequest implements Parcelable {
     */
    @NonNull
    public GenericDocument getParameters() {
        return mParameters;
        return mParameters.getValue();
    }

    /**
@@ -152,7 +152,8 @@ public final class ExecuteAppFunctionRequest implements Parcelable {
        @NonNull
        private Bundle mExtras = Bundle.EMPTY;
        @NonNull
        private GenericDocument mParameters = new GenericDocument.Builder<>("", "", "").build();
        private GenericDocument mParameters =
                new GenericDocument.Builder<>("", "", "").build();

        public Builder(@NonNull String targetPackageName, @NonNull String functionIdentifier) {
            mTargetPackageName = Objects.requireNonNull(targetPackageName);
@@ -173,7 +174,8 @@ public final class ExecuteAppFunctionRequest implements Parcelable {
         */
        @NonNull
        public Builder setParameters(@NonNull GenericDocument parameters) {
            mParameters = Objects.requireNonNull(parameters);
            Objects.requireNonNull(parameters);
            mParameters = parameters;
            return this;
        }

@@ -183,7 +185,8 @@ public final class ExecuteAppFunctionRequest implements Parcelable {
        @NonNull
        public ExecuteAppFunctionRequest build() {
            return new ExecuteAppFunctionRequest(
                    mTargetPackageName, mFunctionIdentifier, mExtras, mParameters);
                    mTargetPackageName, mFunctionIdentifier, mExtras,
                    new GenericDocumentWrapper(mParameters));
        }
    }
}
+30 −23
Original line number Diff line number Diff line
@@ -41,13 +41,16 @@ public final class ExecuteAppFunctionResponse implements Parcelable {
            new Creator<ExecuteAppFunctionResponse>() {
                @Override
                public ExecuteAppFunctionResponse createFromParcel(Parcel parcel) {
                    GenericDocument result =
                            Objects.requireNonNull(GenericDocument.createFromParcel(parcel));
                    GenericDocumentWrapper resultWrapper =
                            Objects.requireNonNull(
                                    GenericDocumentWrapper
                                            .CREATOR.createFromParcel(parcel));
                    Bundle extras = Objects.requireNonNull(
                            parcel.readBundle(Bundle.class.getClassLoader()));
                    int resultCode = parcel.readInt();
                    String errorMessage = parcel.readString8();
                    return new ExecuteAppFunctionResponse(result, extras, resultCode, errorMessage);
                    return new ExecuteAppFunctionResponse(
                            resultWrapper, extras, resultCode, errorMessage);
                }

                @Override
@@ -127,7 +130,7 @@ public final class ExecuteAppFunctionResponse implements Parcelable {
     * <p>See {@link #getResultDocument} for more information on extracting the return value.
     */
    @NonNull
    private final GenericDocument mResultDocument;
    private final GenericDocumentWrapper mResultDocumentWrapper;

    /**
     * Returns the additional metadata data relevant to this function execution response.
@@ -135,16 +138,29 @@ public final class ExecuteAppFunctionResponse implements Parcelable {
    @NonNull
    private final Bundle mExtras;

    private ExecuteAppFunctionResponse(@NonNull GenericDocument resultDocument,
    private ExecuteAppFunctionResponse(@NonNull GenericDocumentWrapper resultDocumentWrapper,
                                       @NonNull Bundle extras,
                                       @ResultCode int resultCode,
                                       @Nullable String errorMessage) {
        mResultDocument = Objects.requireNonNull(resultDocument);
        mResultDocumentWrapper = Objects.requireNonNull(resultDocumentWrapper);
        mExtras = Objects.requireNonNull(extras);
        mResultCode = resultCode;
        mErrorMessage = errorMessage;
    }

    /**
     * Returns result codes from throwable.
     *
     * @hide
     */
    @FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER)
    static @ResultCode int getResultCode(@NonNull Throwable t) {
        if (t instanceof IllegalArgumentException) {
            return ExecuteAppFunctionResponse.RESULT_INVALID_ARGUMENT;
        }
        return ExecuteAppFunctionResponse.RESULT_APP_UNKNOWN_ERROR;
    }

    /**
     * Returns a generic document containing the return value of the executed function.
     *
@@ -166,7 +182,7 @@ public final class ExecuteAppFunctionResponse implements Parcelable {
     */
    @NonNull
    public GenericDocument getResultDocument() {
        return mResultDocument;
        return mResultDocumentWrapper.getValue();
    }

    /**
@@ -210,7 +226,7 @@ public final class ExecuteAppFunctionResponse implements Parcelable {

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        mResultDocument.writeToParcel(dest, flags);
        mResultDocumentWrapper.writeToParcel(dest, flags);
        dest.writeBundle(mExtras);
        dest.writeInt(mResultCode);
        dest.writeString8(mErrorMessage);
@@ -235,25 +251,14 @@ public final class ExecuteAppFunctionResponse implements Parcelable {
    public @interface ResultCode {
    }

    /**
     * Returns result codes from throwable.
     *
     * @hide
     */
    static @ResultCode int getResultCode(@NonNull Throwable t) {
        if (t instanceof IllegalArgumentException) {
            return ExecuteAppFunctionResponse.RESULT_INVALID_ARGUMENT;
        }
        return ExecuteAppFunctionResponse.RESULT_APP_UNKNOWN_ERROR;
    }

    /**
     * The builder for creating {@link ExecuteAppFunctionResponse} instances.
     */
    @FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER)
    public static final class Builder {
        @NonNull
        private GenericDocument mResultDocument = new GenericDocument.Builder<>("", "", "").build();
        private GenericDocument mResultDocument =
                new GenericDocument.Builder<>("", "", "").build();
        @NonNull
        private Bundle mExtras = Bundle.EMPTY;
        private int mResultCode;
@@ -271,7 +276,8 @@ public final class ExecuteAppFunctionResponse implements Parcelable {
         * with a result code of {@link #RESULT_OK} and a resultDocument.
         */
        public Builder(@NonNull GenericDocument resultDocument) {
            mResultDocument = Objects.requireNonNull(resultDocument);
            Objects.requireNonNull(resultDocument);
            mResultDocument = resultDocument;
            mResultCode = RESULT_OK;
        }

@@ -300,7 +306,8 @@ public final class ExecuteAppFunctionResponse implements Parcelable {
        @NonNull
        public ExecuteAppFunctionResponse build() {
            return new ExecuteAppFunctionResponse(
                    mResultDocument, mExtras, mResultCode, mErrorMessage);
                    new GenericDocumentWrapper(mResultDocument),
                    mExtras, mResultCode, mErrorMessage);
        }
    }
}
+91 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.app.appfunctions;

import android.app.appsearch.GenericDocument;
import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.NonNull;

import java.util.Objects;

/**
 * The Parcelable object contains a {@link GenericDocument} to allow the parcelization of it
 * exceeding the binder limit.
 *
 * <p>{#link {@link Parcel#writeBlob(byte[])}} could take care of whether to pass data via binder
 * directly or Android shared memory if the data is large.
 *
 * @hide
 * @see Parcel#writeBlob(byte[])
 */
public final class GenericDocumentWrapper implements Parcelable {
    public static final Creator<GenericDocumentWrapper> CREATOR =
            new Creator<>() {
                @Override
                public GenericDocumentWrapper createFromParcel(Parcel in) {
                    byte[] dataBlob = Objects.requireNonNull(in.readBlob());
                    Parcel unmarshallParcel = Parcel.obtain();
                    try {
                        unmarshallParcel.unmarshall(dataBlob, 0, dataBlob.length);
                        unmarshallParcel.setDataPosition(0);
                        return new GenericDocumentWrapper(
                                GenericDocument.createFromParcel(unmarshallParcel));
                    } finally {
                        unmarshallParcel.recycle();
                    }
                }

                @Override
                public GenericDocumentWrapper[] newArray(int size) {
                    return new GenericDocumentWrapper[size];
                }
            };
    @NonNull
    private final GenericDocument mGenericDocument;

    public GenericDocumentWrapper(@NonNull GenericDocument genericDocument) {
        mGenericDocument = Objects.requireNonNull(genericDocument);
    }

    /**
     * Returns the wrapped {@link android.app.appsearch.GenericDocument}
     */
    @NonNull
    public GenericDocument getValue() {
        return mGenericDocument;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        Parcel parcel = Parcel.obtain();
        try {
            mGenericDocument.writeToParcel(parcel, flags);
            byte[] bytes = parcel.marshall();
            dest.writeBlob(bytes);
        } finally {
            parcel.recycle();
        }

    }
}