diff options
3 files changed, 133 insertions, 32 deletions
diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionRequest.java b/core/java/android/app/appfunctions/ExecuteAppFunctionRequest.java index a50425e4db91..db3de6261589 100644 --- a/core/java/android/app/appfunctions/ExecuteAppFunctionRequest.java +++ b/core/java/android/app/appfunctions/ExecuteAppFunctionRequest.java @@ -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)); } } } diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java b/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java index 872327ddd461..9fb3375a2446 100644 --- a/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java +++ b/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java @@ -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,17 +138,30 @@ 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. * * <p>The {@link #PROPERTY_RETURN_VALUE} key can be used to obtain the return value.</p> @@ -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); @@ -236,24 +252,13 @@ public final class ExecuteAppFunctionResponse implements Parcelable { } /** - * 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); } } } diff --git a/core/java/android/app/appfunctions/GenericDocumentWrapper.java b/core/java/android/app/appfunctions/GenericDocumentWrapper.java new file mode 100644 index 000000000000..8c76c8e4b73b --- /dev/null +++ b/core/java/android/app/appfunctions/GenericDocumentWrapper.java @@ -0,0 +1,91 @@ +/* + * 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(); + } + + } +} |