package com.rubika.aotalk.service;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.analytics.tracking.android.EasyTracker;
import com.google.analytics.tracking.android.Tracker;
import com.rubika.aotalk.AOTalk;
import com.rubika.aotalk.database.DatabaseHandler;
import com.rubika.aotalk.item.Account;
import com.rubika.aotalk.item.Channel;
import com.rubika.aotalk.item.ChatMessage;
import com.rubika.aotalk.item.Friend;
import com.rubika.aotalk.music.AudioFocusHelper;
import com.rubika.aotalk.music.MusicFocusable;
import com.rubika.aotalk.music.MusicIntentReceiver;
import com.rubika.aotalk.util.Logging;
import com.rubika.aotalk.util.Statics;
import com.rubika.aotalk.R;
import com.spoledge.aacdecoder.AACPlayer;
import com.spoledge.aacdecoder.PlayerCallback;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.Html;
import ao.chat.ChatClient;
import ao.misc.Convert;
import ao.misc.NameFormat;
import ao.protocol.CharacterInfo;
import ao.protocol.Client;
import ao.protocol.Client.ClientState;
import ao.protocol.ClientListener;
import ao.protocol.ClientStateException;
import ao.protocol.DimensionAddress;
import ao.protocol.packets.Packet;
import ao.protocol.packets.bi.ChannelMessagePacket;
import ao.protocol.packets.bi.FriendUpdatePacket;
import ao.protocol.packets.bi.PrivateChannelInvitePacket;
import ao.protocol.packets.bi.PrivateChannelKickPacket;
import ao.protocol.packets.bi.PrivateChannelMessagePacket;
import ao.protocol.packets.bi.PrivateMessagePacket;
import ao.protocol.packets.toclient.BroadcastMessagePacket;
import ao.protocol.packets.toclient.ChannelUpdatePacket;
import ao.protocol.packets.toclient.CharacterListPacket;
import ao.protocol.packets.toclient.LoginErrorPacket;
import ao.protocol.packets.toclient.PrivateChannelCharacterJoinPacket;
import ao.protocol.packets.toclient.PrivateChannelCharacterLeavePacket;
import ao.protocol.packets.toclient.SystemMessagePacket;
import ao.protocol.packets.toclient.VicinityMessagePacket;
public class ClientService extends Service implements MusicFocusable {
protected static final String APP_TAG = "--> The Leet :: ClientService";
public static int NOTIFICATION = 1;
public static int NOTIFICATION_TW = 2;
public static int NOTIFICATION_OP = 3;
private static NotificationManager notificationManager;
private static NotificationCompat.Builder notificationBuilder;
public static final String ACTION_TOGGLE_PLAYBACK = "com.rubika.aotalk.action.TOGGLE_PLAYBACK";
public static final String ACTION_PLAY = "com.rubika.aotalk.action.PLAY";
public static final String ACTION_STOP = "com.rubika.aotalk.action.STOP";
private CharacterInfo currentCharacter;
public String currentTargetChannel = "";
public String currentTargetCharacter = "";
public String currentShowChannel = Statics.CHANNEL_MAIN;
private int notificationCounter;
public ChatClient chatClient;
private Account currentAccount;
private SharedPreferences settings;
public SharedPreferences.Editor editor;
public boolean manualLogin = false;
public boolean accountFailed = false;
private int reconnectAttempts = 0;
private long lastReconnectAttempt = 0;
private String PLAYURL = "";
private boolean isPlaying = false;
private boolean retryOnFailure = true;
private boolean stoppedByCall = false;
private TelephonyManager phoneManager;
private PhoneStateListener phoneListener;
private AACPlayer aacPlayer;
private AudioManager audioManager;
private String currentTrack = null;
public List<String> channelsMuted = new ArrayList<String>();
private Messenger messenger = new Messenger(new MessageHandler(this));
public ArrayList<Messenger> clients = new ArrayList<Messenger>();
// public static DatabaseHandler DatabaseHandler.getInstance(context);
private Handler AOVoiceHandler = new Handler();
private long AOVoiceUpdateTime = 60000;
private boolean AOVoiceIsUpdating = false;
public List<Channel> channelList = new ArrayList<Channel>();
public List<Channel> privateList = new ArrayList<Channel>();
public List<Channel> invitationList = new ArrayList<Channel>();
private List<Friend> friendList = new ArrayList<Friend>();
private static Context context;
private Tracker tracker;
private MediaPlayer mediaPlayer;
private RemoteControlClientCompat remoteControlClient;
private ComponentName mediaButtonReceiverComponent;
private static Handler faceHandler = new FaceHandler();
@Override
public IBinder onBind(Intent arg0) {
return messenger.getBinder();
}
static class FaceHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Bitmap face = (Bitmap) msg.obj;
setNotificationFace(face);
}
};
static class MessageHandler extends Handler {
private final WeakReference<ClientService> clientService;
public MessageHandler(ClientService s) {
clientService = new WeakReference<ClientService>(s);
}
@SuppressWarnings("unchecked")
@Override
public void handleMessage(Message message) {
if (message != null) {
switch (message.what) {
case Statics.MESSAGE_PLAYER_PLAY:
clientService.get().play();
break;
case Statics.MESSAGE_PLAYER_STOP:
clientService.get().stop();
break;
case Statics.MESSAGE_PRIVATE_CHANNEL_JOIN:
Channel invitationJoin = (Channel) message.obj;
clientService.get().privateList.add(invitationJoin);
int removeThis = -1;
for (int i = 0; i < clientService.get().invitationList
.size(); i++) {
if (clientService.get().invitationList.get(i).getID() == invitationJoin
.getID()) {
removeThis = i;
}
}
if (removeThis >= 0) {
clientService.get().invitationList.remove(removeThis);
}
try {
clientService.get().chatClient
.acceptInvite(invitationJoin.getID());
} catch (IOException e) {
Logging.log(APP_TAG, e.getMessage());
} catch (ClientStateException e) {
Logging.log(APP_TAG, e.getMessage());
}
Message joined = Message.obtain(null,
Statics.MESSAGE_PRIVATE_CHANNEL);
joined.obj = clientService.get().privateList;
clientService.get().message(joined);
break;
case Statics.MESSAGE_PRIVATE_CHANNEL_DENY:
Channel invitationLeave = (Channel) message.obj;
clientService.get().privateList.remove(invitationLeave);
removeThis = -1;
for (int i = 0; i < clientService.get().invitationList
.size(); i++) {
if (clientService.get().invitationList.get(i).getID() == invitationLeave
.getID()) {
removeThis = i;
}
}
if (removeThis >= 0) {
clientService.get().invitationList.remove(removeThis);
}
try {
clientService.get().chatClient
.denyInvite(invitationLeave.getID());
} catch (IOException e) {
Logging.log(APP_TAG, e.getMessage());
} catch (ClientStateException e) {
Logging.log(APP_TAG, e.getMessage());
}
break;
case Statics.MESSAGE_CLIENT_REGISTER:
clientService.get().clientRegistered(message);
Logging.log(APP_TAG,
"Clients registered: "
+ clientService.get().clients.size());
if (clientService.get().clients.size() > 0) {
clientService.get().AOVoiceHandler
.removeCallbacks(clientService.get().AOVoiceUpdateTask);
clientService.get().AOVoiceHandler.post(clientService
.get().AOVoiceUpdateTask);
} else {
clientService.get().AOVoiceHandler
.removeCallbacks(clientService.get().AOVoiceUpdateTask);
}
break;
case Statics.MESSAGE_CLIENT_UNREGISTER:
clientService.get().clients.remove(message.replyTo);
if (clientService.get().clients.size() == 0) {
clientService.get().AOVoiceHandler
.removeCallbacks(clientService.get().AOVoiceUpdateTask);
}
break;
case Statics.MESSAGE_CONNECT:
clientService.get().editor.putInt("lastAccount",
((Account) message.obj).getID());
clientService.get().editor.commit();
clientService.get().accountFailed = false;
clientService.get().manualLogin = true;
clientService.get().connect((Account) message.obj);
break;
case Statics.MESSAGE_SET_CHANNEL:
clientService.get().currentTargetChannel = (String) message.obj;
clientService.get().editor.putString("currentChannel",
clientService.get().currentTargetChannel);
clientService.get().editor.commit();
break;
case Statics.MESSAGE_SET_SHOW:
clientService.get().currentShowChannel = (String) message.obj;
break;
case Statics.MESSAGE_SET_CHARACTER:
if (clientService.get().chatClient != null
&& message.obj != null) {
clientService.get().currentTargetCharacter = (String) message.obj;
clientService.get().editor.putString(
"currentCharacter",
clientService.get().currentTargetCharacter);
clientService.get().editor.commit();
}
break;
case Statics.MESSAGE_SEND:
clientService.get().sendMessage((ChatMessage) message.obj,
message.arg1);
break;
case Statics.MESSAGE_STATUS:
if (clientService.get().chatClient.getState() == Client.ClientState.LOGGED_IN) {
clientService.get().message(
Message.obtain(null,
Statics.MESSAGE_IS_CONNECTED, 0, 0));
} else {
clientService.get().message(
Message.obtain(null,
Statics.MESSAGE_IS_DISCONNECTED, 0, 0));
}
break;
case Statics.MESSAGE_DISCONNECT:
clientService.get().editor.putBoolean("reconnect", false);
clientService.get().editor.putInt("lastAccount", 0);
clientService.get().editor.commit();
clientService.get().manualLogin = true;
if (clientService.get().chatClient.getState() != Client.ClientState.DISCONNECTED) {
try {
clientService.get().chatClient.disconnect();
} catch (IOException e) {
Logging.log(APP_TAG, e.getMessage());
}
}
break;
case Statics.MESSAGE_CHARACTER:
if (clientService.get().settings.getBoolean(
"autoReconnect", true)) {
clientService.get().editor
.putBoolean("reconnect", true);
} else {
clientService.get().editor.putBoolean("reconnect",
false);
}
clientService.get().editor.commit();
if (message.obj != null) {
clientService.get().login((CharacterInfo) message.obj);
}
break;
case Statics.MESSAGE_FRIEND_ADD:
String nameAdd = (String) message.obj;
if (!nameAdd.equals("")) {
clientService.get().addFriend(nameAdd);
}
break;
case Statics.MESSAGE_FRIEND_REMOVE:
String nameRemove = (String) message.obj;
if (!nameRemove.equals("")) {
clientService.get().removeFriend(nameRemove);
}
break;
case Statics.MESSAGE_MUTED_CHANNELS:
clientService.get().channelList = (List<Channel>) message.obj;
clientService.get().channelsMuted.clear();
String muted = "";
for (Channel channel : clientService.get().channelList) {
if (channel.getMuted()) {
clientService.get().channelsMuted.add(channel
.getName());
if (muted.length() > 0) {
muted += ",";
}
muted += channel.getName();
}
}
clientService.get().editor
.putString("mutedChannels", muted);
clientService.get().editor.commit();
Message msg = Message.obtain(null, Statics.MESSAGE_CHANNEL);
msg.obj = clientService.get().channelList;
clientService.get().message(msg);
break;
default:
super.handleMessage(message);
}
}
}
}
public static Context getContext() {
return context;
}
private void playConnectionSound(int sound) {
if (settings.getBoolean("enableSounds", false)) {
Logging.log(APP_TAG, "Playing connection sound");
mediaPlayer = MediaPlayer.create(context, sound);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Logging.log(APP_TAG, "Releaseing MediaPlayer");
mediaPlayer.release();
}
});
mediaPlayer.start();
}
}
private AudioFocusHelper mAudioFocusHelper = null;
private AudioFocus mAudioFocus = AudioFocus.NoFocusNoDuck;
private enum AudioFocus {
NoFocusNoDuck, // we don't have audio focus, and can't duck
NoFocusCanDuck, // we don't have focus, but can play at a low volume
// ("ducking")
Focused // we have full audio focus
}
public enum PlayerState {
Started, Stopped, Working
}
@Override
public void onCreate() {
Logging.log(APP_TAG, "onCreate");
/*
* IntentFilter filter = new IntentFilter();
* filter.addAction(Statics.BROADCAST_KEY_PLAY);
* filter.addAction(Statics.BROADCAST_KEY_STOP);
*
* receiver = new BroadcastReceiver() {
*
* @Override public void onReceive(Context context, Intent intent) { if
* (intent.getAction().equals(Statics.BROADCAST_KEY_PLAY)) { if
* (!isPlaying) { play(); } } else if
* (intent.getAction().equals(Statics.BROADCAST_KEY_STOP)) { if
* (isPlaying) { stop(); } } } };
*
* registerReceiver(receiver, filter);
*/
settings = PreferenceManager.getDefaultSharedPreferences(this);
editor = settings.edit();
EasyTracker.getInstance().setContext(getApplicationContext());
tracker = EasyTracker.getTracker();
editor.putString("lastCharacterName", "");
editor.commit();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
//DashClockExtender.getInstance().changeMessage();
}
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
mediaButtonReceiverComponent = new ComponentName(this,
MusicIntentReceiver.class);
if (android.os.Build.VERSION.SDK_INT >= 8)
mAudioFocusHelper = new AudioFocusHelper(getApplicationContext(),
this);
else
mAudioFocus = AudioFocus.Focused; // no focus feature, so we always
// "have" audio focus
if (remoteControlClient == null) {
Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
intent.setComponent(mediaButtonReceiverComponent);
remoteControlClient = new RemoteControlClientCompat(
PendingIntent.getBroadcast(this, 0, intent, 0));
// remoteControlClient.setTransportControlFlags(RemoteControlClient.FLAG_KEY_MEDIA_PLAY
// | RemoteControlClient.FLAG_KEY_MEDIA_STOP);
}
registerRemoteControl();
currentTargetChannel = settings.getString("currentChannel", "");
currentTargetCharacter = settings.getString("currentCharacter", "");
context = this.getApplicationContext();
Intent notificationIntent = new Intent(this, AOTalk.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
// PendingIntent pendingPlayIntent = PendingIntent.getBroadcast(this, 1,
// new Intent(Statics.BROADCAST_KEY_PLAY), 0);
// PendingIntent pendingStopIntent = PendingIntent.getBroadcast(this, 1,
// new Intent(Statics.BROADCAST_KEY_STOP), 0);
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationBuilder = new Builder(this);
notificationBuilder.setContentIntent(PendingIntent.getActivity(this, 0,
notificationIntent, 0));
notificationBuilder.setContentTitle(getString(R.string.app_name));
notificationBuilder.setContentText(String.format(
getString(R.string.is_running), getString(R.string.app_name)));
notificationBuilder.setTicker(null);
notificationBuilder.setOngoing(true);
notificationBuilder.setSmallIcon(R.drawable.ic_notification);
notificationBuilder.setNumber(0);
notificationBuilder.setLargeIcon(((BitmapDrawable) getResources()
.getDrawable(R.drawable.leet)).getBitmap());
// notificationBuilder.setStyle(new
// NotificationCompat.InboxStyle().setSummaryText(getString(R.string.app_name)
// + " is running").addLine("test"));
// notificationBuilder.setStyle(new
// NotificationCompat.BigTextStyle().bigText(getString(R.string.app_name)));
// notificationBuilder.setStyle(new
// NotificationCompat.BigPictureStyle().bigPicture(((BitmapDrawable)getResources().getDrawable(R.drawable.leet)).getBitmap()));
// notificationBuilder.setPriority(Notification.PRIORITY_LOW);
// notificationBuilder.addAction(R.drawable.ic_menu_play, "Play",
// pendingPlayIntent);
// notificationBuilder.addAction(R.drawable.ic_menu_stop, "Stop",
// pendingStopIntent);
notificationManager.cancel(NOTIFICATION);
// DatabaseHandler.getInstance(context) =
// DatabaseHandler.getInstance(this);
String muted = settings.getString("mutedChannels", "");
if (muted.length() > 0) {
String[] mutedChannels = muted.split(",");
for (int i = 0; i < mutedChannels.length; i++) {
channelsMuted.add(mutedChannels[i]);
}
}
chatClient = new ChatClient();
chatClient.addListener(new ClientListener() {
@Override
public void connected(Client bot) {
Logging.log(APP_TAG, "Connected");
authenticate();
}
@Override
public void authenticated(Client bot) {
Logging.log(APP_TAG, "Authenticated");
}
@Override
public void loggedIn(Client bot) {
Logging.log(APP_TAG, "Logged in");
startForeground(NOTIFICATION, notificationBuilder.build());
manualLogin = false;
chatClient.start();
tracker.sendEvent("Connection", "Connected",
currentCharacter.getName(), 0L);
}
@Override
public void started(Client bot) {
Logging.log(APP_TAG, "Started");
startForeground(NOTIFICATION, notificationBuilder.build());
setNotification(String.format(
getString(R.string.character_is_online),
currentCharacter.getName()), String.format(
getString(R.string.character_logged_in),
currentCharacter.getName()), true, false);
new Thread(new Runnable() {
public void run() {
Message msg = Message.obtain();
msg.what = 0;
msg.obj = ServiceTools.getUserImage(
currentCharacter.getName(), context);
faceHandler.sendMessage(msg);
}
}).start();
List<Object> returnData = new ArrayList<Object>();
returnData.add(currentTargetChannel);
returnData.add(currentTargetCharacter);
returnData.add(currentCharacter.getName());
returnData.add(currentShowChannel);
Message msg = Message.obtain();
msg.what = Statics.MESSAGE_STARTED;
msg.arg1 = currentCharacter.getID();
if (currentAccount != null) {
msg.arg2 = DimensionAddress.RK.getID();
} else {
msg.arg2 = 0;
}
msg.obj = returnData;
message(msg);
editor.putInt("lastCharacter", currentCharacter.getID());
editor.putString("lastCharacterName", currentCharacter.getName());
editor.commit();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
//DashClockExtender.getInstance().changeMessage();
}
playConnectionSound(R.raw.grid_in);
}
@Override
public void disconnected(Client bot) {
Logging.log(APP_TAG, "Disconnected");
if (currentCharacter != null) {
setNotification(getString(R.string.disconnected),
getString(R.string.disconnected), false, false);
DatabaseHandler.getInstance(context).addPost(
"Disconnected", Statics.CHANNEL_APPLICATION,
Statics.CHANNEL_APPLICATION,
currentCharacter.getID());
tracker.sendEvent("Connection", "Disconnected",
currentCharacter.getName(), 0L);
}
message(Message.obtain(null, Statics.MESSAGE_DISCONNECTED,
(settings.getBoolean("reconnect", true) ? 1 : 0), 0));
friendList.clear();
channelList.clear();
invitationList.clear();
privateList.clear();
Logging.log(APP_TAG, "accountFailed: " + accountFailed);
if (!settings.getBoolean("reconnect", true) || accountFailed) {
Logging.log(APP_TAG, "Skipping automatic reconnect");
currentAccount = null;
currentCharacter = null;
} else {
Logging.log(APP_TAG, "Automatic reconnect (" + reconnectAttempts + ")");
accountFailed = false;
if (lastReconnectAttempt + 2500 >= System
.currentTimeMillis()) {
reconnectAttempts++;
} else {
reconnectAttempts = 0;
}
lastReconnectAttempt = System.currentTimeMillis();
if (reconnectAttempts < 5) {
connect(currentAccount);
} else {
Logging.log(APP_TAG, "Too many automatic reconnects");
currentAccount = null;
currentCharacter = null;
}
}
if (!isPlaying) {
stopForeground(true);
}
editor.putString("lastCharacterName", "");
editor.commit();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
//DashClockExtender.getInstance().changeMessage();
}
playConnectionSound(R.raw.grid_out);
}
@Override
public void exception(Client bot, Exception e) {
Logging.log(APP_TAG, e.getMessage());
message(Message
.obtain(null, Statics.MESSAGE_CLIENT_ERROR, 0, 0));
}
@Override
public void packet(Client bot, Packet packet) {
Message message = null;
if (packet == null) {
return;
}
// Character list packet
if (packet.getType() == CharacterListPacket.TYPE) {
message = handleCharacterListPacket(packet);
}
// Log in failed
if (packet.getType() == LoginErrorPacket.TYPE) {
message = handleLoginErrorPacket(packet);
}
// Private message
if (packet.getType() == PrivateMessagePacket.TYPE
&& packet.getDirection() == Packet.Direction.TO_CLIENT) {
message = handlePrivateMessagePacket(packet);
}
// Chat group message
if (packet.getType() == ChannelMessagePacket.TYPE
&& packet.getDirection() == Packet.Direction.TO_CLIENT) {
message = handleChannelMessagePacket(packet);
}
// System message
if (packet.getType() == SystemMessagePacket.TYPE
&& packet.getDirection() == Packet.Direction.TO_CLIENT) {
message = handleSystemMessagePacket(packet);
}
// Broadcast message
if (packet.getType() == BroadcastMessagePacket.TYPE
&& packet.getDirection() == Packet.Direction.TO_CLIENT) {
message = handleBroadcastMessagePacket(packet);
}
// Vicinity notice
if (packet.getType() == VicinityMessagePacket.TYPE) {
message = handleVicinityMessagePacket(packet);
}
// Friend update
if (packet.getType() == FriendUpdatePacket.TYPE) {
message = handleFriendUpdatePacket(packet);
}
// Group announcement
if (packet.getType() == ChannelUpdatePacket.TYPE) {
message = handleChannelUpdatePacket(packet);
}
// Private group invitation
if (packet.getType() == PrivateChannelInvitePacket.TYPE) {
message = handlePrivateChannelInvitePacket(packet);
}
// Private group join
if (packet.getType() == PrivateChannelCharacterJoinPacket.TYPE) {
message = handlePrivateChannelCharacterJoinPacket(packet);
}
// Private group kick
if (packet.getType() == PrivateChannelKickPacket.TYPE) {
message = handlePrivateChannelKickPacket(packet);
}
// Private group leave
if (packet.getType() == PrivateChannelCharacterLeavePacket.TYPE) {
message = handlePrivateChannelCharacterLeavePacket(packet);
}
// Private group message
if (packet.getType() == PrivateChannelMessagePacket.TYPE) {
message = handlePrivateChannelMessagePacket(packet);
}
// Send message if one exists
if (message != null) {
message(message);
}
}
});
audioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
aacPlayer = new AACPlayer();
aacPlayer
.setAudioBufferCapacityMs(AACPlayer.DEFAULT_AUDIO_BUFFER_CAPACITY_MS);
aacPlayer
.setDecodeBufferCapacityMs(AACPlayer.DEFAULT_DECODE_BUFFER_CAPACITY_MS);
PlayerCallback playerCallback = new PlayerCallback() {
@Override
public void playerStarted() {
Logging.log(APP_TAG, "playerStarted");
editor.putBoolean("restartPlayer", true);
editor.commit();
// audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
isPlaying = true;
setNotification(getString(R.string.gsp_is_playing), null,
false, false);
// setRemoteControlMetadata(((BitmapDrawable)getResources().getDrawable(R.drawable.leet)).getBitmap(),
// "title", "artist");
if (chatClient.getState() == ChatClient.ClientState.DISCONNECTED) {
startForeground(NOTIFICATION, notificationBuilder.build());
}
Message message = Message.obtain(null,
Statics.MESSAGE_PLAYER_STARTED, 0, 0);
message(message);
// setRemoteControlPlaying();
}
@Override
public void playerStopped(int perf) {
Logging.log(APP_TAG, "playerStopped");
editor.putBoolean("restartPlayer", false);
editor.commit();
// audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
currentTrack = null;
isPlaying = false;
setNotification(getString(R.string.gsp_is_playing), null,
false, false);
if (chatClient.getState() == ChatClient.ClientState.DISCONNECTED) {
stopForeground(true);
}
Message message = Message.obtain(null,
Statics.MESSAGE_PLAYER_STOPPED, 0, 0);
message(message);
// setRemoteControlStopped();
giveUpAudioFocus();
}
@Override
public void playerException(Throwable t) {
Logging.log(APP_TAG, "playerException: " + t.getMessage());
editor.putBoolean("restartPlayer", false);
editor.commit();
if (retryOnFailure) {
aacPlayer.stop();
play();
}
}
@Override
public void playerPCMFeedBuffer(boolean isPlaying, int bufSizeMs,
int bufCapacityMs) {
}
@Override
public void playerMetadata(String key, String value) {
if (key != null) {
if (key.equals("StreamTitle")) {
currentTrack = value;
setNotificationPlayerTrack(currentTrack);
List<Object> playerData = new ArrayList<Object>();
playerData.add(isPlaying);
playerData.add(currentTrack);
Message message = Message.obtain(null,
Statics.MESSAGE_PLAYER_TRACK, 0, 0);
message.obj = playerData;
message(message);
} else if (key.equals("icy-name")) {
currentTrack = value;
setNotificationPlayerTrack(currentTrack);
List<Object> playerData = new ArrayList<Object>();
playerData.add(isPlaying);
playerData.add(currentTrack);
Message message = Message.obtain(null,
Statics.MESSAGE_PLAYER_TRACK, 0, 0);
message.obj = playerData;
message(message);
}
}
}
};
aacPlayer.setPlayerCallback(playerCallback);
phoneManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
// Create a PhoneStateListener to watch for off hook and idle events
phoneListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:
// phone going off hook or ringing, pause the player
if (isPlaying) {
stop();
stoppedByCall = true;
}
break;
case TelephonyManager.CALL_STATE_IDLE:
// phone idle
if (stoppedByCall) {
play();
stoppedByCall = false;
}
break;
}
}
};
phoneManager
.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
if (settings.getBoolean("reconnect", true) && !accountFailed) {
Account account = DatabaseHandler.getInstance(context).getAccount(
settings.getInt("lastAccount", 0));
connect(account);
}
if (settings.getBoolean("restartPlayer", false)) {
play();
}
}
@Override
public void onDestroy() {
super.onDestroy();
giveUpAudioFocus();
stopForeground(true);
unregisterRemoteControl();
}
private Message handleCharacterListPacket(Packet packet) {
Logging.log(APP_TAG, "Got CharacterListPacket");
Message msg = null;
CharacterInfo[] cl = ((CharacterListPacket) packet).getCharacters();
if (settings.getBoolean("reconnect", true) && !manualLogin) {
if (currentCharacter != null) {
login(currentCharacter);
} else {
if (settings.getInt("lastCharacter", 0) != 0) {
CharacterInfo cu = null;
for (CharacterInfo c : cl) {
Logging.log(APP_TAG, "user: " + c.getName()
+ ", status: " + c.getOnline());
if (c.getID() == settings.getInt("lastCharacter", 0)) {
cu = c;
}
}
if (cu != null) {
login(cu);
}
}
}
manualLogin = false;
} else {
msg = Message.obtain(null, Statics.MESSAGE_CHARACTERS);
msg.obj = (CharacterListPacket) packet;
}
return msg;
}
private Message handleLoginErrorPacket(Packet packet) {
Logging.log(APP_TAG, "Got LoginErrorPacket");
accountFailed = true;
return Message.obtain(null, Statics.MESSAGE_LOGIN_ERROR);
}
private Message handlePrivateMessagePacket(Packet packet) {
Logging.log(APP_TAG, "Got PrivateMessagePacket");
Message msg = null;
boolean skipThis = false;
boolean treatAsChannel = false;
String channel = "";
Pattern pattern;
Matcher matcher;
// Check if messages from Dnet and Neutnet should be ignored
if (settings.getBoolean("muteDnet", false)) {
pattern = Pattern
.compile("dnet([0-9].*)", Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(chatClient.getCharTable().getName(
((PrivateMessagePacket) packet).getCharID()));
if (matcher.matches() && settings.getBoolean("muteDnet", false)) {
Logging.log(APP_TAG, "Ignoring message from Dnet");
skipThis = true;
}
pattern = Pattern.compile("neutnet([0-9].*)",
Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(chatClient.getCharTable().getName(
((PrivateMessagePacket) packet).getCharID()));
if (matcher.matches() && settings.getBoolean("muteDnet", false)) {
Logging.log(APP_TAG, "Ignoring message from Neutnet");
skipThis = true;
}
}
// Check if messages from Dnet and Neutnet should be treated as channels
if (settings.getBoolean("dnetAsChannel", false)) {
pattern = Pattern
.compile("dnet([0-9].*)", Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(chatClient.getCharTable().getName(
((PrivateMessagePacket) packet).getCharID()));
if (matcher.matches()) {
treatAsChannel = true;
channel = Statics.CHANNEL_DNET;
}
pattern = Pattern.compile("neutnet([0-9].*)",
Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(chatClient.getCharTable().getName(
((PrivateMessagePacket) packet).getCharID()));
if (matcher.matches()) {
treatAsChannel = true;
channel = Statics.CHANNEL_NEUTNET;
}
}
if (!skipThis) {
if (!treatAsChannel) {
DatabaseHandler.getInstance(context).addPost(
((PrivateMessagePacket) packet).display(
chatClient.getCharTable(),
chatClient.getGroupTable()),
chatClient.getCharTable().getName(
((PrivateMessagePacket) packet).getCharID()),
Statics.CHANNEL_PM, currentCharacter.getID());
if (clients.size() == 0
&& settings.getBoolean("notificationEnabled", true)) {
notificationCounter++;
setNotification(
null,
chatClient.getCharTable()
.getName(
((PrivateMessagePacket) packet)
.getCharID())
+ ": "
+ Html.fromHtml(
((PrivateMessagePacket) packet)
.getMessage()).toString(),
true, true);
}
msg = Message.obtain(null, Statics.MESSAGE_UPDATE, 0, 0);
} else {
Logging.log(APP_TAG, String.format(
"Treating message as channel (%s)", channel));
String from = "";
String message = "";
pattern = Pattern.compile("^(.*)\\[(.*?)\\]</font>$",
Pattern.CASE_INSENSITIVE);
matcher = pattern.matcher(((PrivateMessagePacket) packet)
.getMessage());
if (matcher.matches()) {
from = Html.fromHtml(matcher.group(2)).toString();
message = matcher.group(1);
message = message.replaceAll(
"^<font color=#(?:[a-zA-Z0-9]{6})>", "");
message = message.replaceAll("</font>$", "");
message = "[" + channel + "] " + from + ": " + message;
if (!channelsMuted.contains(channel)) {
DatabaseHandler.getInstance(context).addPost(message,
from, channel, currentCharacter.getID());
msg = Message
.obtain(null, Statics.MESSAGE_UPDATE, 0, 0);
}
}
}
}
return msg;
}
private Message handleChannelMessagePacket(Packet packet) {
Logging.log(APP_TAG, "Got ChannelMessagePacket");
Message msg = null;
if (!channelsMuted.contains(chatClient.getGroupTable().getName(
((ChannelMessagePacket) packet).getGroupID()))) {
DatabaseHandler.getInstance(context).addPost(
((ChannelMessagePacket) packet).display(
chatClient.getCharTable(),
chatClient.getGroupTable()),
chatClient.getCharTable().getName(
((ChannelMessagePacket) packet).getCharID()),
chatClient.getGroupTable().getName(
((ChannelMessagePacket) packet).getGroupID()),
currentCharacter.getID());
msg = Message.obtain(null, Statics.MESSAGE_UPDATE, 0, 0);
}
return msg;
}
private Message handleSystemMessagePacket(Packet packet) {
Logging.log(APP_TAG, "Got SystemMessagePacket");
// Got offline message
if (((SystemMessagePacket) packet).getMsgType().equals("a460d92")) {
DatabaseHandler.getInstance(context).addPost(
String.format(getString(R.string.offline_message_from),
NameFormat.format(chatClient.getCharTable()
.getName(
((SystemMessagePacket) packet)
.getCharID()))),
Statics.CHANNEL_SYSTEM, Statics.CHANNEL_SYSTEM,
currentCharacter.getID());
}
// Offline message, message buffered
if (((SystemMessagePacket) packet).getMsgType().equals("9740ff4")) {
DatabaseHandler.getInstance(context).addPost(
String.format(
getString(R.string.user_offline_message_buffered),
NameFormat.format(chatClient.getCharTable()
.getName(
((SystemMessagePacket) packet)
.getCharID()))),
Statics.CHANNEL_SYSTEM, Statics.CHANNEL_SYSTEM,
currentCharacter.getID());
}
// Offline message, message buffered
if (((SystemMessagePacket) packet).getMsgType().equals("340e245")) {
DatabaseHandler.getInstance(context).addPost(
getString(R.string.message_could_not_be_sent),
Statics.CHANNEL_SYSTEM, Statics.CHANNEL_SYSTEM,
currentCharacter.getID());
}
return Message.obtain(null, Statics.MESSAGE_UPDATE, 0, 0);
}
private Message handleBroadcastMessagePacket(Packet packet) {
Logging.log(APP_TAG, "Got BroadcastMessagePacket");
DatabaseHandler.getInstance(context).addPost(
((BroadcastMessagePacket) packet).display(
chatClient.getCharTable(), chatClient.getGroupTable()),
Statics.CHANNEL_SYSTEM, Statics.CHANNEL_SYSTEM,
currentCharacter.getID());
return Message.obtain(null, Statics.MESSAGE_UPDATE, 0, 0);
}
private Message handleVicinityMessagePacket(Packet packet) {
Logging.log(APP_TAG, "Got VicinityMessagePacket");
DatabaseHandler.getInstance(context).addPost(
((VicinityMessagePacket) packet).display(
chatClient.getCharTable(), chatClient.getGroupTable()),
Statics.CHANNEL_SYSTEM, Statics.CHANNEL_SYSTEM,
currentCharacter.getID());
return Message.obtain(null, Statics.MESSAGE_UPDATE, 0, 0);
}
private Message handleFriendUpdatePacket(Packet packet) {
Logging.log(APP_TAG, "Got FriendUpdatePacket");
Message msg = null;
if (!((FriendUpdatePacket) packet).isFriend()) {
boolean removeFriend = false;
int removeFriendID = 0;
int friendCounter = 0;
for (Friend friend : friendList) {
if (friend.getID() == ((FriendUpdatePacket) packet).getCharID()) {
removeFriend = true;
removeFriendID = friendCounter;
break;
}
friendCounter++;
}
if (removeFriend) {
friendList.remove(removeFriendID);
}
}
if (((FriendUpdatePacket) packet).isFriend()) {
boolean addFriend = true;
for (Friend friend : friendList) {
if (friend.getID() == ((FriendUpdatePacket) packet).getCharID()) {
if (friend.isOnline() != ((FriendUpdatePacket) packet)
.isOnline()) {
DatabaseHandler.getInstance(context).addPost(
((FriendUpdatePacket) packet).display(
chatClient.getCharTable(),
chatClient.getGroupTable()),
chatClient.getCharTable().getName(
((FriendUpdatePacket) packet)
.getCharID()),
Statics.CHANNEL_FRIEND,
currentCharacter.getID());
}
friend.setOnline(((FriendUpdatePacket) packet).isOnline());
addFriend = false;
}
}
if (addFriend) {
friendList.add(new Friend(chatClient.getCharTable().getName(
((FriendUpdatePacket) packet).getCharID()),
((FriendUpdatePacket) packet).getCharID(),
((FriendUpdatePacket) packet).isOnline(),
DatabaseHandler.getInstance(context).getCharacterImage(
chatClient.getCharTable().getName(
((FriendUpdatePacket) packet)
.getCharID()))));
}
if (addFriend && ((FriendUpdatePacket) packet).isOnline()) {
DatabaseHandler.getInstance(context).addPost(
((FriendUpdatePacket) packet).display(
chatClient.getCharTable(),
chatClient.getGroupTable()),
chatClient.getCharTable().getName(
((FriendUpdatePacket) packet).getCharID()),
Statics.CHANNEL_FRIEND, currentCharacter.getID());
}
msg = Message.obtain(null, Statics.MESSAGE_FRIEND);
msg.obj = friendList;
}
AOVoiceHandler.removeCallbacks(AOVoiceUpdateTask);
AOVoiceHandler.postDelayed(AOVoiceUpdateTask, 100);
return msg;
}
private Message handleChannelUpdatePacket(Packet packet) {
Logging.log(APP_TAG, "Got ChannelUpdatePacket");
Message msg = null;
boolean addChannel = true;
for (Channel channel : channelList) {
if (channel.getName().equals(
((ChannelUpdatePacket) packet).getGroupName())) {
addChannel = false;
}
}
if (addChannel) {
boolean muted = false;
boolean enabled = true;
if (channelsMuted.contains(((ChannelUpdatePacket) packet)
.getGroupName())) {
muted = true;
}
if (Statics.channelsDisabled
.contains(((ChannelUpdatePacket) packet).getGroupName())) {
enabled = false;
}
channelList.add(new Channel(((ChannelUpdatePacket) packet)
.getGroupName(), Convert
.byteToInt(((ChannelUpdatePacket) packet).getGroupID()),
enabled, muted));
msg = Message.obtain(null, Statics.MESSAGE_CHANNEL);
msg.obj = channelList;
}
return msg;
}
private Message handlePrivateChannelInvitePacket(Packet packet) {
Logging.log(APP_TAG, "Got PrivateChannelInvitePacket");
Message msg = null;
boolean addChannel = true;
for (Channel channel : invitationList) {
if (channel.getID() == ((PrivateChannelInvitePacket) packet)
.getGroupID()) {
addChannel = false;
}
}
if (addChannel) {
invitationList.add(new Channel(
Statics.PREFIX_PRIVATE_GROUP
+ chatClient.getCharTable().getName(
((PrivateChannelInvitePacket) packet)
.getGroupID()),
((PrivateChannelInvitePacket) packet).getGroupID(), true,
false));
}
if (clients.size() == 0
&& settings.getBoolean("notificationEnabled", true)) {
notificationCounter++;
setNotification(null,
String.format(getString(
R.string.you_were_invited,
chatClient.getCharTable().getName(
((PrivateChannelInvitePacket) packet)
.getGroupID()))), true, true);
}
msg = Message.obtain(null, Statics.MESSAGE_PRIVATE_INVITATION);
msg.obj = invitationList;
return msg;
}
private Message handlePrivateChannelCharacterJoinPacket(Packet packet) {
Logging.log(APP_TAG, "Got PrivateChannelCharacterJoinPacket");
DatabaseHandler.getInstance(context).addPost(
String.format(
getString(R.string.joined_channel),
chatClient.getCharTable().getName(
((PrivateChannelCharacterJoinPacket) packet)
.getGroupID()),
chatClient.getCharTable().getName(
((PrivateChannelCharacterJoinPacket) packet)
.getCharID())),
chatClient.getCharTable().getName(
((PrivateChannelCharacterJoinPacket) packet)
.getCharID()),
Statics.PREFIX_PRIVATE_GROUP
+ chatClient.getCharTable().getName(
((PrivateChannelCharacterJoinPacket) packet)
.getGroupID()),
currentCharacter.getID());
return Message.obtain(null, Statics.MESSAGE_UPDATE, 0, 0);
}
private Message handlePrivateChannelKickPacket(Packet packet) {
Logging.log(APP_TAG, "Got PrivateChannelKickPacket");
DatabaseHandler.getInstance(context).addPost(
String.format(
getString(R.string.kicked_from_channel),
chatClient.getCharTable().getName(
((PrivateChannelKickPacket) packet)
.getGroupID())),
chatClient.getCharTable().getName(
((PrivateChannelKickPacket) packet).getGroupID()),
Statics.PREFIX_PRIVATE_GROUP
+ chatClient.getCharTable().getName(
((PrivateChannelKickPacket) packet)
.getGroupID()),
currentCharacter.getID());
int kickedFrom = -1;
for (int i = 0; i < privateList.size(); i++) {
if (privateList.get(i).getID() == ((PrivateChannelKickPacket) packet)
.getGroupID()) {
kickedFrom = i;
}
}
if (kickedFrom >= 0) {
privateList.remove(kickedFrom);
}
Message message = Message.obtain();
message.what = Statics.MESSAGE_PRIVATE_CHANNEL;
message.obj = privateList;
message(message);
return Message.obtain(null, Statics.MESSAGE_UPDATE, 0, 0);
}
private Message handlePrivateChannelCharacterLeavePacket(Packet packet) {
Logging.log(APP_TAG, "Got PrivateChannelCharacterLeavePacket");
DatabaseHandler.getInstance(context).addPost(
String.format(
getString(R.string.left_channel),
chatClient.getCharTable().getName(
((PrivateChannelCharacterLeavePacket) packet)
.getGroupID()),
chatClient.getCharTable().getName(
((PrivateChannelCharacterLeavePacket) packet)
.getCharID())),
chatClient.getCharTable().getName(
((PrivateChannelCharacterLeavePacket) packet)
.getCharID()),
Statics.PREFIX_PRIVATE_GROUP
+ chatClient.getCharTable().getName(
((PrivateChannelCharacterLeavePacket) packet)
.getGroupID()),
currentCharacter.getID());
return Message.obtain(null, Statics.MESSAGE_UPDATE, 0, 0);
}
private Message handlePrivateChannelMessagePacket(Packet packet) {
Logging.log(APP_TAG, "Got PrivateChannelMessagePacket");
DatabaseHandler.getInstance(context).addPost(
((PrivateChannelMessagePacket) packet).display(
chatClient.getCharTable(), chatClient.getGroupTable()),
chatClient.getCharTable().getName(
((PrivateChannelMessagePacket) packet).getCharID()),
Statics.PREFIX_PRIVATE_GROUP
+ chatClient.getCharTable().getName(
((PrivateChannelMessagePacket) packet)
.getGroupID()),
currentCharacter.getID());
return Message.obtain(null, Statics.MESSAGE_UPDATE, 0, 0);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
String action = intent.getAction();
if (action != null) {
Logging.log(APP_TAG, action);
if (action.equals(ACTION_TOGGLE_PLAYBACK)) {
togglePlayback();
} else if (action.equals(ACTION_PLAY)) {
play();
} else if (action.equals(ACTION_STOP)) {
stop();
}
}
}
return START_STICKY;
}
private void registerRemoteControl() {
RemoteControlHelper.registerRemoteControlClient(audioManager,
remoteControlClient);
}
private void unregisterRemoteControl() {
RemoteControlHelper.unregisterRemoteControlClient(audioManager,
remoteControlClient);
}
/*
* private void setRemoteControlStopped() { if (remoteControlClient != null)
* {
* remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED
* ); } }
*
* private void setRemoteControlPlaying() { if (remoteControlClient != null)
* {
* remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING
* ); } }
*
* private void setRemoteControlMetadata(Bitmap artwork, String title,
* String artist) { MetadataEditorCompat editor =
* remoteControlClient.editMetadata(true);
* editor.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, title);
* editor.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, artist);
* editor.putBitmap(RemoteControlClientCompat.MetadataEditorCompat.
* METADATA_KEY_ARTWORK, artwork); editor.apply(); }
*/
public void clientRegistered(Message message) {
clients.add(message.replyTo);
Message msg = Message.obtain();
if (chatClient != null) {
if (chatClient.getState() != Client.ClientState.DISCONNECTED) {
if (currentCharacter != null) {
msg.arg1 = currentCharacter.getID();
} else {
msg.arg1 = 0;
}
notificationCounter = 0;
setNotification(null, null, true, true);
}
}
msg.what = Statics.MESSAGE_REGISTERED;
msg.setTarget(null);
List<Object> registerData = new ArrayList<Object>();
registerData.add(friendList);
registerData.add(channelList);
registerData.add(currentTargetChannel);
registerData.add(currentTargetCharacter);
if (currentCharacter != null) {
registerData.add(currentCharacter.getName());
} else {
registerData.add("");
}
registerData.add(currentShowChannel);
registerData.add(isPlaying);
registerData.add(invitationList);
registerData.add(privateList);
registerData.add(currentTrack);
registerData.add(chatClient.getState() == ClientState.LOGGED_IN);
msg.obj = registerData;
Logging.log(APP_TAG, "Channels: " + channelList.size());
ClientService.this.message(msg);
}
public boolean sendMessage(ChatMessage message, int show) {
Logging.log(APP_TAG, "sendMessage\nChannel: " + message.getChannel()
+ "\nCharacter: " + message.getCharacter());
if (chatClient == null
|| chatClient.getState() != Client.ClientState.LOGGED_IN) {
Logging.toast(context, context.getString(R.string.not_connected));
return false;
}
if (!message.getCharacter().equals("")) {
try {
Logging.log(APP_TAG, "Sending tell");
chatClient.sendTell(message.getCharacter(),
message.getMessage(), true);
if (show == 1) {
DatabaseHandler.getInstance(context).addPost(
String.format(getString(R.string.message_to),
message.getCharacter(),
message.getMessage()),
message.getCharacter(), Statics.CHANNEL_PM,
currentCharacter.getID());
message(Message.obtain(null, Statics.MESSAGE_UPDATE, 0, 0));
}
} catch (IOException e) {
Logging.log(APP_TAG, e.getMessage());
return false;
}
}
if (!message.getChannel().equals("")) {
try {
if (message.getChannel().startsWith(
Statics.PREFIX_PRIVATE_GROUP)) {
Logging.log(APP_TAG, "Sending to private group");
chatClient.sendPrivateChannelMessage(message.getChannel()
.replace(Statics.PREFIX_PRIVATE_GROUP, ""), message
.getMessage());
} else {
Logging.log(APP_TAG, "Sending to public group");
chatClient.sendChannelMessage(message.getChannel(),
message.getMessage());
}
} catch (IOException e) {
Logging.log(APP_TAG, e.getMessage());
return false;
}
}
return true;
}
private long lastNotificationSound = 0;
private long timeBetweenNotificationSounds = 2000;
private void setNotification(String message, String ticker,
boolean persistent, boolean update) {
if (!update) {
notificationBuilder.setContentText(message);
notificationBuilder.setOngoing(persistent);
notificationBuilder.setWhen(System.currentTimeMillis());
}
notificationBuilder.setNumber(notificationCounter);
notificationBuilder.setTicker(ticker);
if (ticker != null
&& update
&& System.currentTimeMillis() - lastNotificationSound > timeBetweenNotificationSounds) {
notificationBuilder.setSound(Uri.parse(settings.getString(
"notificationSound",
"android.resource://com.rubika.aotalk/raw/reet")));
lastNotificationSound = System.currentTimeMillis();
} else {
notificationBuilder.setSound(null);
}
if (isPlaying) {
notificationBuilder.setOngoing(true);
}
setNotificationPlaying();
}
private static void setNotificationFace(Bitmap face) {
if (face != null) {
notificationBuilder.setLargeIcon(face);
notificationManager.notify(NOTIFICATION,
notificationBuilder.build());
} else {
Logging.log(APP_TAG, "Character image is NULL");
}
}
private void setNotificationPlayerTrack(String track) {
notificationBuilder.setContentText(track);
notificationManager.notify(NOTIFICATION, notificationBuilder.build());
}
private void setNotificationPlaying() {
if (isPlaying) {
notificationBuilder.setSmallIcon(R.drawable.ic_gridstream);
if (chatClient.getState() == Client.ClientState.DISCONNECTED) {
notificationBuilder
.setLargeIcon(((BitmapDrawable) getResources()
.getDrawable(R.drawable.gspleet)).getBitmap());
}
if (currentTrack != null) {
notificationBuilder.setContentText(currentTrack);
}
} else {
notificationBuilder.setSmallIcon(R.drawable.ic_notification);
if (chatClient.getState() == Client.ClientState.DISCONNECTED) {
notificationBuilder
.setLargeIcon(((BitmapDrawable) getResources()
.getDrawable(R.drawable.leet)).getBitmap());
}
if (currentCharacter != null) {
notificationBuilder.setContentText(String.format(
getString(R.string.character_is_online),
currentCharacter.getName()));
} else {
notificationBuilder.setContentText("Doh");
}
}
notificationManager.notify(NOTIFICATION, notificationBuilder.build());
if (chatClient.getState() == Client.ClientState.DISCONNECTED
&& !isPlaying) {
notificationManager.cancel(NOTIFICATION);
}
}
public boolean message(Message message) {
if (message != null) {
for (int i = clients.size() - 1; i >= 0; i--) {
try {
clients.get(i).send(message);
} catch (RemoteException ex) {
clients.remove(i);
}
}
return true;
}
return false;
}
private class UpdateAOVoice extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... str) {
AOVoiceIsUpdating = true;
updateAOVoiceData();
return null;
}
protected void onPostExecute(String result) {
Message msg = Message.obtain(null, Statics.MESSAGE_FRIEND);
msg.obj = friendList;
message(msg);
AOVoiceIsUpdating = false;
}
}
private void updateAOVoiceData() {
HttpClient httpclient;
HttpPost httppost;
HttpResponse response;
HttpEntity entity;
InputStream is;
BufferedReader reader;
StringBuilder sb;
String line;
String resultData = null;
JSONArray jArray;
JSONObject json_data;
try {
httpclient = new DefaultHttpClient();
httppost = new HttpPost(String.format(Statics.AOSPEAK_API_PATH,
chatClient.getDimensionID()));
response = httpclient.execute(httppost);
entity = response.getEntity();
is = entity.getContent();
try {
reader = new BufferedReader(new InputStreamReader(is,
"iso-8859-1"), 8);
sb = new StringBuilder();
line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
Logging.log(APP_TAG, sb.toString());
resultData = sb.toString();
} catch (Exception e) {
Logging.log(APP_TAG, e.toString());
}
} catch (Exception e) {
Logging.log(APP_TAG, e.toString());
}
try {
if (resultData != null) {
if ((!resultData.startsWith("null"))) {
jArray = new JSONArray(resultData);
try {
for (Friend f : friendList) {
f.setAOSpeakStatus(false);
}
} catch (ConcurrentModificationException e) {
Logging.log(APP_TAG, e.getMessage());
}
for (int i = jArray.length() - 1; i >= 0; i--) {
json_data = jArray.getJSONObject(i);
try {
for (Friend f : friendList) {
String fixedName = "";
if (json_data.getString("name").contains(" ")) {
fixedName = json_data.getString("name")
.split(" ")[0].trim();
} else {
fixedName = json_data.getString("name");
}
if (f.getName()
.toLowerCase(Locale.getDefault())
.equals(fixedName.toLowerCase(Locale
.getDefault()))) {
f.setAOSpeakStatus(true);
}
}
} catch (ConcurrentModificationException e) {
Logging.log(APP_TAG, e.getMessage());
}
}
}
}
} catch (JSONException e) {
Logging.log(APP_TAG, e.toString());
}
}
private Runnable AOVoiceUpdateTask = new Runnable() {
public void run() {
if (chatClient.getState() == Client.ClientState.LOGGED_IN
&& !AOVoiceIsUpdating) {
Logging.log(APP_TAG,
"AOVoiceUpdate - User is logged in, fetching AOVoice data and updating friends");
new UpdateAOVoice().execute();
} else {
Logging.log(
APP_TAG,
"AOVoiceUpdate - User is NOT logged in or update already running, no need to fetch data");
}
if (clients.size() > 0) {
AOVoiceHandler.postDelayed(this, AOVoiceUpdateTime);
} else {
AOVoiceHandler.removeCallbacks(this);
}
}
};
public void connect(Account acc) {
if (acc != null) {
currentAccount = acc;
new Thread(new Runnable() {
public void run() {
if (settings.getBoolean("reconnect", true)) {
try {
synchronized (this) {
long startTime = System.currentTimeMillis();
long timeout = 60000;
while (!ServiceTools.isOnline(context)) {
wait(500);
if (System.currentTimeMillis() - startTime > timeout) {
Logging.log(
APP_TAG,
String.format(
getString(R.string.reconnect_timeout),
(timeout / 1000)));
break;
}
}
}
} catch (InterruptedException e) {
Logging.log(APP_TAG, e.getMessage());
}
}
try {
if (currentAccount != null) {
Logging.log(APP_TAG, "Connecting");
if (chatClient.getState() != ChatClient.ClientState.DISCONNECTED) {
chatClient.disconnect();
}
if (chatClient.getState() == ChatClient.ClientState.DISCONNECTED) {
chatClient.connect(DimensionAddress.RK);
}
}
} catch (IOException e) {
message(Message.obtain(null, Statics.MESSAGE_CONNECTION_ERROR, 0, 0));
accountFailed = true;
Logging.log(APP_TAG, e.getMessage());
} catch (ClientStateException e) {
message(Message.obtain(null, Statics.MESSAGE_CONNECTION_ERROR, 0, 0));
accountFailed = true;
Logging.log(APP_TAG, e.getMessage());
}
}
}).start();
}
}
private void authenticate() {
if (chatClient.getState() == Client.ClientState.CONNECTED) {
try {
if (currentAccount != null) {
chatClient.authenticate(currentAccount.getUsername(),
currentAccount.getPassword());
}
} catch (IOException e) {
message(Message.obtain(null, Statics.MESSAGE_CONNECTION_ERROR,
0, 0));
accountFailed = true;
Logging.log(APP_TAG, e.getMessage());
Logging.log(APP_TAG, "authentication failed");
}
}
}
public void login(final CharacterInfo character) {
if (character != null) {
currentCharacter = character;
new Thread(new Runnable() {
public void run() {
try {
Logging.log(APP_TAG, "Logging in");
chatClient.login(character);
} catch (IOException e) {
message(Message.obtain(null,
Statics.MESSAGE_CONNECTION_ERROR, 0, 0));
accountFailed = true;
Logging.log(APP_TAG, e.getMessage());
Logging.log(APP_TAG, "login failed");
}
}
}).start();
}
}
public boolean addFriend(final String name) {
if (chatClient.getState() != Client.ClientState.DISCONNECTED) {
if (NameFormat.format(currentCharacter.getName()).equals(
NameFormat.format(name))) {
Logging.toast(context, getString(R.string.not_add_yourself));
return false;
}
List<Friend> tempList = friendList;
boolean addCharacter = true;
for (Friend friend : tempList) {
if (NameFormat.format(friend.getName()).equals(
NameFormat.format(name))) {
addCharacter = false;
}
}
if (addCharacter) {
new Thread(new Runnable() {
public void run() {
try {
chatClient.addFriend(name, true);
} catch (IOException e) {
Logging.log(APP_TAG, e.getMessage());
}
}
}).start();
Logging.toast(context, String.format(
getString(R.string.added_to_buddy_list), name));
return true;
} else {
Logging.toast(context, String.format(
getString(R.string.already_in_buddy_list), name));
}
} else {
Logging.toast(context, getString(R.string.not_connected));
}
return false;
}
public boolean removeFriend(final String name) {
if (chatClient.getState() != Client.ClientState.DISCONNECTED) {
List<Friend> tempList = new ArrayList<Friend>();
tempList.addAll(friendList);
boolean removeCharacter = false;
int friendCounter = 0;
int removeID = 0;
for (Friend friend : tempList) {
if (NameFormat.format(friend.getName()).equals(
NameFormat.format(name))) {
removeCharacter = true;
removeID = friendCounter;
}
friendCounter++;
}
final int removeThis = removeID;
if (removeCharacter) {
new Thread(new Runnable() {
public void run() {
try {
chatClient.deleteFriend(name, true);
friendList.remove(removeThis);
Message msg = Message.obtain(null,
Statics.MESSAGE_FRIEND);
msg.obj = friendList;
message(msg);
} catch (IOException e) {
Logging.log(APP_TAG, e.getMessage());
}
}
}).start();
Logging.toast(context, String.format(
getString(R.string.removed_from_buddy_list), name));
return true;
} else {
Logging.toast(context, String.format(
getString(R.string.not_in_buddy_list), name));
}
} else {
Logging.toast(context, getString(R.string.disconnected));
}
return false;
}
private void togglePlayback() {
if (isPlaying) {
stop();
} else {
play();
}
}
public void play() {
aacPlayer.stop();
/*
if (PLAYURL.equals("")) {
try {
URL updateURL = new URL(Statics.GSP_PLAYLIST_PATH);
URLConnection conn = updateURL.openConnection();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
String html = new String(baf.toByteArray());
String[] lines = html.split("\n");
for (String s : lines) {
Logging.log(APP_TAG, "Line: " + s);
if (s.trim().startsWith("File1=")) {
PLAYURL = s.trim().replace("File1=", "").trim();
}
}
} catch (Exception e) {
Logging.log(APP_TAG, e.getMessage());
}
}
*/
if (PLAYURL.equals("")) {
PLAYURL = "http://5.152.208.98:8120";
}
if (!isPlaying) {
try {
tryToGetAudioFocus();
aacPlayer.playAsync(PLAYURL, 48);
} catch (Exception e) {
Logging.log(APP_TAG, e.getMessage());
if (retryOnFailure) {
aacPlayer.stop();
Logging.log(APP_TAG, "Player retry");
play();
}
}
}
}
public void stop() {
if (isPlaying) {
// audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
}
aacPlayer.stop();
}
private void tryToGetAudioFocus() {
if (mAudioFocus != AudioFocus.Focused && mAudioFocusHelper != null
&& mAudioFocusHelper.requestFocus()) {
mAudioFocus = AudioFocus.Focused;
}
}
private void giveUpAudioFocus() {
if (mAudioFocus == AudioFocus.Focused && mAudioFocusHelper != null
&& mAudioFocusHelper.abandonFocus()) {
mAudioFocus = AudioFocus.NoFocusNoDuck;
}
}
@Override
public void onGainedAudioFocus() {
mAudioFocus = AudioFocus.Focused;
}
@Override
public void onLostAudioFocus(boolean canDuck) {
mAudioFocus = canDuck ? AudioFocus.NoFocusCanDuck
: AudioFocus.NoFocusNoDuck;
}
}