Home | History | Annotate | Download | only in mockable
      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.avrcp;
     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 
     36 /**
     37  * Provide a mockable interface in order to test classes that use MediaController.
     38  * We need this class due to the fact that the MediaController class is marked as final and
     39  * there is no way to currently mock final classes in Android. Once this is possible this class
     40  * can be deleted.
     41  */
     42 public class MediaController {
     43     @NonNull public android.media.session.MediaController mDelegate;
     44     public android.media.session.MediaController.TransportControls mTransportDelegate;
     45     public TransportControls mTransportControls;
     46 
     47     public MediaController(@NonNull android.media.session.MediaController delegate) {
     48         mDelegate = delegate;
     49         mTransportDelegate = delegate.getTransportControls();
     50         mTransportControls = new TransportControls();
     51     }
     52 
     53     public MediaController(Context context, MediaSession.Token token) {
     54         mDelegate = new android.media.session.MediaController(context, token);
     55         mTransportDelegate = mDelegate.getTransportControls();
     56         mTransportControls = new TransportControls();
     57     }
     58 
     59     public android.media.session.MediaController getWrappedInstance() {
     60         return mDelegate;
     61     }
     62 
     63     @NonNull
     64     public TransportControls getTransportControls() {
     65         return mTransportControls;
     66     }
     67 
     68     public boolean dispatchMediaButtonEvent(@NonNull KeyEvent keyEvent) {
     69         return mDelegate.dispatchMediaButtonEvent(keyEvent);
     70     }
     71 
     72     @Nullable
     73     public PlaybackState getPlaybackState() {
     74         return mDelegate.getPlaybackState();
     75     }
     76 
     77     @Nullable
     78     public MediaMetadata getMetadata() {
     79         return mDelegate.getMetadata();
     80     }
     81 
     82     @Nullable
     83     public List<MediaSession.QueueItem> getQueue() {
     84         return mDelegate.getQueue();
     85     }
     86 
     87     @Nullable
     88     public CharSequence getQueueTitle() {
     89         return mDelegate.getQueueTitle();
     90     }
     91 
     92     @Nullable
     93     public Bundle getExtras() {
     94         return mDelegate.getExtras();
     95     }
     96 
     97     public int getRatingType() {
     98         return mDelegate.getRatingType();
     99     }
    100 
    101     public long getFlags() {
    102         return mDelegate.getFlags();
    103     }
    104 
    105     @Nullable
    106     public android.media.session.MediaController.PlaybackInfo getPlaybackInfo() {
    107         return mDelegate.getPlaybackInfo();
    108     }
    109 
    110     @Nullable
    111     public PendingIntent getSessionActivity() {
    112         return mDelegate.getSessionActivity();
    113     }
    114 
    115     @NonNull
    116     public MediaSession.Token getSessionToken() {
    117         return mDelegate.getSessionToken();
    118     }
    119 
    120     public void setVolumeTo(int value, int flags) {
    121         mDelegate.setVolumeTo(value, flags);
    122     }
    123 
    124     public void adjustVolume(int direction, int flags) {
    125         mDelegate.adjustVolume(direction, flags);
    126     }
    127 
    128     public void registerCallback(@NonNull Callback callback) {
    129         //TODO(apanicke): Add custom callback struct to be able to analyze and
    130         // delegate callbacks
    131         mDelegate.registerCallback(callback);
    132     }
    133 
    134     public void registerCallback(@NonNull Callback callback, @Nullable Handler handler) {
    135         mDelegate.registerCallback(callback, handler);
    136     }
    137 
    138     public void unregisterCallback(@NonNull Callback callback) {
    139         mDelegate.unregisterCallback(callback);
    140     }
    141 
    142     public void sendCommand(@NonNull String command, @Nullable Bundle args,
    143             @Nullable ResultReceiver cb) {
    144         mDelegate.sendCommand(command, args, cb);
    145     }
    146 
    147     public String getPackageName() {
    148         return mDelegate.getPackageName();
    149     }
    150 
    151     public String getTag() {
    152         return mDelegate.getTag();
    153     }
    154 
    155     public boolean controlsSameSession(MediaController other) {
    156         return mDelegate.controlsSameSession(other.getWrappedInstance());
    157     }
    158 
    159     public boolean controlsSameSession(android.media.session.MediaController other) {
    160         return mDelegate.controlsSameSession(other);
    161     }
    162 
    163     @Override
    164     public boolean equals(Object o) {
    165         if (o instanceof android.media.session.MediaController) {
    166             return mDelegate.equals(o);
    167         } else if (o instanceof MediaController) {
    168             MediaController other = (MediaController) o;
    169             return mDelegate.equals(other.mDelegate);
    170         }
    171         return false;
    172     }
    173 
    174     @Override
    175     public String toString() {
    176         MediaMetadata data = getMetadata();
    177         MediaDescription desc = (data == null) ? null : data.getDescription();
    178         return "MediaController (" + getPackageName() + "@" + Integer.toHexString(
    179                 mDelegate.hashCode()) + ") " + desc;
    180     }
    181 
    182     public abstract static class Callback extends android.media.session.MediaController.Callback {}
    183 
    184     public class TransportControls {
    185 
    186         public void prepare() {
    187             mTransportDelegate.prepare();
    188         }
    189 
    190         public void prepareFromMediaId(String mediaId, Bundle extras) {
    191             mTransportDelegate.prepareFromMediaId(mediaId, extras);
    192         }
    193 
    194         public void prepareFromSearch(String query, Bundle extras) {
    195             mTransportDelegate.prepareFromSearch(query, extras);
    196         }
    197 
    198         public void prepareFromUri(Uri uri, Bundle extras) {
    199             mTransportDelegate.prepareFromUri(uri, extras);
    200         }
    201 
    202         public void play() {
    203             mTransportDelegate.play();
    204         }
    205 
    206         public void playFromMediaId(String mediaId, Bundle extras) {
    207             mTransportDelegate.playFromMediaId(mediaId, extras);
    208         }
    209 
    210         public void playFromSearch(String query, Bundle extras) {
    211             mTransportDelegate.playFromSearch(query, extras);
    212         }
    213 
    214         public void playFromUri(Uri uri, Bundle extras) {
    215             mTransportDelegate.playFromUri(uri, extras);
    216         }
    217 
    218         public void skipToQueueItem(long id) {
    219             mTransportDelegate.skipToQueueItem(id);
    220         }
    221 
    222         public void pause() {
    223             mTransportDelegate.pause();
    224         }
    225 
    226         public void stop() {
    227             mTransportDelegate.stop();
    228         }
    229 
    230         public void seekTo(long pos) {
    231             mTransportDelegate.seekTo(pos);
    232         }
    233 
    234         public void fastForward() {
    235             mTransportDelegate.fastForward();
    236         }
    237 
    238         public void skipToNext() {
    239             mTransportDelegate.skipToNext();
    240         }
    241 
    242         public void rewind() {
    243             mTransportDelegate.rewind();
    244         }
    245 
    246         public void skipToPrevious() {
    247             mTransportDelegate.skipToPrevious();
    248         }
    249 
    250         public void setRating(Rating rating) {
    251             mTransportDelegate.setRating(rating);
    252         }
    253 
    254         public void sendCustomAction(@NonNull PlaybackState.CustomAction customAction,
    255                 @Nullable Bundle args) {
    256             mTransportDelegate.sendCustomAction(customAction, args);
    257         }
    258 
    259         public void sendCustomAction(@NonNull String action, @Nullable Bundle args) {
    260             mTransportDelegate.sendCustomAction(action, args);
    261         }
    262     }
    263 }
    264 
    265