• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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.audio_util;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.PendingIntent;
22 import android.content.Context;
23 import android.media.MediaDescription;
24 import android.media.MediaMetadata;
25 import android.media.Rating;
26 import android.media.session.MediaSession;
27 import android.media.session.PlaybackState;
28 import android.net.Uri;
29 import android.os.Bundle;
30 import android.os.Handler;
31 import android.os.ResultReceiver;
32 import android.view.KeyEvent;
33 
34 import java.util.List;
35 import java.util.Objects;
36 
37 /**
38  * Provide a mockable interface in order to test classes that use MediaController.
39  * We need this class due to the fact that the MediaController class is marked as final and
40  * there is no way to currently mock final classes in Android. Once this is possible this class
41  * can be deleted.
42  */
43 public class MediaController {
44     @NonNull public android.media.session.MediaController mDelegate;
45     public android.media.session.MediaController.TransportControls mTransportDelegate;
46     public TransportControls mTransportControls;
47 
MediaController(@onNull android.media.session.MediaController delegate)48     MediaController(@NonNull android.media.session.MediaController delegate) {
49         mDelegate = delegate;
50         mTransportDelegate = delegate.getTransportControls();
51         mTransportControls = new TransportControls();
52     }
53 
MediaController(Context context, MediaSession.Token token)54     MediaController(Context context, MediaSession.Token token) {
55         mDelegate = new android.media.session.MediaController(context, token);
56         mTransportDelegate = mDelegate.getTransportControls();
57         mTransportControls = new TransportControls();
58     }
59 
getWrappedInstance()60     public android.media.session.MediaController getWrappedInstance() {
61         return mDelegate;
62     }
63 
64     @NonNull
getTransportControls()65     public TransportControls getTransportControls() {
66         return mTransportControls;
67     }
68 
69     /**
70      * Wrapper for MediaController.dispatchMediaButtonEvent(KeyEvent keyEvent)
71      */
dispatchMediaButtonEvent(@onNull KeyEvent keyEvent)72     public boolean dispatchMediaButtonEvent(@NonNull KeyEvent keyEvent) {
73         return mDelegate.dispatchMediaButtonEvent(keyEvent);
74     }
75 
76     /**
77      * Wrapper for MediaController.getPlaybackState()
78      */
79     @Nullable
getPlaybackState()80     public PlaybackState getPlaybackState() {
81         return mDelegate.getPlaybackState();
82     }
83 
84 
85     /**
86      * Wrapper for MediaController.getMetadata()
87      */
88     @Nullable
getMetadata()89     public MediaMetadata getMetadata() {
90         return mDelegate.getMetadata();
91     }
92 
93     /**
94      * Wrapper for MediaController.getQueue()
95      */
96     @Nullable
getQueue()97     public List<MediaSession.QueueItem> getQueue() {
98         return mDelegate.getQueue();
99     }
100 
101     /**
102      * Wrapper for MediaController.getQueueTitle()
103      */
104     @Nullable
getQueueTitle()105     public CharSequence getQueueTitle() {
106         return mDelegate.getQueueTitle();
107     }
108 
109     /**
110      * Wrapper for MediaController.getExtras()
111      */
112     @Nullable
getExtras()113     public Bundle getExtras() {
114         return mDelegate.getExtras();
115     }
116 
117     /**
118      * Wrapper for MediaController.getRatingType()
119      */
getRatingType()120     public int getRatingType() {
121         return mDelegate.getRatingType();
122     }
123 
124     /**
125      * Wrapper for MediaController.getFlags()
126      */
getFlags()127     public long getFlags() {
128         return mDelegate.getFlags();
129     }
130 
131     /**
132      * Wrapper for MediaController.getPlaybackInfo()
133      */
134     @Nullable
getPlaybackInfo()135     public android.media.session.MediaController.PlaybackInfo getPlaybackInfo() {
136         return mDelegate.getPlaybackInfo();
137     }
138 
139 
140     /**
141      * Wrapper for MediaController.getSessionActivity()
142      */
143     @Nullable
getSessionActivity()144     public PendingIntent getSessionActivity() {
145         return mDelegate.getSessionActivity();
146     }
147 
148     /**
149      * Wrapper for MediaController.getSessionToken()
150      */
151     @NonNull
getSessionToken()152     public MediaSession.Token getSessionToken() {
153         return mDelegate.getSessionToken();
154     }
155 
156     /**
157      * Wrapper for MediaController.setVolumeTo(int value, int flags)
158      */
setVolumeTo(int value, int flags)159     public void setVolumeTo(int value, int flags) {
160         mDelegate.setVolumeTo(value, flags);
161     }
162 
163     /**
164      * Wrapper for MediaController.adjustVolume(int direction, int flags)
165      */
adjustVolume(int direction, int flags)166     public void adjustVolume(int direction, int flags) {
167         mDelegate.adjustVolume(direction, flags);
168     }
169 
170     /**
171      * Wrapper for MediaController.registerCallback(Callback callback)
172      */
registerCallback(@onNull Callback callback)173     public void registerCallback(@NonNull Callback callback) {
174         //TODO(apanicke): Add custom callback struct to be able to analyze and
175         // delegate callbacks
176         mDelegate.registerCallback(callback);
177     }
178 
179     /**
180      * Wrapper for MediaController.registerCallback(Callback callback, Handler handler)
181      */
registerCallback(@onNull Callback callback, @Nullable Handler handler)182     public void registerCallback(@NonNull Callback callback, @Nullable Handler handler) {
183         mDelegate.registerCallback(callback, handler);
184     }
185 
186     /**
187      * Wrapper for MediaController.unregisterCallback(Callback callback)
188      */
unregisterCallback(@onNull Callback callback)189     public void unregisterCallback(@NonNull Callback callback) {
190         mDelegate.unregisterCallback(callback);
191     }
192 
193     /**
194      * Wrapper for MediaController.sendCommand(String command, Bundle args, ResultReceiver cb)
195      */
sendCommand(@onNull String command, @Nullable Bundle args, @Nullable ResultReceiver cb)196     public void sendCommand(@NonNull String command, @Nullable Bundle args,
197             @Nullable ResultReceiver cb) {
198         mDelegate.sendCommand(command, args, cb);
199     }
200 
201     /**
202      * Wrapper for MediaController.getPackageName()
203      */
getPackageName()204     public String getPackageName() {
205         return mDelegate.getPackageName();
206     }
207 
208     /**
209      * Wrapper for MediaController.getTag()
210      */
getTag()211     public String getTag() {
212         return mDelegate.getTag();
213     }
214 
215     /**
216      * Wrapper for MediaController.controlsSameSession(MediaController other)
217      */
controlsSameSession(MediaController other)218     public boolean controlsSameSession(MediaController other) {
219         return mDelegate.getSessionToken().equals(other.getWrappedInstance().getSessionToken());
220     }
221 
222     /**
223      * Wrapper for MediaController.controlsSameSession(MediaController other)
224      */
controlsSameSession(android.media.session.MediaController other)225     public boolean controlsSameSession(android.media.session.MediaController other) {
226         return mDelegate.getSessionToken().equals(other.getSessionToken());
227     }
228 
229     /**
230      * Wrapper for MediaController.equals(Object other)
231      */
232     @Override
equals(Object o)233     public boolean equals(Object o) {
234         if (o instanceof android.media.session.MediaController) {
235             return mDelegate.equals(o);
236         } else if (o instanceof MediaController) {
237             MediaController other = (MediaController) o;
238             return mDelegate.equals(other.mDelegate);
239         }
240         return false;
241     }
242 
243     /**
244      * Wrapper for MediaController.hashCode()
245      */
246     @Override
hashCode()247     public int hashCode() {
248         return Objects.hash(mDelegate);
249     }
250 
251     /**
252      * Wrapper for MediaController.toString()
253      */
254     @Override
toString()255     public String toString() {
256         MediaMetadata data = getMetadata();
257         MediaDescription desc = (data == null) ? null : data.getDescription();
258         return "MediaController (" + getPackageName() + "@" + Integer.toHexString(
259                 mDelegate.hashCode()) + ") " + desc;
260     }
261 
262     /**
263      * Wrapper for MediaController.Callback
264      */
265     public abstract static class Callback extends android.media.session.MediaController.Callback {}
266 
267     /**
268      * Wrapper for MediaController.TransportControls
269      */
270     public class TransportControls {
271 
272         /**
273          * Wrapper for MediaController.TransportControls.prepare()
274          */
prepare()275         public void prepare() {
276             mTransportDelegate.prepare();
277         }
278 
279         /**
280          * Wrapper for MediaController.TransportControls.prepareFromMediaId()
281          */
prepareFromMediaId(String mediaId, Bundle extras)282         public void prepareFromMediaId(String mediaId, Bundle extras) {
283             mTransportDelegate.prepareFromMediaId(mediaId, extras);
284         }
285 
286         /**
287          * Wrapper for MediaController.TransportControls.prepareFromSearch()
288          */
prepareFromSearch(String query, Bundle extras)289         public void prepareFromSearch(String query, Bundle extras) {
290             mTransportDelegate.prepareFromSearch(query, extras);
291         }
292 
293         /**
294          * Wrapper for MediaController.TransportControls.prepareFromUri()
295          */
prepareFromUri(Uri uri, Bundle extras)296         public void prepareFromUri(Uri uri, Bundle extras) {
297             mTransportDelegate.prepareFromUri(uri, extras);
298         }
299 
300         /**
301          * Wrapper for MediaController.TransportControls.play()
302          */
play()303         public void play() {
304             mTransportDelegate.play();
305         }
306 
307         /**
308          * Wrapper for MediaController.TransportControls.playFromMediaId()
309          */
playFromMediaId(String mediaId, Bundle extras)310         public void playFromMediaId(String mediaId, Bundle extras) {
311             mTransportDelegate.playFromMediaId(mediaId, extras);
312         }
313 
314         /**
315          * Wrapper for MediaController.TransportControls.playFromSearch()
316          */
playFromSearch(String query, Bundle extras)317         public void playFromSearch(String query, Bundle extras) {
318             mTransportDelegate.playFromSearch(query, extras);
319         }
320 
321         /**
322          * Wrapper for MediaController.TransportControls.playFromUri()
323          */
playFromUri(Uri uri, Bundle extras)324         public void playFromUri(Uri uri, Bundle extras) {
325             mTransportDelegate.playFromUri(uri, extras);
326         }
327 
328         /**
329          * Wrapper for MediaController.TransportControls.skipToQueueItem()
330          */
skipToQueueItem(long id)331         public void skipToQueueItem(long id) {
332             mTransportDelegate.skipToQueueItem(id);
333         }
334 
335         /**
336          * Wrapper for MediaController.TransportControls.pause()
337          */
pause()338         public void pause() {
339             mTransportDelegate.pause();
340         }
341 
342         /**
343          * Wrapper for MediaController.TransportControls.stop()
344          */
stop()345         public void stop() {
346             mTransportDelegate.stop();
347         }
348 
349         /**
350          * Wrapper for MediaController.TransportControls.seekTo()
351          */
seekTo(long pos)352         public void seekTo(long pos) {
353             mTransportDelegate.seekTo(pos);
354         }
355 
356         /**
357          * Wrapper for MediaController.TransportControls.fastForward()
358          */
fastForward()359         public void fastForward() {
360             mTransportDelegate.fastForward();
361         }
362 
363         /**
364          * Wrapper for MediaController.TransportControls.skipToNext()
365          */
skipToNext()366         public void skipToNext() {
367             mTransportDelegate.skipToNext();
368         }
369 
370         /**
371          * Wrapper for MediaController.TransportControls.rewind()
372          */
rewind()373         public void rewind() {
374             mTransportDelegate.rewind();
375         }
376 
377         /**
378          * Wrapper for MediaController.TransportControls.skipToPrevious()
379          */
skipToPrevious()380         public void skipToPrevious() {
381             mTransportDelegate.skipToPrevious();
382         }
383 
384         /**
385          * Wrapper for MediaController.TransportControls.setRating()
386          */
setRating(Rating rating)387         public void setRating(Rating rating) {
388             mTransportDelegate.setRating(rating);
389         }
390 
391         /**
392          * Wrapper for MediaController.TransportControls.setPlaybackSpeed(float speed)
393          */
setPlaybackSpeed(float speed)394         public void setPlaybackSpeed(float speed) {
395             mTransportDelegate.setPlaybackSpeed(speed);
396         }
397 
398         /**
399          * Wrapper for MediaController.TransportControls.sendCustomAction()
400          */
sendCustomAction(@onNull PlaybackState.CustomAction customAction, @Nullable Bundle args)401         public void sendCustomAction(@NonNull PlaybackState.CustomAction customAction,
402                 @Nullable Bundle args) {
403             mTransportDelegate.sendCustomAction(customAction, args);
404         }
405 
406         /**
407          * Wrapper for MediaController.TransportControls.sendCustomAction()
408          */
sendCustomAction(@onNull String action, @Nullable Bundle args)409         public void sendCustomAction(@NonNull String action, @Nullable Bundle args) {
410             mTransportDelegate.sendCustomAction(action, args);
411         }
412     }
413 }
414 
415