]> Pileus Git - ~andy/spades/blobdiff - src/org/pileus/spades/Task.java
Improve client modeing
[~andy/spades] / src / org / pileus / spades / Task.java
index 5aad096554237ec13cc761ccf385cdb2ec994b08..ac1a243bf3073fd2988f949ce2a703195dcbd798 100644 (file)
@@ -1,31 +1,46 @@
 package org.pileus.spades;
 
+import java.util.List;
+import java.util.LinkedList;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.Messenger;
+import android.preference.PreferenceManager;
 
 public class Task extends Service implements Runnable
 {
        /* Commands */
-       public static final int REGISTER = 0;
-       public static final int MESSAGE  = 1;
-
-       /* Configuration */
-       private String    server    = "irc.freenode.net";
-       private String    nickname  = "andydroid";
-       private String    channel   = "#rhnoise";
+       public static final int REGISTER   = 0;
+       public static final int MESSAGE    = 1;
+       public static final int CONNECT    = 2;
+       public static final int DISCONNECT = 3;
+       public static final int NOTIFY     = 4;
 
        /* Private data */
-       private Messenger messenger = null;
-       private Thread    thread    = null;
-       private Client    client    = null;
+       private SharedPreferences prefs;
+       private Messenger         messenger;
+       private Thread            thread;
+       private Client            client;
+       private List<Object>      log;
+       private Lock              lock;
 
        /* Private methods */
        private void command(int cmd, Object value)
        {
+               if (cmd == MESSAGE || cmd == NOTIFY) {
+                       this.lock.lock();
+                       this.log.add(value);
+                       this.lock.unlock();
+               }
                try {
                        android.os.Message msg = android.os.Message.obtain();
                        msg.what = cmd;
@@ -36,12 +51,70 @@ public class Task extends Service implements Runnable
                }
        }
 
+       private void notify(String text, int icon)
+       {
+               // Notify Main
+               this.command(NOTIFY, text);
+
+               // Notification bar
+               Notification  note   = new Notification(icon, null, 0);
+               Intent        intent = new Intent(this, Main.class);
+               PendingIntent pend   = PendingIntent.getActivity(this, 0, intent, 0);
+
+               note.setLatestEventInfo(this, "Spades!", text, pend);
+               this.startForeground(1, note);
+       }
+
+       private void handle(int cmd, Messenger mgr)
+       {
+               // Setup communication with Main
+               if (cmd == REGISTER) {
+                       Os.debug("Task: handle - register");
+                       this.messenger = mgr;
+                       this.command(REGISTER, this);
+               }
+
+               // Create client thread
+               if (cmd == CONNECT && this.thread == null) {
+                       Os.debug("Task: handle - connect");
+                       this.thread = new Thread(this);
+                       this.thread.start();
+               }
+
+               // Stop client thread
+               if (cmd == DISCONNECT && this.thread != null) {
+                       Os.debug("Task: handle - register");
+                       try {
+                               this.client.abort();
+                               this.thread.join();
+                       } catch (Exception e) {
+                               Os.debug("Task: error stopping service", e);
+                       }
+               }
+       }
+
        /* Public methods */
        public Message send(String txt)
        {
                if (this.client == null)
                        return null;
-               return this.client.send(txt);
+               Message msg = this.client.send(txt);
+               if (msg != null)
+                       this.command(MESSAGE, msg);
+               return msg;
+       }
+
+       public List<Object> getLog()
+       {
+               this.lock.lock();
+               LinkedList<Object> out = new LinkedList<Object>(this.log);
+               this.lock.unlock();
+               return out;
+       }
+
+       public boolean isRunning()
+       {
+               return this.thread != null;
        }
 
        /* Runnable methods */
@@ -50,18 +123,63 @@ public class Task extends Service implements Runnable
        {
                Os.debug("Task: thread run");
 
-               if (!client.connect(server, nickname, channel))
+               // Setup notification bar
+               this.notify("Connecting..", android.R.drawable.presence_invisible);
+
+               // Grab preferences
+               String  server   = this.prefs.getString ("pref_server",   this.client.server);
+               String  port     = this.prefs.getString ("pref_port",     this.client.port + "");
+               String  nickname = this.prefs.getString ("pref_nickname", this.client.nickname);
+               String  channel  = this.prefs.getString ("pref_channel",  this.client.channel);
+               boolean usesasl  = this.prefs.getBoolean("pref_usesasl",  this.client.usesasl);
+               String  authname = this.prefs.getString ("pref_authname", this.client.authname);
+               String  password = this.prefs.getString ("pref_password", this.client.password);
+
+               // Update client settings
+               this.client.setServer(server, Integer.parseInt(port));
+               this.client.setUser(nickname, channel);
+               this.client.setAuth(usesasl, authname, password);
+
+               // Start connecting
+               if (!this.client.connect()) {
+                       this.command(DISCONNECT, null);
+                       this.notify("Unable to connect", android.R.drawable.presence_offline);
+                       this.thread = null;
                        return;
+               }
 
-               while (true) {
-                       Message msg = client.recv();
+               // Wait for login
+               while (this.client.state == Client.State.SETUP) {
+                       Message msg = this.client.recv();
                        if (msg == null)
                                break;
                        this.command(MESSAGE, msg);
                }
 
-               if (!client.abort())
-                       return;
+               // Notify connection status
+               if (this.client.state == Client.State.READY) {
+                       this.command(CONNECT, null);
+                       this.notify("Connected", android.R.drawable.presence_online);
+               } else {
+                       this.command(DISCONNECT, null);
+                       this.notify("Connetion aborted", android.R.drawable.presence_offline);
+               }
+
+               // Process messages
+               while (this.client.state == Client.State.READY) {
+                       Message msg = this.client.recv();
+                       if (msg == null)
+                               break;
+                       this.command(MESSAGE, msg);
+               }
+
+               // Notify disconnect disconnected
+               this.notify("Disconnected", android.R.drawable.presence_offline);
+               this.command(DISCONNECT, null);
+
+               // Shutdown the client
+               this.client.abort();
+               this.thread = null;
 
                Os.debug("Task: thread exit");
        }
@@ -73,39 +191,27 @@ public class Task extends Service implements Runnable
                Os.debug("Task: onCreate");
                super.onCreate();
 
-               /* Setup notification bar */
-               Notification  note   = new Notification(android.R.drawable.presence_online, null, 0);
-               Intent        intent = new Intent(this, Main.class);
-               PendingIntent pend   = PendingIntent.getActivity(this, 0, intent, 0);
-
-               note.setLatestEventInfo(this, "Spades Title", "Spades Message", pend);
-               startForeground(1, note);
-
-               /* Start client thread */
-               client = new Client();
-               thread = new Thread(this);
-               thread.start();
+               this.log    = new LinkedList<Object>();
+               this.lock   = new ReentrantLock();
+               this.client = new Client();
+               this.prefs  = PreferenceManager.getDefaultSharedPreferences(this);
        }
-        
+
        @Override
        public void onDestroy()
        {
                Os.debug("Task: onDestroy");
-               try {
-                       this.client.abort();
-                       this.thread.join();
-               } catch (Exception e) {
-                       Os.debug("Task: error stopping service", e);
-               }
+               this.handle(DISCONNECT, null);
        }
-        
+
        @Override
        public void onStart(Intent intent, int startId)
        {
                Os.debug("Task: onStart");
                super.onStart(intent, startId);
-               this.messenger = (Messenger)intent.getExtras().get("Messenger");
-               this.command(REGISTER, this);
+               int       cmd = intent.getExtras().getInt("Command");
+               Messenger mgr = (Messenger)intent.getExtras().get("Messenger");
+               this.handle(cmd, mgr);
        }
 
        @Override