package org.droidklavier.tcp;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import org.droidklavier.BuildConfig;
import org.droidklavier.Droidklavier;
import org.droidklavier.R;
import org.droidklavier.activity.Player;
import org.droidklavier.activity.SettingsActivity;
import org.droidklavier.rc.RC;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
/**
* The Handler that gets information back from the TCPClient
*
*/
public class TCPHandler extends Handler {
private static final String TAG = "TCPHandler";
public static final int MESSAGE_STATE_CHANGE = 0;
public static final int MESSAGE_READ = 1;
public static final int MESSAGE_WRITE = 2;
public static final int MESSAGE_CONNECTED_ADDRESS = 3;
public static final int MESSAGE_CONNECTION_FAILED = 4;
public static final int MESSAGE_CONNECTION_LOST = 5;
// Key names received from the TCPClient
public static final String CONNECTED_ADDRESS = "connected_address";
private final Droidklavier mDroidklavier;
private DocumentBuilder mDocumentBuilder;
public TCPHandler(Droidklavier droidklavier) {
mDroidklavier = droidklavier;
/** DocumentBuilder for parsing incoming XML messages */
try {
mDocumentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (Exception e) {
if (BuildConfig.DEBUG) {
Log.e(TAG, "XML Document: " + e.getMessage());
}
}
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Player player;
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
handleStateChange(msg);
break;
case MESSAGE_WRITE:
if (BuildConfig.DEBUG) {
Log.d(TAG, "Message sent: " + (String) msg.obj);
}
break;
case MESSAGE_READ:
handleMessageRead(msg);
break;
case MESSAGE_CONNECTED_ADDRESS:
handleMConnectedAddr(msg);
break;
case MESSAGE_CONNECTION_FAILED:
player = mDroidklavier.getPlayer();
if (player != null) {
player.connectionFailed();
}
break;
case MESSAGE_CONNECTION_LOST:
player = mDroidklavier.getPlayer();
if (player != null) {
player.connectionLost();
}
break;
}
}
private synchronized void parse(String xmlString) throws Exception {
Element element = mDocumentBuilder.parse(
new InputSource(new StringReader(xmlString))).getDocumentElement();
if (element == null) {
return;
}
String tagName = element.getTagName();
// RCS_STATUS
if (tagName.equals("rcs_status")) {
parseRcsStatus(element);
return;
}
// RC_CERTIFICATE
if (tagName.equals("rc_certificate")) {
parseRcCert(element);
return;
}
// QUIET_STATUS
if (tagName.equals("quiet_status")) {
parseQuietStatus(element);
return;
}
// VOL_STATUS
if (tagName.equals("vol_status")) {
parseVolStatus(element);
return;
}
// KARAOKE
// report when it has finished after sending <search />
if (tagName.equals("karaoke")) {
parseKaraoke();
return;
}
// SEQ_STATUS
if (tagName.equals("seq_status")) {
parseSeqStatus(element);
return;
}
// MESSAGE
if (tagName.equals("message_box")) {
parseMessageBox(element);
}
mDocumentBuilder.reset();
}
private void handleStateChange(Message msg) {
if (BuildConfig.DEBUG) {
Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
}
Player player;
switch (msg.arg1) {
case TCPClient.STATE_CONNECTED:
break;
case TCPClient.STATE_DISCONNECTED:
player = mDroidklavier.getPlayer();
if (player != null) {
player.connectionLost();
}
break;
}
}
private void handleMessageRead(Message msg) {
String message = ((String) msg.obj).trim();
try {
if (message != null && message.length() > 0) {
parse(message);
}
} catch (Exception e) {
if (BuildConfig.DEBUG) {
Log.e(TAG, "XML Parser Error: " + e.getMessage() + " when trying to parse [" + message + "]");
}
e.printStackTrace();
}
if (BuildConfig.DEBUG) {
Log.d(TAG, "Message received: " + message);
}
}
private void handleMConnectedAddr(Message msg) {
String connectedAddr = msg.getData().getString(CONNECTED_ADDRESS);
mDroidklavier.setConnectedAddr(connectedAddr);
Player player = mDroidklavier.getPlayer();
if (player != null) {
player.connectionSuccess();
}
}
private void parseRcsStatus(Element element) {
Player player = mDroidklavier.getPlayer();
if (player != null) {
player.updateRCSStatus(element.getAttribute("status"));
}
}
private void parseRcCert(Element element) {
String param = element.getAttribute("param");
String result = element.getAttribute("result");
if (param.length() > 0) {
SharedPreferences sharedPref = PreferenceManager
.getDefaultSharedPreferences(Droidklavier.context);
String pass = sharedPref.getString(SettingsActivity.PASS,
SettingsActivity.PASS_DEFAULT);
mDroidklavier.sendTCPMessage(RC.rcCertificate(param, pass));
mDroidklavier.sendTCPMessage(RC.quietStatus());
mDroidklavier.sendTCPMessage(RC.getRcsStatus());
}
if (BuildConfig.DEBUG) {
if (result.equals("pass")) {
Log.d(TAG, "RC Certificate = PASS");
} else if (result.equals("fail")) {
Log.e(TAG, "RC Certificate = FAIL");
}
}
}
private void parseQuietStatus(Element element) {
String mode = element.getAttribute("mode");
Player player = mDroidklavier.getPlayer();
if (player != null) {
player.updateQuietStatus(mode);
mDroidklavier.sendTCPMessage(RC.volStatus());
}
}
private void parseVolStatus(Element element) {
mDroidklavier.getRC().setVolumes(
Integer.parseInt(element.getAttribute("main_acoustic")),
Integer.parseInt(element.getAttribute("main_quiet")),
Integer.parseInt(element.getAttribute("main_headphone")),
Integer.parseInt(element.getAttribute("voice")),
Integer.parseInt(element.getAttribute("tg")),
Integer.parseInt(element.getAttribute("audio")),
Integer.parseInt(element.getAttribute("mic")));
}
private void parseKaraoke() {
Player player = mDroidklavier.getPlayer();
if (player != null) {
player.updateSeekingStatus(false);
}
}
private void parseSeqStatus(Element element) {
String status = element.getAttribute("status");
String source = element.getAttribute("source_id");
int albumId = Integer.parseInt(element.getAttribute("album_id"));
int selSongNo = Integer.valueOf(element.getAttribute("sel_song_no"));
int time = Integer.parseInt(element.getAttribute("time"));
Player player = mDroidklavier.getPlayer();
if (player != null) {
player.updateSeqStatus(status, source, albumId, selSongNo, time);
}
if (status.equals("loaded")) {
mDroidklavier.sendTCPMessage(RC.play());
}
}
private void parseMessageBox(Element element) {
String message = "";
NodeList messageList = element.getChildNodes();
int length = messageList.getLength();
for (int i = 0; i < length; i++) {
message += messageList.item(i).getChildNodes().item(0).getNodeValue();
if (i < length - 1) {
message += "\n";
}
}
Player player = mDroidklavier.getPlayer();
if (player != null && player.isSearching()) {
if (element.getAttribute("button").equals("CANCEL")) {
player.searchProcessing(message);
} else if (element.getAttribute("button").equals("OK")) {
if (element.getAttribute("rank").equals("error")) {
player.searchEnd(
mDroidklavier.getString(R.string.search_canceled),
message);
} else {
player.searchEnd(
mDroidklavier.getString(R.string.search_complete),
message);
}
}
}
}
}