1 /*
2  * Copyright 2019 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 com.android.bluetooth.avrcpcontroller;
18 
19 import android.bluetooth.BluetoothAdapter;
20 import android.bluetooth.BluetoothDevice;
21 import android.content.Context;
22 import android.net.Uri;
23 import android.support.v4.media.MediaBrowserCompat.MediaItem;
24 import android.support.v4.media.MediaDescriptionCompat;
25 import android.support.v4.media.MediaMetadataCompat;
26 
27 import androidx.test.InstrumentationRegistry;
28 import androidx.test.runner.AndroidJUnit4;
29 
30 import org.junit.After;
31 import org.junit.Assert;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 
36 /**
37  * A test suite for the AvrcpItem class.
38  */
39 @RunWith(AndroidJUnit4.class)
40 public final class AvrcpItemTest {
41 
42     private BluetoothDevice mDevice;
43     private static final String UUID = "AVRCP-ITEM-TEST-UUID";
44 
45      // Attribute ID Values from AVRCP Specification
46     private static final int MEDIA_ATTRIBUTE_TITLE = 0x01;
47     private static final int MEDIA_ATTRIBUTE_ARTIST_NAME = 0x02;
48     private static final int MEDIA_ATTRIBUTE_ALBUM_NAME = 0x03;
49     private static final int MEDIA_ATTRIBUTE_TRACK_NUMBER = 0x04;
50     private static final int MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER = 0x05;
51     private static final int MEDIA_ATTRIBUTE_GENRE = 0x06;
52     private static final int MEDIA_ATTRIBUTE_PLAYING_TIME = 0x07;
53     private static final int MEDIA_ATTRIBUTE_COVER_ART_HANDLE = 0x08;
54 
55     @Before
setUp()56     public void setUp() {
57         Context context = InstrumentationRegistry.getTargetContext();
58         mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice("AA:BB:CC:DD:EE:FF");
59     }
60 
61     @After
tearDown()62     public void tearDown() {
63         mDevice = null;
64     }
65 
66     @Test
buildAvrcpItem()67     public void buildAvrcpItem() {
68         String title = "Aaaaargh";
69         String artist = "Bluetooth";
70         String album = "The Best Protocol";
71         long trackNumber = 1;
72         long totalTracks = 12;
73         String genre = "Viking Metal";
74         long playingTime = 301;
75         String artHandle = "abc123";
76         Uri uri = Uri.parse("content://somewhere");
77         Uri uri2 = Uri.parse("content://somewhereelse");
78 
79         AvrcpItem.Builder builder = new AvrcpItem.Builder();
80         builder.setItemType(AvrcpItem.TYPE_MEDIA);
81         builder.setType(AvrcpItem.MEDIA_AUDIO);
82         builder.setDevice(mDevice);
83         builder.setPlayable(true);
84         builder.setUid(0);
85         builder.setUuid(UUID);
86         builder.setTitle(title);
87         builder.setArtistName(artist);
88         builder.setAlbumName(album);
89         builder.setTrackNumber(trackNumber);
90         builder.setTotalNumberOfTracks(totalTracks);
91         builder.setGenre(genre);
92         builder.setPlayingTime(playingTime);
93         builder.setCoverArtHandle(artHandle);
94         builder.setCoverArtLocation(uri);
95 
96         AvrcpItem item = builder.build();
97 
98         Assert.assertEquals(mDevice, item.getDevice());
99         Assert.assertEquals(true, item.isPlayable());
100         Assert.assertEquals(false, item.isBrowsable());
101         Assert.assertEquals(0, item.getUid());
102         Assert.assertEquals(UUID, item.getUuid());
103         Assert.assertEquals(null, item.getDisplayableName());
104         Assert.assertEquals(title, item.getTitle());
105         Assert.assertEquals(artist, item.getArtistName());
106         Assert.assertEquals(album, item.getAlbumName());
107         Assert.assertEquals(trackNumber, item.getTrackNumber());
108         Assert.assertEquals(totalTracks, item.getTotalNumberOfTracks());
109         Assert.assertEquals(artHandle, item.getCoverArtHandle());
110         Assert.assertEquals(uri, item.getCoverArtLocation());
111     }
112 
113     @Test
buildAvrcpItemFromAvrcpAttributes()114     public void buildAvrcpItemFromAvrcpAttributes() {
115         String title = "Aaaaargh";
116         String artist = "Bluetooth";
117         String album = "The Best Protocol";
118         String trackNumber = "1";
119         String totalTracks = "12";
120         String genre = "Viking Metal";
121         String playingTime = "301";
122         String artHandle = "abc123";
123 
124         int[] attrIds = new int[]{
125             MEDIA_ATTRIBUTE_TITLE,
126             MEDIA_ATTRIBUTE_ARTIST_NAME,
127             MEDIA_ATTRIBUTE_ALBUM_NAME,
128             MEDIA_ATTRIBUTE_TRACK_NUMBER,
129             MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER,
130             MEDIA_ATTRIBUTE_GENRE,
131             MEDIA_ATTRIBUTE_PLAYING_TIME,
132             MEDIA_ATTRIBUTE_COVER_ART_HANDLE
133         };
134 
135         String[] attrMap = new String[]{
136             title,
137             artist,
138             album,
139             trackNumber,
140             totalTracks,
141             genre,
142             playingTime,
143             artHandle
144         };
145 
146         AvrcpItem.Builder builder = new AvrcpItem.Builder();
147         builder.fromAvrcpAttributeArray(attrIds, attrMap);
148         AvrcpItem item = builder.build();
149 
150         Assert.assertEquals(null, item.getDevice());
151         Assert.assertEquals(false, item.isPlayable());
152         Assert.assertEquals(false, item.isBrowsable());
153         Assert.assertEquals(0, item.getUid());
154         Assert.assertEquals(null, item.getUuid());
155         Assert.assertEquals(null, item.getDisplayableName());
156         Assert.assertEquals(title, item.getTitle());
157         Assert.assertEquals(artist, item.getArtistName());
158         Assert.assertEquals(album, item.getAlbumName());
159         Assert.assertEquals(1, item.getTrackNumber());
160         Assert.assertEquals(12, item.getTotalNumberOfTracks());
161         Assert.assertEquals(artHandle, item.getCoverArtHandle());
162         Assert.assertEquals(null, item.getCoverArtLocation());
163     }
164 
165     @Test
buildAvrcpItemFromAvrcpAttributesWithBadIds_badIdsIgnored()166     public void buildAvrcpItemFromAvrcpAttributesWithBadIds_badIdsIgnored() {
167         String title = "Aaaaargh";
168         String artist = "Bluetooth";
169         String album = "The Best Protocol";
170         String trackNumber = "1";
171         String totalTracks = "12";
172         String genre = "Viking Metal";
173         String playingTime = "301";
174         String artHandle = "abc123";
175 
176         int[] attrIds = new int[]{
177             MEDIA_ATTRIBUTE_TITLE,
178             MEDIA_ATTRIBUTE_ARTIST_NAME,
179             MEDIA_ATTRIBUTE_ALBUM_NAME,
180             MEDIA_ATTRIBUTE_TRACK_NUMBER,
181             MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER,
182             MEDIA_ATTRIBUTE_GENRE,
183             MEDIA_ATTRIBUTE_PLAYING_TIME,
184             MEDIA_ATTRIBUTE_COVER_ART_HANDLE,
185             75,
186             76,
187             77,
188             78
189         };
190 
191         String[] attrMap = new String[]{
192             title,
193             artist,
194             album,
195             trackNumber,
196             totalTracks,
197             genre,
198             playingTime,
199             artHandle,
200             "ignore me",
201             "ignore me",
202             "ignore me",
203             "ignore me"
204         };
205 
206         AvrcpItem.Builder builder = new AvrcpItem.Builder();
207         builder.fromAvrcpAttributeArray(attrIds, attrMap);
208         AvrcpItem item = builder.build();
209 
210         Assert.assertEquals(null, item.getDevice());
211         Assert.assertEquals(false, item.isPlayable());
212         Assert.assertEquals(false, item.isBrowsable());
213         Assert.assertEquals(0, item.getUid());
214         Assert.assertEquals(null, item.getUuid());
215         Assert.assertEquals(null, item.getDisplayableName());
216         Assert.assertEquals(title, item.getTitle());
217         Assert.assertEquals(artist, item.getArtistName());
218         Assert.assertEquals(album, item.getAlbumName());
219         Assert.assertEquals(1, item.getTrackNumber());
220         Assert.assertEquals(12, item.getTotalNumberOfTracks());
221         Assert.assertEquals(artHandle, item.getCoverArtHandle());
222         Assert.assertEquals(null, item.getCoverArtLocation());
223     }
224 
225     @Test
updateCoverArtLocation()226     public void updateCoverArtLocation() {
227         Uri uri = Uri.parse("content://somewhere");
228         Uri uri2 = Uri.parse("content://somewhereelse");
229 
230         AvrcpItem.Builder builder = new AvrcpItem.Builder();
231         builder.setCoverArtLocation(uri);
232 
233         AvrcpItem item = builder.build();
234         Assert.assertEquals(uri, item.getCoverArtLocation());
235 
236         item.setCoverArtLocation(uri2);
237         Assert.assertEquals(uri2, item.getCoverArtLocation());
238     }
239 
240     @Test
avrcpMediaItem_toMediaMetadata()241     public void avrcpMediaItem_toMediaMetadata() {
242         String title = "Aaaaargh";
243         String artist = "Bluetooth";
244         String album = "The Best Protocol";
245         long trackNumber = 1;
246         long totalTracks = 12;
247         String genre = "Viking Metal";
248         long playingTime = 301;
249         String artHandle = "abc123";
250         Uri uri = Uri.parse("content://somewhere");
251 
252         AvrcpItem.Builder builder = new AvrcpItem.Builder();
253         builder.setItemType(AvrcpItem.TYPE_MEDIA);
254         builder.setType(AvrcpItem.MEDIA_AUDIO);
255         builder.setDevice(mDevice);
256         builder.setPlayable(true);
257         builder.setUid(0);
258         builder.setUuid(UUID);
259         builder.setDisplayableName(title);
260         builder.setTitle(title);
261         builder.setArtistName(artist);
262         builder.setAlbumName(album);
263         builder.setTrackNumber(trackNumber);
264         builder.setTotalNumberOfTracks(totalTracks);
265         builder.setGenre(genre);
266         builder.setPlayingTime(playingTime);
267         builder.setCoverArtHandle(artHandle);
268         builder.setCoverArtLocation(uri);
269 
270         AvrcpItem item = builder.build();
271         MediaMetadataCompat metadata = item.toMediaMetadata();
272 
273         Assert.assertEquals(UUID, metadata.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID));
274         Assert.assertEquals(title,
275                 metadata.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE));
276         Assert.assertEquals(title, metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE));
277         Assert.assertEquals(artist, metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST));
278         Assert.assertEquals(album, metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM));
279         Assert.assertEquals(trackNumber,
280                 metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER));
281         Assert.assertEquals(totalTracks,
282                 metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS));
283         Assert.assertEquals(genre, metadata.getString(MediaMetadataCompat.METADATA_KEY_GENRE));
284         Assert.assertEquals(playingTime,
285                 metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION));
286         Assert.assertEquals(uri,
287                 Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI)));
288         Assert.assertEquals(uri,
289                 Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ART_URI)));
290         Assert.assertEquals(uri,
291                 Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI)));
292         Assert.assertEquals(null,
293                 metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON));
294         Assert.assertEquals(null, metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_ART));
295         Assert.assertEquals(null, metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART));
296         Assert.assertFalse(metadata.containsKey(MediaMetadataCompat.METADATA_KEY_BT_FOLDER_TYPE));
297     }
298 
299     @Test
avrcpFolderItem_toMediaMetadata()300     public void avrcpFolderItem_toMediaMetadata() {
301         String title = "Bluetooth Playlist";
302         String artist = "Many";
303         long totalTracks = 12;
304         String genre = "Viking Metal";
305         long playingTime = 301;
306         String artHandle = "abc123";
307         Uri uri = Uri.parse("content://somewhere");
308         int type = AvrcpItem.FOLDER_TITLES;
309 
310         AvrcpItem.Builder builder = new AvrcpItem.Builder();
311         builder.setItemType(AvrcpItem.TYPE_FOLDER);
312         builder.setType(type);
313         builder.setDevice(mDevice);
314         builder.setUuid(UUID);
315         builder.setDisplayableName(title);
316         builder.setTitle(title);
317         builder.setArtistName(artist);
318         builder.setTotalNumberOfTracks(totalTracks);
319         builder.setGenre(genre);
320         builder.setPlayingTime(playingTime);
321         builder.setCoverArtHandle(artHandle);
322         builder.setCoverArtLocation(uri);
323 
324         AvrcpItem item = builder.build();
325         MediaMetadataCompat metadata = item.toMediaMetadata();
326 
327         Assert.assertEquals(UUID, metadata.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID));
328         Assert.assertEquals(title,
329                 metadata.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE));
330         Assert.assertEquals(title, metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE));
331         Assert.assertEquals(artist, metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST));
332         Assert.assertEquals(null, metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM));
333         Assert.assertEquals(totalTracks,
334                 metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS));
335         Assert.assertEquals(genre, metadata.getString(MediaMetadataCompat.METADATA_KEY_GENRE));
336         Assert.assertEquals(playingTime,
337                 metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION));
338         Assert.assertEquals(uri,
339                 Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI)));
340         Assert.assertEquals(uri,
341                 Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ART_URI)));
342         Assert.assertEquals(uri,
343                 Uri.parse(metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI)));
344         Assert.assertEquals(null,
345                 metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON));
346         Assert.assertEquals(null, metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_ART));
347         Assert.assertEquals(null, metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART));
348         Assert.assertEquals(type,
349                 metadata.getLong(MediaMetadataCompat.METADATA_KEY_BT_FOLDER_TYPE));
350     }
351 
352     @Test
avrcpItemNoDisplayName_toMediaItem()353     public void avrcpItemNoDisplayName_toMediaItem() {
354         String title = "Aaaaargh";
355         Uri uri = Uri.parse("content://somewhere");
356 
357         AvrcpItem.Builder builder = new AvrcpItem.Builder();
358         builder.setPlayable(true);
359         builder.setUuid(UUID);
360         builder.setTitle(title);
361         builder.setCoverArtLocation(uri);
362 
363         AvrcpItem item = builder.build();
364         MediaItem mediaItem = item.toMediaItem();
365         MediaDescriptionCompat desc = mediaItem.getDescription();
366 
367         Assert.assertTrue(mediaItem.isPlayable());
368         Assert.assertFalse(mediaItem.isBrowsable());
369         Assert.assertEquals(UUID, mediaItem.getMediaId());
370 
371         Assert.assertEquals(UUID, desc.getMediaId());
372         Assert.assertEquals(null, desc.getMediaUri());
373         Assert.assertEquals(title, desc.getTitle().toString());
374         Assert.assertEquals(null, desc.getSubtitle());
375         Assert.assertEquals(uri, desc.getIconUri());
376         Assert.assertEquals(null, desc.getIconBitmap());
377     }
378 
379     @Test
avrcpItemWithDisplayName_toMediaItem()380     public void avrcpItemWithDisplayName_toMediaItem() {
381         String title = "Aaaaargh";
382         String displayName = "A Different Type of Aaaaargh";
383         Uri uri = Uri.parse("content://somewhere");
384 
385         AvrcpItem.Builder builder = new AvrcpItem.Builder();
386         builder.setPlayable(true);
387         builder.setUuid(UUID);
388         builder.setDisplayableName(displayName);
389         builder.setTitle(title);
390         builder.setCoverArtLocation(uri);
391 
392         AvrcpItem item = builder.build();
393         MediaItem mediaItem = item.toMediaItem();
394         MediaDescriptionCompat desc = mediaItem.getDescription();
395 
396         Assert.assertTrue(mediaItem.isPlayable());
397         Assert.assertFalse(mediaItem.isBrowsable());
398         Assert.assertEquals(UUID, mediaItem.getMediaId());
399 
400         Assert.assertEquals(UUID, desc.getMediaId());
401         Assert.assertEquals(null, desc.getMediaUri());
402         Assert.assertEquals(displayName, desc.getTitle().toString());
403         Assert.assertEquals(null, desc.getSubtitle());
404         Assert.assertEquals(uri, desc.getIconUri());
405         Assert.assertEquals(null, desc.getIconBitmap());
406     }
407 
408     @Test
avrcpItemBrowsable_toMediaItem()409     public void avrcpItemBrowsable_toMediaItem() {
410         String title = "Aaaaargh";
411         Uri uri = Uri.parse("content://somewhere");
412 
413         AvrcpItem.Builder builder = new AvrcpItem.Builder();
414         builder.setBrowsable(true);
415         builder.setUuid(UUID);
416         builder.setTitle(title);
417         builder.setCoverArtLocation(uri);
418 
419         AvrcpItem item = builder.build();
420         MediaItem mediaItem = item.toMediaItem();
421         MediaDescriptionCompat desc = mediaItem.getDescription();
422 
423         Assert.assertFalse(mediaItem.isPlayable());
424         Assert.assertTrue(mediaItem.isBrowsable());
425         Assert.assertEquals(UUID, mediaItem.getMediaId());
426 
427         Assert.assertEquals(UUID, desc.getMediaId());
428         Assert.assertEquals(null, desc.getMediaUri());
429         Assert.assertEquals(title, desc.getTitle().toString());
430         Assert.assertEquals(null, desc.getSubtitle());
431         Assert.assertEquals(uri, desc.getIconUri());
432         Assert.assertEquals(null, desc.getIconBitmap());
433     }
434 }
435