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.media.tv;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.net.Uri;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.os.SharedMemory;
25 
26 /**
27  * A response for Table from broadcast signal.
28  */
29 public final class TableResponse extends BroadcastInfoResponse implements Parcelable {
30     private static final @TvInputManager.BroadcastInfoType int RESPONSE_TYPE =
31             TvInputManager.BROADCAST_INFO_TYPE_TABLE;
32 
33     public static final @NonNull Parcelable.Creator<TableResponse> CREATOR =
34             new Parcelable.Creator<TableResponse>() {
35                 @Override
36                 public TableResponse createFromParcel(Parcel source) {
37                     source.readInt();
38                     return createFromParcelBody(source);
39                 }
40 
41                 @Override
42                 public TableResponse[] newArray(int size) {
43                     return new TableResponse[size];
44                 }
45             };
46 
47     private final Uri mTableUri;
48     private final int mVersion;
49     private final int mSize;
50     private final byte[] mTableByteArray;
51     private final SharedMemory mTableSharedMemory;
52 
createFromParcelBody(Parcel in)53     static TableResponse createFromParcelBody(Parcel in) {
54         return new TableResponse(in);
55     }
56 
57     /**
58      * Constructs a TableResponse with a table URI.
59      *
60      * @param requestId The ID is used to associate the response with the request.
61      * @param sequence The sequence number which indicates the order of related responses.
62      * @param responseResult The result for the response. It's one of {@link #RESPONSE_RESULT_OK},
63      *                       {@link #RESPONSE_RESULT_CANCEL}, {@link #RESPONSE_RESULT_ERROR}.
64      * @param tableUri The URI of the table in the database.
65      * @param version The version number of requested table.
66      * @param size The Size number of table in bytes.
67      *
68      * @deprecated use {@link Builder} instead.
69      */
70     @Deprecated
TableResponse(int requestId, int sequence, @ResponseResult int responseResult, @Nullable Uri tableUri, int version, int size)71     public TableResponse(int requestId, int sequence, @ResponseResult int responseResult,
72             @Nullable Uri tableUri, int version, int size) {
73         super(RESPONSE_TYPE, requestId, sequence, responseResult);
74         mVersion = version;
75         mSize = size;
76         mTableUri = tableUri;
77         mTableByteArray = null;
78         mTableSharedMemory = null;
79     }
80 
81     /**
82      * Constructs a TableResponse.
83      *
84      * @param requestId The ID is used to associate the response with the request.
85      * @param sequence The sequence number which indicates the order of related responses.
86      * @param responseResult The result for the response. It's one of {@link #RESPONSE_RESULT_OK},
87      *                       {@link #RESPONSE_RESULT_CANCEL}, {@link #RESPONSE_RESULT_ERROR}.
88      * @param tableSharedMemory The shared memory which stores the table. The table size can be
89      *                          large so using a shared memory optimizes the data
90      *                          communication between the table data source and the receiver. The
91      *                          structure syntax of the table depends on the table name in
92      *                          {@link TableRequest#getTableName()} and the corresponding standard.
93      * @param version The version number of requested table.
94      * @param size The Size number of table in bytes.
95      * @param tableUri The URI of the table in the database.
96      * @param tableByteArray The byte array which stores the table in bytes. The structure and
97      *                       syntax of the table depends on the table name in
98      * @param tableSharedMemory The shared memory which stores the table. The table size can be
99      *                          large so using a shared memory optimizes the data
100      *                          communication between the table data source and the receiver. The
101      *                          structure syntax of the table depends on the table name in
102      *                          {@link TableRequest#getTableName()} and the corresponding standard.
103      */
TableResponse(int requestId, int sequence, @ResponseResult int responseResult, int version, int size, Uri tableUri, byte[] tableByteArray, SharedMemory tableSharedMemory)104     private TableResponse(int requestId, int sequence, @ResponseResult int responseResult,
105             int version, int size, Uri tableUri, byte[] tableByteArray,
106             SharedMemory tableSharedMemory) {
107         super(RESPONSE_TYPE, requestId, sequence, responseResult);
108         mVersion = version;
109         mSize = size;
110         mTableUri = tableUri;
111         mTableByteArray = tableByteArray;
112         mTableSharedMemory = tableSharedMemory;
113     }
114 
115     /**
116      * Builder for {@link TableResponse}.
117      */
118     public static final class Builder {
119         private final int mRequestId;
120         private final int mSequence;
121         @ResponseResult
122         private final int mResponseResult;
123         private final int mVersion;
124         private final int mSize;
125         private Uri mTableUri;
126         private byte[] mTableByteArray;
127         private SharedMemory mTableSharedMemory;
128 
129         /**
130          * Constructs a Builder object of {@link TableResponse}.
131          *
132          * @param requestId The ID is used to associate the response with the request.
133          * @param sequence The sequence number which indicates the order of related responses.
134          * @param responseResult The result for the response. It's one of
135          *                       {@link #RESPONSE_RESULT_OK}, {@link #RESPONSE_RESULT_CANCEL},
136          *                       {@link #RESPONSE_RESULT_ERROR}.
137          * @param version The version number of requested table.
138          * @param size The Size number of table in bytes.
139          */
Builder(int requestId, int sequence, @ResponseResult int responseResult, int version, int size)140         public Builder(int requestId, int sequence, @ResponseResult int responseResult, int version,
141                 int size) {
142             mRequestId = requestId;
143             mSequence = sequence;
144             mResponseResult = responseResult;
145             mVersion = version;
146             mSize = size;
147         }
148 
149         /**
150          * Sets table URI.
151          *
152          * <p>For a single builder instance, at most one of table URI, table byte array, and table
153          * shared memory can be set. If more than one are set, only the last call takes precedence
154          * and others are reset to {@code null}.
155          *
156          * @param uri The URI of the table.
157          */
158         @NonNull
setTableUri(@onNull Uri uri)159         public Builder setTableUri(@NonNull Uri uri) {
160             mTableUri = uri;
161             mTableByteArray = null;
162             mTableSharedMemory = null;
163             return this;
164         }
165 
166         /**
167          * Sets table byte array.
168          *
169          * <p>For a single builder instance, at most one of table URI, table byte array, and table
170          * shared memory can be set. If more than one are set, only the last call takes precedence
171          * and others are reset to {@code null}.
172          *
173          * @param bytes The byte array which stores the table in bytes. The structure and
174          *              syntax of the table depends on the table name in
175          *              {@link TableRequest#getTableName()} and the corresponding standard.
176          */
177         @NonNull
setTableByteArray(@onNull byte[] bytes)178         public Builder setTableByteArray(@NonNull byte[] bytes) {
179             mTableByteArray = bytes;
180             mTableUri = null;
181             mTableSharedMemory = null;
182             return this;
183         }
184 
185 
186         /**
187          * Sets table shared memory.
188          *
189          * <p>For a single builder instance, at most one of table URI, table byte array, and table
190          * shared memory can be set. If more than one are set, only the last call takes precedence
191          * and others are reset to {@code null}.
192          *
193          * @param sharedMemory The shared memory which stores the table. The table size can be
194          *                     large so using a shared memory optimizes the data
195          *                     communication between the table data source and the receiver. The
196          *                     structure syntax of the table depends on the table name in
197          *                     {@link TableRequest#getTableName()} and the corresponding standard.
198          */
199         @NonNull
setTableSharedMemory(@onNull SharedMemory sharedMemory)200         public Builder setTableSharedMemory(@NonNull SharedMemory sharedMemory) {
201             mTableSharedMemory = sharedMemory;
202             mTableUri = null;
203             mTableByteArray = null;
204             return this;
205         }
206 
207         /**
208          * Builds a {@link TableResponse} object.
209          */
210         @NonNull
build()211         public TableResponse build() {
212             return new TableResponse(mRequestId, mSequence, mResponseResult, mVersion, mSize,
213                     mTableUri, mTableByteArray, mTableSharedMemory);
214         }
215     }
216 
TableResponse(Parcel source)217     TableResponse(Parcel source) {
218         super(RESPONSE_TYPE, source);
219         String uriString = source.readString();
220         mTableUri = uriString == null ? null : Uri.parse(uriString);
221         mVersion = source.readInt();
222         mSize = source.readInt();
223         int arrayLength = source.readInt();
224         if (arrayLength >= 0) {
225             mTableByteArray = new byte[arrayLength];
226             source.readByteArray(mTableByteArray);
227         } else {
228             mTableByteArray = null;
229         }
230         mTableSharedMemory = (SharedMemory) source.readTypedObject(SharedMemory.CREATOR);
231     }
232 
233     /**
234      * Gets the URI in TvProvider database.
235      */
236     @Nullable
getTableUri()237     public Uri getTableUri() {
238         return mTableUri;
239     }
240 
241     /**
242      * Gets the data of the table as a byte array.
243      *
244      * @return the table data as a byte array, or {@code null} if the data is not stored as a byte
245      *         array.
246      */
247     @Nullable
getTableByteArray()248     public byte[] getTableByteArray() {
249         return mTableByteArray;
250     }
251 
252     /**
253      * Gets the data of the table as a {@link SharedMemory} object.
254      *
255      * <p> This data lives in a {@link SharedMemory} instance because of the potentially large
256      * amount of data needed to store the table. This optimizes the data communication between the
257      * table data source and the receiver.
258      *
259      * @return the table data as a {@link SharedMemory} object, or {@code null} if the data is not
260      *         stored in shared memory.
261      *
262      * @see SharedMemory#map(int, int, int)
263      */
264     @Nullable
getTableSharedMemory()265     public SharedMemory getTableSharedMemory() {
266         return mTableSharedMemory;
267     }
268 
269     /**
270      * Gets the version number of requested table. If it is null, value will be -1.
271      * <p>The consistency of version numbers between request and response depends on
272      * {@link BroadcastInfoRequest.RequestOption}. If the request has RequestOption value
273      * REQUEST_OPTION_AUTO_UPDATE, then the response may be set to the latest version which may be
274      * different from the version of the request. Otherwise, response with a different version from
275      * its request will be considered invalid.
276      */
getVersion()277     public int getVersion() {
278         return mVersion;
279     }
280 
281     /**
282      * Gets the Size number of table.
283      */
getSize()284     public int getSize() {
285         return mSize;
286     }
287 
288     @Override
describeContents()289     public int describeContents() {
290         return 0;
291     }
292 
293     @Override
writeToParcel(@onNull Parcel dest, int flags)294     public void writeToParcel(@NonNull Parcel dest, int flags) {
295         super.writeToParcel(dest, flags);
296         String uriString = mTableUri == null ? null : mTableUri.toString();
297         dest.writeString(uriString);
298         dest.writeInt(mVersion);
299         dest.writeInt(mSize);
300         if (mTableByteArray != null) {
301             dest.writeInt(mTableByteArray.length);
302             dest.writeByteArray(mTableByteArray);
303         } else {
304             dest.writeInt(-1);
305         }
306         dest.writeTypedObject(mTableSharedMemory, flags);
307     }
308 }
309