/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.onemedia;
import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.util.Log;
import com.android.onemedia.playback.RequestUtils;
public class PlayerController {
private static final String TAG = "PlayerController";
public static final int STATE_DISCONNECTED = 0;
public static final int STATE_CONNECTED = 1;
protected MediaController mController;
protected IPlayerService mBinder;
protected MediaController.TransportControls mTransportControls;
private final Intent mServiceIntent;
private Activity mContext;
private Listener mListener;
private SessionCallback mControllerCb;
private MediaSessionManager mManager;
private Handler mHandler = new Handler();
private boolean mResumed;
private Bitmap mArt;
public PlayerController(Activity context, Intent serviceIntent) {
mContext = context;
if (serviceIntent == null) {
mServiceIntent = new Intent(mContext, PlayerService.class);
} else {
mServiceIntent = serviceIntent;
}
mControllerCb = new SessionCallback();
mManager = (MediaSessionManager) context
.getSystemService(Context.MEDIA_SESSION_SERVICE);
mResumed = false;
}
public void setListener(Listener listener) {
mListener = listener;
Log.d(TAG, "Listener set to " + listener + " session is " + mController);
if (mListener != null) {
mHandler = new Handler();
mListener.onConnectionStateChange(
mController == null ? STATE_DISCONNECTED : STATE_CONNECTED);
}
}
public void onResume() {
mResumed = true;
Log.d(TAG, "onResume. Binding to service with intent " + mServiceIntent.toString());
bindToService();
}
public void onPause() {
mResumed = false;
Log.d(TAG, "onPause, unbinding from service");
unbindFromService();
}
public void setArt(Bitmap art) {
mArt = art;
if (mBinder != null) {
try {
mBinder.setIcon(art);
} catch (RemoteException e) {
}
}
}
public void play() {
if (mTransportControls != null) {
mTransportControls.play();
}
}
public void pause() {
if (mTransportControls != null) {
mTransportControls.pause();
}
}
public void setContent(String source) {
RequestUtils.ContentBuilder bob = new RequestUtils.ContentBuilder();
bob.setSource(source);
try {
mBinder.sendRequest(RequestUtils.ACTION_SET_CONTENT, bob.build(), null);
} catch (RemoteException e) {
Log.d(TAG, "setContent failed, service may have died.", e);
}
}
public void setNextContent(String source) {
RequestUtils.ContentBuilder bob = new RequestUtils.ContentBuilder();
bob.setSource(source);
try {
mBinder.sendRequest(RequestUtils.ACTION_SET_NEXT_CONTENT, bob.build(), null);
} catch (RemoteException e) {
Log.d(TAG, "setNexctContent failed, service may have died.", e);
}
}
public void showRoutePicker() {
// TODO
}
public MediaSession.Token getSessionToken() {
if (mBinder != null) {
try {
return mBinder.getSessionToken();
} catch (RemoteException e) {
}
}
return null;
}
private void unbindFromService() {
mContext.unbindService(mServiceConnection);
}
private void bindToService() {
mContext.bindService(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
if (mController != null) {
mController.unregisterCallback(mControllerCb);
}
mBinder = null;
mController = null;
mTransportControls = null;
mContext.setMediaController(null);
Log.d(TAG, "Disconnected from PlayerService");
if (mListener != null) {
mListener.onConnectionStateChange(STATE_DISCONNECTED);
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBinder = IPlayerService.Stub.asInterface(service);
Log.d(TAG, "service is " + service + " binder is " + mBinder);
MediaSession.Token token;
try {
token = mBinder.getSessionToken();
} catch (RemoteException e) {
Log.e(TAG, "Error getting session", e);
return;
}
mController = new MediaController(mContext, token);
mContext.setMediaController(mController);
mController.registerCallback(mControllerCb, mHandler);
mTransportControls = mController.getTransportControls();
if (mArt != null) {
setArt(mArt);
}
Log.d(TAG, "Ready to use PlayerService");
if (mListener != null) {
mListener.onConnectionStateChange(STATE_CONNECTED);
if (mTransportControls != null) {
mListener.onPlaybackStateChange(mController.getPlaybackState());
}
}
}
};
private class SessionCallback extends MediaController.Callback {
@Override
public void onPlaybackStateChanged(PlaybackState state) {
if (state == null) {
return;
}
Log.d(TAG, "Received playback state change to state " + state.getState());
if (mListener != null) {
mListener.onPlaybackStateChange(state);
}
}
@Override
public void onMetadataChanged(MediaMetadata metadata) {
if (metadata == null) {
return;
}
Log.d(TAG, "Received metadata change, " + metadata.getDescription());
if (mListener != null) {
mListener.onMetadataChange(metadata);
}
}
}
public interface Listener {
public void onPlaybackStateChange(PlaybackState state);
public void onMetadataChange(MediaMetadata metadata);
public void onConnectionStateChange(int state);
}
}