package com.sound.ampache.service;
/* Copyright (c) 2010 Jacob Alexander < haata@users.sf.net >
* Copyright (c) 2014 David Hrdina Nemecek <dejvino@gmail.com>
*
* +------------------------------------------------------------------------+
* | This program is free software; you can redistribute it and/or |
* | modify it under the terms of the GNU General Public License |
* | as published by the Free Software Foundation; either version 2 |
* | of the License, or (at your option) any later version. |
* | |
* | This program is distributed in the hope that it will be useful, |
* | but WITHOUT ANY WARRANTY; without even the implied warranty of |
* | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* | GNU General Public License for more details. |
* | |
* | You should have received a copy of the GNU General Public License |
* | along with this program; if not, write to the Free Software |
* | Foundation, Inc., 59 Temple Place - Suite 330, |
* | Boston, MA 02111-1307, USA. |
* +------------------------------------------------------------------------+
*/
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import java.util.HashSet;
import java.util.Set;
public class PlayerServiceClient
{
private static final String LOG_TAG = "Ampache_Amdroid_PlayerServiceClient";
private IPlayerService playerService;
private PlayerServiceConnection conn;
private Context mContext;
private Set<PlayerServiceStatusListener> statusListeners = new HashSet<PlayerServiceStatusListener>();
public PlayerServiceClient()
{
}
protected void finalize()
{
releaseService();
}
public void registerServiceStatusListener(PlayerServiceStatusListener listener)
{
Log.d(LOG_TAG, "Adding new service status listener: " + listener);
statusListeners.add(listener);
}
public void unregisterServiceStatusListener(PlayerServiceStatusListener listener)
{
Log.d(LOG_TAG, "Removing service status listener: " + listener);
statusListeners.remove(listener);
}
// **********************************************************************
// Client to Service Requests *******************************************
// **********************************************************************
public void initService(Context context)
{
if (conn == null) {
mContext = context;
conn = new PlayerServiceConnection();
Intent intent = new Intent();
intent.setClassName("com.sound.ampache", "com.sound.ampache.service.PlayerService");
try {
if (!mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE))
Log.d(LOG_TAG, "Failed: bindService()");
} catch (SecurityException exp) {
Log.d(LOG_TAG, "Failed (Security): bindService()");
}
Log.d(LOG_TAG, "bindService()");
// TODO Ready
} else {
// TODO Warn user that init binding failed
}
}
public void releaseService()
{
if (conn != null) {
mContext.unbindService(conn);
conn = null;
Log.d(LOG_TAG, "unbindService()");
} else {
// TODO Warn user that service was already unbound
}
}
public IPlayerService serviceInterface()
{
// Make sure to check for DeadObjectException when calling interface functions
if (conn != null) {
if (playerService != null) {
//Log.d( LOG_TAG, "Accessing PlayerService interface." );
return playerService;
}
Log.d(LOG_TAG, "Tried accessing PlayerService interface, but it's null...");
return null;
}
Log.d(LOG_TAG, "Tried accessing PlayerService interface, but connection does not exist...");
// TODO Warn user that the service is not bound/connected
return null;
}
class PlayerServiceConnection implements ServiceConnection
{
public void onServiceConnected(ComponentName className, IBinder boundService)
{
playerService = IPlayerService.Stub.asInterface((IBinder) boundService);
Log.d(LOG_TAG, "onServiceConnected");
// Send Messenger
try {
serviceInterface().registerMessenger(mMessenger);
} catch (RemoteException ex) {
Log.e(LOG_TAG, "Could not register Service Callback Messenger!! Very Bad!!");
}
// notify service status listeners
Message msg = new Message();
msg.what = PlayerService.MSG_SERVICE_CONNECTED;
try {
mMessenger.send(msg);
} catch (RemoteException e) {
Log.d(LOG_TAG, "Local listener seems dead.", e);
}
}
public void onServiceDisconnected(ComponentName className)
{
playerService = null;
Log.d(LOG_TAG, "onServiceDisconnected");
// notify service status listeners
Message msg = new Message();
msg.what = PlayerService.MSG_SERVICE_CONNECTED;
try {
mMessenger.send(msg);
} catch (RemoteException e) {
Log.d(LOG_TAG, "Local listener seems dead.", e);
}
}
}
// **********************************************************************
// Service to Client Messages *******************************************
// **********************************************************************
class IncomingHandler extends Handler
{
@Override
public void handleMessage(Message msg)
{
// handle (log) message
switch (msg.what) {
case PlayerService.MSG_SEEK_POSITION:
Log.d(LOG_TAG, "MSG_SEEK_POSITION: " + msg.arg1);
break;
case PlayerService.MSG_BUFFER_PERCENTAGE:
//Log.d( LOG_TAG, "MSG_BUFFER_PERCENTAGE: " + msg.arg1 );
break;
case PlayerService.MSG_NEW_MEDIA:
Log.d(LOG_TAG, "MSG_NEW_MEDIA");
break;
case PlayerService.MSG_PLAYLIST_INDEX:
Log.d(LOG_TAG, "MSG_PLAYLIST_INDEX: " + msg.arg1);
break;
case PlayerService.MSG_SHUFFLE_CHANGED:
Log.d(LOG_TAG, "MSG_SHUFFLE_CHANGED: " + msg.arg1 == "0" ? "on" : "off");
break;
case PlayerService.MSG_REPEAT_CHANGED:
Log.d(LOG_TAG, "MSG_REPEAT_CHANGED: " + msg.arg1 == "0" ? "on" : "off");
break;
case PlayerService.MSG_PLAY:
Log.d(LOG_TAG, "MSG_PLAY");
break;
case PlayerService.MSG_PAUSE:
Log.d(LOG_TAG, "MSG_PAUSE");
break;
case PlayerService.MSG_STOP:
Log.d(LOG_TAG, "MSG_STOP");
break;
case PlayerService.MSG_VIDEO_SIZE_CHANGED:
Log.d(LOG_TAG, "MSG_VIDEO_SIZE_CHANGED | Width: " + msg.arg1 + " | Height: " + msg.arg2);
break;
case PlayerService.MSG_PLAYLIST_CHANGED:
Log.d(LOG_TAG, "MSG_PLAYLIST_CHANGED: " + msg.arg1);
break;
case PlayerService.MSG_SERVICE_CONNECTED:
Log.d(LOG_TAG, "MSG_SERVICE_CONNECTED.");
break;
case PlayerService.MSG_SERVICE_DISCONNECTED:
Log.d(LOG_TAG, "MSG_SERVICE_CONNECTED.");
break;
case PlayerService.MSG_ERROR:
Log.d(LOG_TAG, "MSG_ERROR | What: " + msg.arg1 + " | Extra: " + msg.arg2);
break;
default:
super.handleMessage(msg);
break;
}
// pass message to status listeners
for (PlayerServiceStatusListener listener : statusListeners) {
switch (msg.what) {
case PlayerService.MSG_SEEK_POSITION:
listener.onSeek(msg.arg1);
break;
case PlayerService.MSG_BUFFER_PERCENTAGE:
listener.onBuffering(msg.arg1);
break;
case PlayerService.MSG_NEW_MEDIA:
listener.onNewMedia();
break;
case PlayerService.MSG_PLAYLIST_INDEX:
listener.onPlaylistIndexChanged(msg.arg1);
break;
case PlayerService.MSG_SHUFFLE_CHANGED:
listener.onShuffledChanged(msg.arg1);
break;
case PlayerService.MSG_REPEAT_CHANGED:
listener.onRepeatChanged(msg.arg1);
break;
case PlayerService.MSG_PLAY:
listener.onPlay();
break;
case PlayerService.MSG_PAUSE:
listener.onPause();
break;
case PlayerService.MSG_STOP:
listener.onStop();
break;
case PlayerService.MSG_VIDEO_SIZE_CHANGED:
listener.onVideoSizeChanged(msg.arg1, msg.arg2);
break;
case PlayerService.MSG_PLAYLIST_CHANGED:
listener.onPlaylistChanged(msg.arg1);
break;
case PlayerService.MSG_SERVICE_CONNECTED:
listener.onServiceConnected();
break;
case PlayerService.MSG_SERVICE_DISCONNECTED:
listener.onServiceDisconnected();
break;
case PlayerService.MSG_ERROR:
listener.onError(msg.arg1, msg.arg2);
break;
}
}
}
}
// Target for the incoming messages
final Messenger mMessenger = new Messenger(new IncomingHandler());
}