AvrcpHelperClasses.java revision eb48cddfe0630c165baae581c65c1fe0c42a4842
1/*
2 * Copyright (C) 2016 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
17package com.android.bluetooth.avrcp;
18
19import android.media.session.MediaSession;
20
21import java.util.List;
22import java.util.Arrays;
23
24/*************************************************************************************************
25 * Helper classes used for callback/response of browsing commands:-
26 *     1) To bundle parameters for  native callbacks/response.
27 *     2) Stores information of Addressed and Browsed Media Players.
28 ************************************************************************************************/
29
30class AvrcpCmd {
31
32    public AvrcpCmd() {}
33
34    /* Helper classes to pass parameters from callbacks to Avrcp handler */
35    class FolderItemsCmd {
36        byte mScope;
37        int mStartItem;
38        int mEndItem;
39        byte mNumAttr;
40        int[] mAttrIDs;
41        public byte[] mAddress;
42
43        public FolderItemsCmd(byte[] address,byte scope, int startItem, int endItem, byte numAttr,
44                int[] attrIds) {
45            mAddress = address;
46            this.mScope = scope;
47            this.mStartItem = startItem;
48            this.mEndItem = endItem;
49            this.mNumAttr = numAttr;
50            this.mAttrIDs = attrIds;
51        }
52    }
53
54    class ItemAttrCmd {
55        byte mScope;
56        byte[] mUid;
57        int mUidCounter;
58        byte mNumAttr;
59        int[] mAttrIDs;
60        public byte[] mAddress;
61
62        public ItemAttrCmd(byte[] address, byte scope, byte[] uid, int uidCounter, byte numAttr,
63                int[] attrIDs) {
64            mAddress = address;
65            mScope = scope;
66            mUid = uid;
67            mUidCounter = uidCounter;
68            mNumAttr = numAttr;
69            mAttrIDs = attrIDs;
70        }
71    }
72
73    class ElementAttrCmd {
74        byte mNumAttr;
75        int[] mAttrIDs;
76        public byte[] mAddress;
77
78        public ElementAttrCmd(byte[] address, byte numAttr, int[] attrIDs) {
79            mAddress = address;
80            mNumAttr = numAttr;
81            mAttrIDs = attrIDs;
82        }
83    }
84}
85
86/* Helper classes to pass parameters to native response */
87class MediaPlayerListRsp {
88    byte mStatus;
89    short mUIDCounter;
90    byte itemType;
91    int[] mPlayerIds;
92    byte[] mPlayerTypes;
93    int[] mPlayerSubTypes;
94    byte[] mPlayStatusValues;
95    short[] mFeatureBitMaskValues;
96    String[] mPlayerNameList;
97    int mNumItems;
98
99    public MediaPlayerListRsp(byte status, short UIDCounter, int numItems, byte itemType,
100            int[] playerIds, byte[] playerTypes, int[] playerSubTypes, byte[] playStatusValues,
101            short[] featureBitMaskValues, String[] playerNameList) {
102        this.mStatus = status;
103        this.mUIDCounter = UIDCounter;
104        this.mNumItems = numItems;
105        this.itemType = itemType;
106        this.mPlayerIds = playerIds;
107        this.mPlayerTypes = playerTypes;
108        this.mPlayerSubTypes = new int[numItems];
109        this.mPlayerSubTypes = playerSubTypes;
110        this.mPlayStatusValues = new byte[numItems];
111        this.mPlayStatusValues = playStatusValues;
112        int bitMaskSize = AvrcpConstants.AVRC_FEATURE_MASK_SIZE;
113        this.mFeatureBitMaskValues = new short[numItems * bitMaskSize];
114        for (int bitMaskIndex = 0; bitMaskIndex < (numItems * bitMaskSize); bitMaskIndex++) {
115            this.mFeatureBitMaskValues[bitMaskIndex] = featureBitMaskValues[bitMaskIndex];
116        }
117        this.mPlayerNameList = playerNameList;
118    }
119}
120
121class FolderItemsRsp {
122    byte mStatus;
123    short mUIDCounter;
124    byte mScope;
125    int mNumItems;
126    byte[] mFolderTypes;
127    byte[] mPlayable;
128    byte[] mItemTypes;
129    byte[] mItemUid;
130    String[] mDisplayNames; /* display name of the item. Eg: Folder name or song name */
131    int[] mAttributesNum;
132    int[] mAttrIds;
133    String[] mAttrValues;
134
135    public FolderItemsRsp(byte Status, short UIDCounter, byte scope, int numItems,
136            byte[] folderTypes, byte[] playable, byte[] ItemTypes, byte[] ItemsUid,
137            String[] displayNameArray, int[] AttributesNum, int[] AttrIds, String[] attrValues) {
138        this.mStatus = Status;
139        this.mUIDCounter = UIDCounter;
140        this.mScope = scope;
141        this.mNumItems = numItems;
142        this.mFolderTypes = folderTypes;
143        this.mPlayable = playable;
144        this.mItemTypes = ItemTypes;
145        this.mItemUid = ItemsUid;
146        this.mDisplayNames = displayNameArray;
147        this.mAttributesNum = AttributesNum;
148        this.mAttrIds = AttrIds;
149        this.mAttrValues = attrValues;
150    }
151}
152
153class ItemAttrRsp {
154    byte mStatus;
155    byte mNumAttr;
156    int[] mAttributesIds;
157    String[] mAttributesArray;
158
159    public ItemAttrRsp(byte status, byte numAttr, int[] attributesIds, String[] attributesArray) {
160        this.mStatus = status;
161        this.mNumAttr = numAttr;
162        this.mAttributesIds = attributesIds;
163        this.mAttributesArray = attributesArray;
164    }
165}
166
167/* Helps managing the NowPlayingList */
168class NowPlayingListManager {
169    private List<MediaSession.QueueItem> mNowPlayingItems = null;
170
171    synchronized void setNowPlayingList(List<MediaSession.QueueItem> queue) {
172        mNowPlayingItems = queue;
173    }
174
175    synchronized List<MediaSession.QueueItem> getNowPlayingList() {
176        return mNowPlayingItems;
177    }
178}
179
180/* stores information of Media Players in the system */
181class MediaPlayerInfo {
182
183    private byte majorType;
184    private int subType;
185    private byte playStatus;
186    private short[] featureBitMask;
187    private String packageName;
188    private String displayableName;
189    private MediaController mediaController;
190
191    MediaPlayerInfo(MediaController controller, byte majorType, int subType, byte playStatus,
192            short[] featureBitMask, String packageName, String displayableName) {
193        this.setMajorType(majorType);
194        this.setSubType(subType);
195        this.playStatus = playStatus;
196        // store a copy the FeatureBitMask array
197        this.featureBitMask = Arrays.copyOf(featureBitMask, featureBitMask.length);
198        this.setPackageName(packageName);
199        this.setDisplayableName(displayableName);
200        this.setMediaController(controller);
201    }
202
203    /* getters and setters */
204    byte getPlayStatus() {
205        return playStatus;
206    }
207
208    void setPlayStatus(byte playStatus) {
209        this.playStatus = playStatus;
210    }
211
212    MediaController getMediaController() {
213        return mediaController;
214    }
215
216    void setMediaController(MediaController mediaController) {
217        if (mediaController != null) {
218            this.packageName = mediaController.getPackageName();
219        }
220        this.mediaController = mediaController;
221    }
222
223    void setPackageName(String name) {
224        // Controller determines package name when it is set.
225        if (mediaController != null) return;
226        this.packageName = name;
227    }
228
229    String getPackageName() {
230        if (mediaController != null) {
231            return mediaController.getPackageName();
232        } else if (packageName != null) {
233            return packageName;
234        }
235        return null;
236    }
237
238    byte getMajorType() {
239        return majorType;
240    }
241
242    void setMajorType(byte majorType) {
243        this.majorType = majorType;
244    }
245
246    int getSubType() {
247        return subType;
248    }
249
250    void setSubType(int subType) {
251        this.subType = subType;
252    }
253
254    String getDisplayableName() {
255        return displayableName;
256    }
257
258    void setDisplayableName(String displayableName) {
259        this.displayableName = displayableName;
260    }
261
262    short[] getFeatureBitMask() {
263        return featureBitMask;
264    }
265
266    void setFeatureBitMask(short[] featureBitMask) {
267        synchronized (this) {
268            this.featureBitMask = Arrays.copyOf(featureBitMask, featureBitMask.length);
269        }
270    }
271
272    boolean isBrowseSupported() {
273        synchronized (this) {
274            if (this.featureBitMask == null) return false;
275            for (short bit : this.featureBitMask) {
276                if (bit == AvrcpConstants.AVRC_PF_BROWSE_BIT_NO) return true;
277            }
278        }
279        return false;
280    }
281
282    @Override
283    public String toString() {
284        StringBuilder sb = new StringBuilder();
285        sb.append("MediaPlayerInfo ");
286        sb.append(getPackageName());
287        sb.append(" (as '" + getDisplayableName() + "')");
288        sb.append(" Type = " + getMajorType());
289        sb.append(", SubType = " + getSubType());
290        sb.append(", Status = " + playStatus);
291        sb.append(" Feature Bits [");
292        short[] bits = getFeatureBitMask();
293        for (int i = 0; i < bits.length; i++) {
294            if (i != 0) sb.append(" ");
295            sb.append(bits[i]);
296        }
297        sb.append("] Controller: ");
298        sb.append(getMediaController());
299        return sb.toString();
300    }
301}
302
303/* stores information for browsable Media Players available in the system */
304class BrowsePlayerInfo {
305    String packageName;
306    String displayableName;
307    String serviceClass;
308
309    public BrowsePlayerInfo(String packageName, String displayableName, String serviceClass) {
310        this.packageName = packageName;
311        this.displayableName = displayableName;
312        this.serviceClass = serviceClass;
313    }
314
315    @Override
316    public String toString() {
317        StringBuilder sb = new StringBuilder();
318        sb.append("BrowsePlayerInfo ");
319        sb.append(packageName);
320        sb.append(" ( as '" + displayableName + "')");
321        sb.append(" service " + serviceClass);
322        return sb.toString();
323    }
324}
325
326class FolderItemsData {
327    /* initialize sizes for rsp parameters */
328    int mNumItems;
329    int[] mAttributesNum;
330    byte[] mFolderTypes ;
331    byte[] mItemTypes;
332    byte[] mPlayable;
333    byte[] mItemUid;
334    String[] mDisplayNames;
335    int[] mAttrIds;
336    String[] mAttrValues;
337    int attrCounter;
338
339    public FolderItemsData(int size) {
340        mNumItems = size;
341        mAttributesNum = new int[size];
342
343        mFolderTypes = new byte[size]; /* folderTypes */
344        mItemTypes = new byte[size]; /* folder or media item */
345        mPlayable = new byte[size];
346        Arrays.fill(mFolderTypes, AvrcpConstants.FOLDER_TYPE_MIXED);
347        Arrays.fill(mItemTypes, AvrcpConstants.BTRC_ITEM_MEDIA);
348        Arrays.fill(mPlayable, AvrcpConstants.ITEM_PLAYABLE);
349
350        mItemUid = new byte[size * AvrcpConstants.UID_SIZE];
351        mDisplayNames = new String[size];
352
353        mAttrIds = null; /* array of attr ids */
354        mAttrValues = null; /* array of attr values */
355    }
356}
357