• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.GenericDocument;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Objects;
28 
29 /**
30  * The Parcelable object contains a List of {@link GenericDocument}.
31  *
32  * <P>This class will batch a list of {@link GenericDocument}. If the number of documents is too
33  * large for a transact, they will be put to Android Shared Memory.
34  *
35  * @see Parcel#writeBlob(byte[])
36  * @hide
37  */
38 public final class DocumentsParcel implements Parcelable {
39     private final List<GenericDocument> mDocuments;
40 
DocumentsParcel(@onNull List<GenericDocument> documents)41     public DocumentsParcel(@NonNull List<GenericDocument> documents) {
42         mDocuments = Objects.requireNonNull(documents);
43     }
44 
DocumentsParcel(@onNull Parcel in)45     private DocumentsParcel(@NonNull Parcel in) {
46         mDocuments = readFromParcel(in);
47     }
48 
readFromParcel(Parcel source)49     private List<GenericDocument> readFromParcel(Parcel source) {
50         byte[] dataBlob = ParcelableUtil.readBlob(source);
51         // Create a parcel object to un-serialize the byte array we are reading from
52         // Parcel.readBlob(). Parcel.WriteBlob() could take care of whether to pass data via
53         // binder directly or Android shared memory if the data is large.
54         Parcel unmarshallParcel = Parcel.obtain();
55         try {
56             unmarshallParcel.unmarshall(dataBlob, 0, dataBlob.length);
57             unmarshallParcel.setDataPosition(0);
58             // read the number of document that stored in here.
59             int size = unmarshallParcel.readInt();
60             List<GenericDocument> documentList = new ArrayList<>(size);
61             for (int i = 0; i < size; i++) {
62                 // Read document's bundle and convert them.
63                 documentList.add(new GenericDocument(
64                         unmarshallParcel.readBundle(getClass().getClassLoader())));
65             }
66             return documentList;
67         } finally {
68             unmarshallParcel.recycle();
69         }
70     }
71 
72     public static final Creator<DocumentsParcel> CREATOR = new Creator<DocumentsParcel>() {
73         @Override
74         public DocumentsParcel createFromParcel(Parcel in) {
75             return new DocumentsParcel(in);
76         }
77 
78         @Override
79         public DocumentsParcel[] newArray(int size) {
80             return new DocumentsParcel[size];
81         }
82     };
83 
84     @Override
describeContents()85     public int describeContents() {
86         return 0;
87     }
88 
89     @Override
writeToParcel(Parcel dest, int flags)90     public void writeToParcel(Parcel dest, int flags) {
91         byte[] documentsByteArray = serializeToByteArray();
92         ParcelableUtil.writeBlob(dest, documentsByteArray);
93     }
94 
95     /**
96      * Serializes the whole object, So that we can use Parcel.writeBlob() to send data. WriteBlob()
97      * could take care of whether to pass data via binder directly or Android shared memory if the
98      * data is large.
99      */
100     @NonNull
serializeToByteArray()101     private byte[] serializeToByteArray() {
102         byte[] bytes;
103         Parcel data = Parcel.obtain();
104         try {
105             // Save the number documents to the temporary Parcel object.
106             data.writeInt(mDocuments.size());
107             // Save all document's bundle to the temporary Parcel object.
108             for (int i = 0; i < mDocuments.size(); i++) {
109                 data.writeBundle(mDocuments.get(i).getBundle());
110             }
111             bytes = data.marshall();
112         } finally {
113             data.recycle();
114         }
115         return bytes;
116     }
117 
118     /**  Returns the List of {@link GenericDocument} of this object. */
119     @NonNull
getDocuments()120     public List<GenericDocument> getDocuments() {
121         return mDocuments;
122     }
123 }
124