Home | History | Annotate | Download | only in onemedia
      1 
      2 /*
      3  * Copyright (C) 2014 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 package com.android.onemedia;
     18 
     19 import android.media.MediaMetadata;
     20 import android.media.session.MediaController;
     21 import android.media.session.MediaSession;
     22 import android.media.session.MediaSessionManager;
     23 import android.media.session.PlaybackState;
     24 import android.os.Bundle;
     25 import android.os.Handler;
     26 import android.os.IBinder;
     27 import android.os.RemoteException;
     28 import android.app.Activity;
     29 import android.content.ComponentName;
     30 import android.content.Context;
     31 import android.content.Intent;
     32 import android.content.ServiceConnection;
     33 import android.graphics.Bitmap;
     34 import android.util.Log;
     35 
     36 import com.android.onemedia.playback.RequestUtils;
     37 
     38 public class PlayerController {
     39     private static final String TAG = "PlayerController";
     40 
     41     public static final int STATE_DISCONNECTED = 0;
     42     public static final int STATE_CONNECTED = 1;
     43 
     44     protected MediaController mController;
     45     protected IPlayerService mBinder;
     46     protected MediaController.TransportControls mTransportControls;
     47 
     48     private final Intent mServiceIntent;
     49     private Activity mContext;
     50     private Listener mListener;
     51     private SessionCallback mControllerCb;
     52     private MediaSessionManager mManager;
     53     private Handler mHandler = new Handler();
     54 
     55     private boolean mResumed;
     56     private Bitmap mArt;
     57 
     58     public PlayerController(Activity context, Intent serviceIntent) {
     59         mContext = context;
     60         if (serviceIntent == null) {
     61             mServiceIntent = new Intent(mContext, PlayerService.class);
     62         } else {
     63             mServiceIntent = serviceIntent;
     64         }
     65         mControllerCb = new SessionCallback();
     66         mManager = (MediaSessionManager) context
     67                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
     68 
     69         mResumed = false;
     70     }
     71 
     72     public void setListener(Listener listener) {
     73         mListener = listener;
     74         Log.d(TAG, "Listener set to " + listener + " session is " + mController);
     75         if (mListener != null) {
     76             mHandler = new Handler();
     77             mListener.onConnectionStateChange(
     78                     mController == null ? STATE_DISCONNECTED : STATE_CONNECTED);
     79         }
     80     }
     81 
     82     public void onResume() {
     83         mResumed = true;
     84         Log.d(TAG, "onResume. Binding to service with intent " + mServiceIntent.toString());
     85         bindToService();
     86     }
     87 
     88     public void onPause() {
     89         mResumed = false;
     90         Log.d(TAG, "onPause, unbinding from service");
     91         unbindFromService();
     92     }
     93 
     94     public void setArt(Bitmap art) {
     95         mArt = art;
     96         if (mBinder != null) {
     97             try {
     98                 mBinder.setIcon(art);
     99             } catch (RemoteException e) {
    100             }
    101         }
    102     }
    103 
    104     public void play() {
    105         if (mTransportControls != null) {
    106             mTransportControls.play();
    107         }
    108     }
    109 
    110     public void pause() {
    111         if (mTransportControls != null) {
    112             mTransportControls.pause();
    113         }
    114     }
    115 
    116     public void setContent(String source) {
    117         RequestUtils.ContentBuilder bob = new RequestUtils.ContentBuilder();
    118         bob.setSource(source);
    119         try {
    120             mBinder.sendRequest(RequestUtils.ACTION_SET_CONTENT, bob.build(), null);
    121         } catch (RemoteException e) {
    122             Log.d(TAG, "setContent failed, service may have died.", e);
    123         }
    124     }
    125 
    126     public void setNextContent(String source) {
    127         RequestUtils.ContentBuilder bob = new RequestUtils.ContentBuilder();
    128         bob.setSource(source);
    129         try {
    130             mBinder.sendRequest(RequestUtils.ACTION_SET_NEXT_CONTENT, bob.build(), null);
    131         } catch (RemoteException e) {
    132             Log.d(TAG, "setNexctContent failed, service may have died.", e);
    133         }
    134     }
    135 
    136     public void showRoutePicker() {
    137         // TODO
    138     }
    139 
    140     public MediaSession.Token getSessionToken() {
    141         if (mBinder != null) {
    142             try {
    143                 return mBinder.getSessionToken();
    144             } catch (RemoteException e) {
    145             }
    146         }
    147         return null;
    148     }
    149 
    150     private void unbindFromService() {
    151         mContext.unbindService(mServiceConnection);
    152     }
    153 
    154     private void bindToService() {
    155         mContext.bindService(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
    156     }
    157 
    158     private ServiceConnection mServiceConnection = new ServiceConnection() {
    159         @Override
    160         public void onServiceDisconnected(ComponentName name) {
    161             if (mController != null) {
    162                 mController.unregisterCallback(mControllerCb);
    163             }
    164             mBinder = null;
    165             mController = null;
    166             mTransportControls = null;
    167             mContext.setMediaController(null);
    168             Log.d(TAG, "Disconnected from PlayerService");
    169 
    170             if (mListener != null) {
    171                 mListener.onConnectionStateChange(STATE_DISCONNECTED);
    172             }
    173         }
    174 
    175         @Override
    176         public void onServiceConnected(ComponentName name, IBinder service) {
    177             mBinder = IPlayerService.Stub.asInterface(service);
    178             Log.d(TAG, "service is " + service + " binder is " + mBinder);
    179             MediaSession.Token token;
    180             try {
    181                 token = mBinder.getSessionToken();
    182             } catch (RemoteException e) {
    183                 Log.e(TAG, "Error getting session", e);
    184                 return;
    185             }
    186             mController = new MediaController(mContext, token);
    187             mContext.setMediaController(mController);
    188             mController.registerCallback(mControllerCb, mHandler);
    189             mTransportControls = mController.getTransportControls();
    190             if (mArt != null) {
    191                 setArt(mArt);
    192             }
    193             Log.d(TAG, "Ready to use PlayerService");
    194 
    195             if (mListener != null) {
    196                 mListener.onConnectionStateChange(STATE_CONNECTED);
    197                 if (mTransportControls != null) {
    198                     mListener.onPlaybackStateChange(mController.getPlaybackState());
    199                 }
    200             }
    201         }
    202     };
    203 
    204     private class SessionCallback extends MediaController.Callback {
    205         @Override
    206         public void onPlaybackStateChanged(PlaybackState state) {
    207             if (state == null) {
    208                 return;
    209             }
    210             Log.d(TAG, "Received playback state change to state " + state.getState());
    211             if (mListener != null) {
    212                 mListener.onPlaybackStateChange(state);
    213             }
    214         }
    215 
    216         @Override
    217         public void onMetadataChanged(MediaMetadata metadata) {
    218             if (metadata == null) {
    219                 return;
    220             }
    221             Log.d(TAG, "Received metadata change, " + metadata.getDescription());
    222             if (mListener != null) {
    223                 mListener.onMetadataChange(metadata);
    224             }
    225         }
    226     }
    227 
    228     public interface Listener {
    229         public void onPlaybackStateChange(PlaybackState state);
    230         public void onMetadataChange(MediaMetadata metadata);
    231         public void onConnectionStateChange(int state);
    232     }
    233 
    234 }
    235