From 04c2dbbe888080ef8083763900041b45885712f0 Mon Sep 17 00:00:00 2001 From: lado Date: Wed, 27 Mar 2013 23:24:14 +0100 Subject: Merged from comrepss branch + better cancellable handling --- .../de/bjusystems/vdrmanager/gui/BaseActivity.java | 11 +- .../vdrmanager/gui/SvdrpProgressDialog.java | 2 + .../vdrmanager/utils/svdrp/SvdrpAsyncTask.java | 4 + .../vdrmanager/utils/svdrp/SvdrpClient.java | 927 +++++++++++---------- 4 files changed, 492 insertions(+), 452 deletions(-) diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java index de3d42e..d9dc70f 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java @@ -4,6 +4,8 @@ import java.util.List; import android.app.AlertDialog; import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.content.DialogInterface.OnCancelListener; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; @@ -205,7 +207,14 @@ public abstract class BaseActivity extends super.onCreate(savedInstanceState); Preferences.setLocale(this); progress = new ProgressDialog(this); - + progress.setCancelable(false); + progress.setCanceledOnTouchOutside(false); +// progress.setOnCancelListener(new OnCancelListener() { +// @Override +// public void onCancel(DialogInterface dialog) { +// +// } +// }); initActionBar(); diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/SvdrpProgressDialog.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/SvdrpProgressDialog.java index 4c72795..74cd502 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/SvdrpProgressDialog.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/SvdrpProgressDialog.java @@ -23,6 +23,8 @@ public class SvdrpProgressDialog extends ProgressDialog implements this.client = client; progress = new ProgressDialog(context); progress.setOnCancelListener(this); + progress.setCancelable(true); + progress.setCanceledOnTouchOutside(false); } public void svdrpEvent(final SvdrpEvent sevent) { diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java index 0a7e539..b7b090e 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java @@ -155,4 +155,8 @@ public class SvdrpAsyncTask> extends public void svdrpEvent(Result result) { results.add(result); } + + public void abort(){ + client.abort(); + } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java index f6307f5..12ef6d5 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java @@ -12,8 +12,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; +import java.util.zip.GZIPInputStream; +import java.util.zip.InflaterInputStream; -import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import android.util.Log; @@ -28,455 +29,479 @@ import de.bjusystems.vdrmanager.data.Preferences; */ public abstract class SvdrpClient { - private final String TAG = getClass().getName(); - - /** Socket for connection to SVDRP */ - private Socket socket; - /** Output stream for sending commands */ - private OutputStream outputStream; - /** Input stream for reading answer lines */ - private InputStream inputStream; - /** flag for stopping the current request */ - private boolean abort; - /** listener */ - private final List svdrpListeners = new ArrayList(); - - private final List> svdrpResultListeners = new ArrayList>(); - - private final List svdrpExceptionListeners = new ArrayList(); - - private final List> svdrpFinishedListeners = new ArrayList>(); - - /** list of results */ - // private final List results = new ArrayList(); - /** should the listener be informed about each received result */ - // private boolean resultInfoEnabled = false; - /** - * @return true if the client has result - */ - // public boolean hasResults(){ - // return results.isEmpty() == false; - // } - - private Timer watchDog = new Timer(); - - // private NativeDES crypt = new NativeDES(); - - public boolean isConnected() { - if (socket == null) { - return false; - } - return socket.isConnected(); - } - - /** - * Parse received answer line - * - * @param line - * line - * @return received data object or null if not completed yet - */ - protected abstract Result parseAnswer(String line); - - public abstract int getProgressTextId(); - - public abstract void run(); - - /** - * Constructor - * - * @param prefs - * Preferences - */ - protected SvdrpClient() { - // results.clear(); - } - - /** - * Remove all listeners - */ - public void clearListener() { - svdrpExceptionListeners.clear(); - svdrpListeners.clear(); - svdrpResultListeners.clear(); - } - - /** - * Adds the listener to the list of listeners - * - * @param listener - * listener - */ - public void addSvdrpListener(final SvdrpListener listener) { - svdrpListeners.add(listener); - } - - /** - * Adds the listener to the list of listeners - * - * @param listener - * listener - */ - public void addSvdrpResultListener( - final SvdrpResultListener listener) { - svdrpResultListeners.add(listener); - } - - /** - * Adds the listener to the list of listeners - * - * @param listener - * listener - */ - public void addSvdrpFinishedListener( - final SvdrpFinishedListener listener) { - svdrpFinishedListeners.add(listener); - } - - /** - * Adds the listener to the list of listeners - * - * @param listener - * listener - */ - public void addSvdrpExceptionListener(final SvdrpExceptionListener listener) { - svdrpExceptionListeners.add(listener); - } - - /** - * Removes the listener from the list of listeners - * - * @param listener - * listener - */ - public void removeSvdrpListener(final SvdrpListener listener) { - svdrpListeners.remove(listener); - } - - public void removeSvdrpResultListener( - final SvdrpResultListener listener) { - svdrpResultListeners.remove(listener); - } - - public void removeSvdrpExceptionListener( - final SvdrpExceptionListener listener) { - svdrpExceptionListeners.remove(listener); - } - - /** - * Cancel the current request - */ - public void abort() { - abort = true; - try { - if (isConnected()) { - socket.shutdownInput(); - socket.shutdownOutput(); - socket.close(); - } - } catch (Exception ex) { - Log.w(TAG, ex); - } - - } - - // /** - // * Gets the list of results - // * - // * @return results - // */ - // public List getResults() { - // return results; - // } - - /** - * Connect to SVDRP - * - * @param host - * host - * @param port - * port - * @param ssl - * use SSL - * @throws IOException - * on errors - */ - protected boolean connect() throws IOException { - - final Preferences prefs = Preferences.get(); - try { - // connect - informListener(SvdrpEvent.CONNECTING); - - if (false && Preferences.get().isSecure()) { - - SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory - .getDefault(); // Erzeugt eine SSLSocketFactory mit - // Standartkonfiguration - socket = (SSLSocket) factory.createSocket(); - } else { - socket = new Socket(); - } - - socket.connect( - new InetSocketAddress(prefs.getSvdrpHost(), prefs - .getSvdrpPort()), - prefs.getConnectionTimeout() * 1000);// 8 secs for connect - if (abort) { - informListener(SvdrpEvent.ABORTED); - } - // - socket.setSoTimeout(prefs.getReadTimeout() * 1000);// 15 sec for - // each read - final long delay = C.ONE_MINUTE_IN_MILLIS * prefs.getTimeout() * 60; // in - // 3 - // minutes - // we - // abort - // the - // communication - watchDog.schedule(new TimerTask() { - @Override - public void run() { - Log.w(TAG, "Aborted after " + delay + " ms"); - abort = true; - } - }, delay); - informListener(SvdrpEvent.CONNECTED); - } catch (final SocketTimeoutException sote) { - Log.w(TAG, sote); - if (abort) { - informListener(SvdrpEvent.ABORTED); - } else { - informListener(SvdrpEvent.CONNECTION_TIMEOUT); - } - return false; - } catch (final Exception e) { - - Log.w(TAG, e); - if (abort) { - informListener(SvdrpEvent.ABORTED); - } else { - informListener(SvdrpEvent.CONNECT_ERROR); - } - return false; - } - - // create streams - outputStream = socket.getOutputStream(); - inputStream = socket.getInputStream(); - // TODO http://projects.vdr-developer.org/issues/790 - // inputStream = new InflaterInputStream(socket.getInputStream()) - - // password needed? - informListener(SvdrpEvent.LOGIN); - writeLine("passwd " + prefs.getPassword()); - if (!readLine().startsWith("!OK")) { - informListener(SvdrpEvent.LOGIN_ERROR); - disconnect(); - return false; - } else { - informListener(SvdrpEvent.LOGGED_IN); - } - return true; - } - - /** - * Disconnect from SVDRP if connected - * - * @throws IOException - * on errors - */ - protected void disconnect() throws IOException { - informListener(SvdrpEvent.DISCONNECTING); - if (socket != null && socket.isConnected()) { - socket.close(); - socket = null; - } - informListener(SvdrpEvent.DISCONNECTED); - } - - /** - * Sends one line to SVDRP - * - * @param line - * line of text - * @throws IOException - * on errors - */ - protected void writeLine(final String line) throws IOException { - - String command = line + "\r\n"; - // if (false && Preferences.get().isSecure()) { - // command = crypt.encrypt(command, Preferences.get().getPassword()); - // } - final byte[] bytes = command.getBytes("utf-8"); - outputStream.write(bytes); - outputStream.flush(); - } - - /** - * Reads one line from SVDRP - * - * @return line read - * @throws IOException - * on errors - */ - protected String readLine() throws IOException { - - // handle not gzipped input - final ByteArrayOutputStream lineBytes = new ByteArrayOutputStream(); - - for (;;) { - - // read next char - final int d = inputStream.read(); - if (d < 0) { - break; - } - final char c = (char) d; - - // skip '\r' - if (c == '\r') { - continue; - } - - // with '\n' the line is completed - if (c == '\n') { - break; - } - - // remember char - lineBytes.write(c); - } - - String line = null; - try { - line = lineBytes.toString(Preferences.get().getEncoding()); - } catch (UnsupportedEncodingException usex) { - Log.w(TAG, usex); - line = lineBytes.toString(); - } - // if (false && Preferences.get().isSecure()) { - // line = crypt.decrypt(line, Preferences.get().getPassword()); - // } - return line; - } - - public void runCommand(final String command) { - - try { - - // reset cancel flag - abort = false; - - // clear results - // results.clear(); - - // connect - final boolean connected = connect(); - if (!connected) { - return; - } - - // send command - informListener(SvdrpEvent.COMMAND_SENDING); - writeLine(command); - informListener(SvdrpEvent.COMMAND_SENT); - Log.i(TAG, SvdrpEvent.COMMAND_SENT + ":" + command); - - // read first line - String line = readLine(); - if (!line.startsWith("START")) { - Log.w(TAG, line); - throw new IOException("Answer not wellformed: " + line); - } - - // read answer lines - for (; !abort;) { - - // get next line - line = readLine(); - if (line.length() == 0) { - break; - } - - // last line? - if (line.startsWith("END")) { - break; - } - - // error? - if (line.startsWith("!ERROR")) { - Log.w(TAG, line); - String msg; - if (line.startsWith("!ERROR:")) { - msg = line.substring(7); - } else { - msg = line; - } - disconnect(); - informListener(SvdrpEvent.ERROR, new SvdrpException(msg)); - break; - } - - // delegate analysis - Result result = null; - try { - result = parseAnswer(line); - - } catch (Exception ex) { - Log.w(TAG, ex); - disconnect(); - Log.w(TAG, "line: " + line); - informListener(SvdrpEvent.ERROR, ex); - return; - } - if (result != null) { - informListener(result); - // results.add(result); - // if (resultInfoEnabled) { - - // } - } - - } - - // disconnect - disconnect(); - - if (abort) { - informListener(SvdrpEvent.ABORTED); - } else { - informListener(SvdrpEvent.FINISHED_SUCCESS); - } - - } catch (final Exception e) { - Log.w(TAG, e); - informListener(SvdrpEvent.FINISHED_ABNORMALY, e); - } - } - - // public void setResultInfoEnabled(final boolean resultInfoEnabled) { - // this.resultInfoEnabled = resultInfoEnabled; - // } - - protected void informListener(final SvdrpEvent event, final Throwable e) { - for (final SvdrpExceptionListener listener : svdrpExceptionListeners) { - listener.svdrpEvent(event, e); - } - } - - protected void informListener(final SvdrpEvent event) { - for (final SvdrpListener listener : svdrpListeners) { - listener.svdrpEvent(event); - } - } - - protected void informListener(final Result result) { - for (final SvdrpResultListener listener : svdrpResultListeners) { - listener.svdrpEvent(result); - } - } + private final String TAG = getClass().getName(); + + /** Socket for connection to SVDRP */ + private Socket socket; + /** Output stream for sending commands */ + private OutputStream outputStream; + /** Input stream for reading answer lines */ + private InputStream inputStream; + /** flag for stopping the current request */ + private boolean abort; + /** listener */ + private final List svdrpListeners = new ArrayList(); + + private final List> svdrpResultListeners = new ArrayList>(); + + private final List svdrpExceptionListeners = new ArrayList(); + + private final List> svdrpFinishedListeners = new ArrayList>(); + + /** list of results */ + // private final List results = new ArrayList(); + /** should the listener be informed about each received result */ + // private boolean resultInfoEnabled = false; + /** + * @return true if the client has result + */ + // public boolean hasResults(){ + // return results.isEmpty() == false; + // } + + private final Timer watchDog = new Timer(); + + // private NativeDES crypt = new NativeDES(); + + public boolean isConnected() { + if (socket == null) { + return false; + } + return socket.isConnected(); + } + + /** + * Parse received answer line + * + * @param line + * line + * @return received data object or null if not completed yet + */ + protected abstract Result parseAnswer(String line); + + public abstract int getProgressTextId(); + + public abstract void run(); + + /** + * Constructor + * + * @param prefs + * Preferences + */ + protected SvdrpClient() { + // results.clear(); + } + + /** + * Remove all listeners + */ + public void clearListener() { + svdrpExceptionListeners.clear(); + svdrpListeners.clear(); + svdrpResultListeners.clear(); + } + + /** + * Adds the listener to the list of listeners + * + * @param listener + * listener + */ + public void addSvdrpListener(final SvdrpListener listener) { + svdrpListeners.add(listener); + } + + /** + * Adds the listener to the list of listeners + * + * @param listener + * listener + */ + public void addSvdrpResultListener( + final SvdrpResultListener listener) { + svdrpResultListeners.add(listener); + } + + /** + * Adds the listener to the list of listeners + * + * @param listener + * listener + */ + public void addSvdrpFinishedListener( + final SvdrpFinishedListener listener) { + svdrpFinishedListeners.add(listener); + } + + /** + * Adds the listener to the list of listeners + * + * @param listener + * listener + */ + public void addSvdrpExceptionListener(final SvdrpExceptionListener listener) { + svdrpExceptionListeners.add(listener); + } + + /** + * Removes the listener from the list of listeners + * + * @param listener + * listener + */ + public void removeSvdrpListener(final SvdrpListener listener) { + svdrpListeners.remove(listener); + } + + public void removeSvdrpResultListener( + final SvdrpResultListener listener) { + svdrpResultListeners.remove(listener); + } + + public void removeSvdrpExceptionListener( + final SvdrpExceptionListener listener) { + svdrpExceptionListeners.remove(listener); + } + + /** + * Cancel the current request + */ + public void abort() { + abort = true; + try { + if (isConnected()) { + socket.shutdownInput(); + socket.shutdownOutput(); + socket.close(); + } + } catch (final Exception ex) { + Log.w(TAG, ex); + } + + } + + // /** + // * Gets the list of results + // * + // * @return results + // */ + // public List getResults() { + // return results; + // } + + /** + * Connect to SVDRP + * + * @param host + * host + * @param port + * port + * @param ssl + * use SSL + * @throws IOException + * on errors + */ + protected boolean connect() throws IOException { + + final Preferences prefs = Preferences.get(); + try { + // connect + informListener(SvdrpEvent.CONNECTING); + + if (false && Preferences.get().isSecure()) { + + final SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory + .getDefault(); // Erzeugt eine SSLSocketFactory mit + // Standartkonfiguration + socket = factory.createSocket(); + } else { + socket = new Socket(); + } + + socket.connect( + new InetSocketAddress(prefs.getSvdrpHost(), prefs + .getSvdrpPort()), + prefs.getConnectionTimeout() * 1000);// 8 secs for connect + if (abort) { + informListener(SvdrpEvent.ABORTED); + } + // + socket.setSoTimeout(prefs.getReadTimeout() * 1000);// 15 sec for + // each read + final long delay = C.ONE_MINUTE_IN_MILLIS * prefs.getTimeout() * 60; // in + // 3 + // minutes + // we + // abort + // the + // communication + watchDog.schedule(new TimerTask() { + @Override + public void run() { + Log.w(TAG, "Aborted after " + delay + " ms"); + abort = true; + } + }, delay); + informListener(SvdrpEvent.CONNECTED); + } catch (final SocketTimeoutException sote) { + Log.w(TAG, sote); + if (abort) { + informListener(SvdrpEvent.ABORTED); + } else { + informListener(SvdrpEvent.CONNECTION_TIMEOUT); + } + return false; + } catch (final Exception e) { + + Log.w(TAG, e); + if (abort) { + informListener(SvdrpEvent.ABORTED); + } else { + informListener(SvdrpEvent.CONNECT_ERROR); + } + return false; + } + + // create streams + outputStream = socket.getOutputStream(); + inputStream = socket.getInputStream(); + + + // password needed? + informListener(SvdrpEvent.LOGIN); + writeLine("passwd " + prefs.getPassword()); + if (!readLine().startsWith("!OK")) { + informListener(SvdrpEvent.LOGIN_ERROR); + disconnect(); + return false; + } else { + informListener(SvdrpEvent.LOGGED_IN); + } + return true; + } + + /** + * Disconnect from SVDRP if connected + * + * @throws IOException + * on errors + */ + protected void disconnect() throws IOException { + informListener(SvdrpEvent.DISCONNECTING); + if (socket != null && socket.isConnected()) { + socket.close(); + socket = null; + } + informListener(SvdrpEvent.DISCONNECTED); + } + + /** + * Sends one line to SVDRP + * + * @param line + * line of text + * @throws IOException + * on errors + */ + protected void writeLine(final String line) throws IOException { + + final String command = line + "\r\n"; + // if (false && Preferences.get().isSecure()) { + // command = crypt.encrypt(command, Preferences.get().getPassword()); + // } + final byte[] bytes = command.getBytes("utf-8"); + outputStream.write(bytes); + outputStream.flush(); + } + + /** + * Reads one line from SVDRP + * + * @return line read + * @throws IOException + * on errors + */ + protected String readLine() throws IOException { + + // handle not gzipped input + final ByteArrayOutputStream lineBytes = new ByteArrayOutputStream(); + + for (;;) { + + // read next char + final int d = inputStream.read(); + if (d < 0) { + break; + } + final char c = (char) d; + + // skip '\r' + if (c == '\r') { + continue; + } + + // with '\n' the line is completed + if (c == '\n') { + break; + } + + // remember char + lineBytes.write(c); + } + + String line = null; + try { + line = lineBytes.toString(Preferences.get().getEncoding()); + } catch (final UnsupportedEncodingException usex) { + Log.w(TAG, usex); + line = lineBytes.toString(); + } + // if (false && Preferences.get().isSecure()) { + // line = crypt.decrypt(line, Preferences.get().getPassword()); + // } + return line; + } + + public void runCommand(final String command) { + + try { + + // reset cancel flag + abort = false; + + // clear results + // results.clear(); + + // connect + final boolean connected = connect(); + if (!connected) { + return; + } + + // activate compression + Log.i(TAG, "Activate compression"); + writeLine("compress"); + + // send command + informListener(SvdrpEvent.COMMAND_SENDING); + writeLine(command); + informListener(SvdrpEvent.COMMAND_SENT); + Log.i(TAG, SvdrpEvent.COMMAND_SENT + ":" + command); + + // get the answer for the compress command or + // the first line of the answer for the command + String line = readLine(); + if (line.startsWith("!OK")) { + final String[] words = line.split(" "); + if (words.length > 1) { + final String mode = words[1].toUpperCase(); + if (mode.equals("ZLIB")) { + Log.i(TAG, "ZLIB compression activated"); + inputStream = new InflaterInputStream(inputStream); + } else if (mode.equals("GZIP")) { + Log.i(TAG, "GZIP compression activated"); + inputStream = new GZIPInputStream(inputStream); + } else { + Log.i(TAG, "NO compression activated"); + } + } + line = readLine(); + } else { + Log.i(TAG, "NO compression activated"); + } + + // correct answer? + if (!line.startsWith("START")) { + Log.w(TAG, line); + throw new IOException("Answer not wellformed: " + line); + } + + // read answer lines + for (; !abort;) { + + // get next line + line = readLine(); + if (line.length() == 0) { + break; + } + + // last line? + if (line.startsWith("END")) { + break; + } + + // error? + if (line.startsWith("!ERROR")) { + Log.w(TAG, line); + String msg; + if (line.startsWith("!ERROR:")) { + msg = line.substring(7); + } else { + msg = line; + } + disconnect(); + informListener(SvdrpEvent.ERROR, new SvdrpException(msg)); + break; + } + + // delegate analysis + Result result = null; + try { + result = parseAnswer(line); + + } catch (final Exception ex) { + Log.w(TAG, ex); + disconnect(); + Log.w(TAG, "line: " + line); + informListener(SvdrpEvent.ERROR, ex); + return; + } + if (result != null) { + informListener(result); + // results.add(result); + // if (resultInfoEnabled) { + + // } + } + + } + + // disconnect + disconnect(); + + if (abort) { + informListener(SvdrpEvent.ABORTED); + } else { + informListener(SvdrpEvent.FINISHED_SUCCESS); + } + + } catch (final Exception e) { + Log.w(TAG, e); + informListener(SvdrpEvent.FINISHED_ABNORMALY, e); + } + } + + // public void setResultInfoEnabled(final boolean resultInfoEnabled) { + // this.resultInfoEnabled = resultInfoEnabled; + // } + + protected void informListener(final SvdrpEvent event, final Throwable e) { + for (final SvdrpExceptionListener listener : svdrpExceptionListeners) { + listener.svdrpEvent(event, e); + } + } + + protected void informListener(final SvdrpEvent event) { + for (final SvdrpListener listener : svdrpListeners) { + listener.svdrpEvent(event); + } + } + + protected void informListener(final Result result) { + for (final SvdrpResultListener listener : svdrpResultListeners) { + listener.svdrpEvent(result); + } + } } -- cgit v1.2.3