• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app.appsearch.aidl;
18 
19 import android.annotation.NonNull;
20 import android.app.appsearch.ParcelableUtil;
21 import android.app.appsearch.AppSearchResult;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.util.Objects;
26 
27 /**
28  * Parcelable wrapper around {@link AppSearchResult}.
29  *
30  * <p>{@link AppSearchResult} can contain any value, including non-parcelable values. For the
31  * specific case of sending {@link AppSearchResult} across Binder, this class wraps an
32  * {@link AppSearchResult} that contains a parcelable type and provides parcelability of the whole
33  * structure.
34  *
35  * @param <ValueType> The type of result object for successful calls. Must be a parcelable type.
36  * @hide
37  */
38 public final class AppSearchResultParcel<ValueType> implements Parcelable {
39     private final AppSearchResult<ValueType> mResult;
40 
41     /** Creates a new {@link AppSearchResultParcel} from the given result. */
AppSearchResultParcel(@onNull AppSearchResult<ValueType> result)42     public AppSearchResultParcel(@NonNull AppSearchResult<ValueType> result) {
43         mResult = Objects.requireNonNull(result);
44     }
45 
AppSearchResultParcel(@onNull Parcel in)46     private AppSearchResultParcel(@NonNull Parcel in) {
47         byte[] dataBlob = Objects.requireNonNull(ParcelableUtil.readBlob(in));
48         Parcel data = Parcel.obtain();
49         try {
50             data.unmarshall(dataBlob, 0, dataBlob.length);
51             data.setDataPosition(0);
52             mResult = (AppSearchResult<ValueType>) directlyReadFromParcel(data);
53         } finally {
54             data.recycle();
55         }
56     }
57 
directlyReadFromParcel(@onNull Parcel data)58     static AppSearchResult directlyReadFromParcel(@NonNull Parcel data) {
59         int resultCode = data.readInt();
60         Object resultValue = data.readValue(/*loader=*/ null);
61         String errorMessage = data.readString();
62         if (resultCode == AppSearchResult.RESULT_OK) {
63             return AppSearchResult.newSuccessfulResult(resultValue);
64         } else {
65             return AppSearchResult.newFailedResult(resultCode, errorMessage);
66         }
67     }
68 
69     @NonNull
getResult()70     public AppSearchResult<ValueType> getResult() {
71         return mResult;
72     }
73 
74     /** @hide */
75     @Override
writeToParcel(@onNull Parcel dest, int flags)76     public void writeToParcel(@NonNull Parcel dest, int flags) {
77         // Serializes the whole object, So that we can use Parcel.writeBlob() to send data.
78         // WriteBlob() could take care of whether to pass data via binder directly or Android shared
79         // memory if the data is large.
80         byte[] bytes;
81         Parcel data = Parcel.obtain();
82         try {
83             directlyWriteToParcel(data, mResult);
84             bytes = data.marshall();
85         } finally {
86             data.recycle();
87         }
88         ParcelableUtil.writeBlob(dest, bytes);
89     }
90 
directlyWriteToParcel(@onNull Parcel data, @NonNull AppSearchResult result)91     static void directlyWriteToParcel(@NonNull Parcel data, @NonNull AppSearchResult result) {
92         data.writeInt(result.getResultCode());
93         if (result.isSuccess()) {
94             data.writeValue(result.getResultValue());
95         } else {
96             data.writeValue(null);
97         }
98         data.writeString(result.getErrorMessage());
99     }
100 
101     /** @hide */
102     @Override
describeContents()103     public int describeContents() {
104         return 0;
105     }
106 
107     /** @hide */
108     @NonNull
109     public static final Creator<AppSearchResultParcel<?>> CREATOR =
110             new Creator<AppSearchResultParcel<?>>() {
111                 @NonNull
112                 @Override
113                 public AppSearchResultParcel<?> createFromParcel(@NonNull Parcel in) {
114                     return new AppSearchResultParcel<>(in);
115                 }
116 
117                 @NonNull
118                 @Override
119                 public AppSearchResultParcel<?>[] newArray(int size) {
120                     return new AppSearchResultParcel<?>[size];
121                 }
122             };
123 }
124