]> Pileus Git - ~andy/spades/blob - src/Task.java
Suppress warnings
[~andy/spades] / src / Task.java
1 package org.pileus.spades;
2
3 import java.util.List;
4 import java.util.LinkedList;
5 import java.util.concurrent.locks.Lock;
6 import java.util.concurrent.locks.ReentrantLock;
7
8 import android.app.Notification;
9 import android.app.PendingIntent;
10 import android.app.Service;
11 import android.content.Context;
12 import android.content.Intent;
13 import android.content.SharedPreferences;
14 import android.os.IBinder;
15 import android.os.Looper;
16 import android.os.Messenger;
17 import android.preference.PreferenceManager;
18
19 public class Task extends Service implements Runnable
20 {
21         /* Commands */
22         public static final int REGISTER   = 0;
23         public static final int MESSAGE    = 1;
24         public static final int CONNECT    = 2;
25         public static final int DISCONNECT = 3;
26         public static final int NOTIFY     = 4;
27
28         /* Private data */
29         private SharedPreferences prefs;
30         private Messenger         messenger;
31         private Thread            thread;
32         private Client            client;
33         private List<Object>      log;
34         private Lock              lock;
35
36         /* Private methods */
37         private void command(int cmd, Object value)
38         {
39                 if (cmd == MESSAGE || cmd == NOTIFY) {
40                         this.lock.lock();
41                         this.log.add(value);
42                         this.lock.unlock();
43                 }
44                 try {
45                         android.os.Message msg = android.os.Message.obtain();
46                         msg.what = cmd;
47                         msg.obj  = value;
48                         this.messenger.send(msg);
49                 } catch (Exception e) {
50                         Os.debug("Task: error sending message", e);
51                 }
52         }
53
54         @SuppressWarnings("deprecation")
55         private void notify(String text, int icon)
56         {
57                 // Notify Main
58                 this.command(NOTIFY, text);
59
60                 // Notification bar
61                 Notification  note   = new Notification(icon, null, 0);
62                 Intent        intent = new Intent(this, Main.class);
63                 PendingIntent pend   = PendingIntent.getActivity(this, 0, intent, 0);
64
65                 note.setLatestEventInfo(this, "Spades!", text, pend);
66                 this.startForeground(1, note);
67         }
68
69         private void handle(int cmd, Messenger mgr)
70         {
71                 // Validate messenger
72                 if (cmd != REGISTER && mgr != null && mgr != this.messenger) {
73                         Os.debug("Task: handle - invalid messenger");
74                 }
75
76                 // Setup communication with Main
77                 if (cmd == REGISTER) {
78                         Os.debug("Task: handle - register");
79                         this.messenger = mgr;
80                         this.command(REGISTER, this);
81                 }
82
83                 // Create client thread
84                 if (cmd == CONNECT && this.thread == null) {
85                         Os.debug("Task: handle - connect");
86                         this.thread = new Thread(this);
87                         this.thread.start();
88                 }
89
90                 // Stop client thread
91                 if (cmd == DISCONNECT && this.thread != null) {
92                         Os.debug("Task: handle - register");
93                         try {
94                                 this.client.abort();
95                                 this.thread.join();
96                         } catch (Exception e) {
97                                 Os.debug("Task: error stopping service", e);
98                         }
99                 }
100         }
101
102         /* Public methods */
103         public Message send(String txt)
104         {
105                 if (this.client == null)
106                         return null;
107                 Message msg = this.client.send(txt);
108                 if (msg != null)
109                         this.command(MESSAGE, msg);
110                 return msg;
111         }
112
113         public List<Object> getLog()
114         {
115                 this.lock.lock();
116                 LinkedList<Object> out = new LinkedList<Object>(this.log);
117                 this.lock.unlock();
118                 return out;
119         }
120
121         public boolean isRunning()
122         {
123                 return this.thread != null;
124         }
125
126         /* Runnable methods */
127         @Override
128         public void run()
129         {
130                 Os.debug("Task: thread run");
131
132                 // Setup notification bar
133                 this.notify("Connecting..", android.R.drawable.presence_invisible);
134
135                 // Grab preferences
136                 String  server   = this.prefs.getString ("pref_server",   this.client.server);
137                 String  port     = this.prefs.getString ("pref_port",     this.client.port + "");
138                 String  nickname = this.prefs.getString ("pref_nickname", this.client.nickname);
139                 String  channel  = this.prefs.getString ("pref_channel",  this.client.channel);
140                 boolean usesasl  = this.prefs.getBoolean("pref_usesasl",  this.client.usesasl);
141                 String  authname = this.prefs.getString ("pref_authname", this.client.authname);
142                 String  password = this.prefs.getString ("pref_password", this.client.password);
143
144                 // Update client settings
145                 this.client.setServer(server, Integer.parseInt(port));
146                 this.client.setUser(nickname, channel);
147                 this.client.setAuth(usesasl, authname, password);
148
149                 // Start connecting
150                 if (!this.client.connect()) {
151                         this.command(DISCONNECT, null);
152                         this.notify("Unable to connect", android.R.drawable.presence_offline);
153                         this.thread = null;
154                         return;
155                 }
156
157                 // Wait for login
158                 while (this.client.state == Client.State.SETUP) {
159                         Message msg = this.client.recv();
160                         if (msg == null)
161                                 break;
162                         this.command(MESSAGE, msg);
163                 }
164
165                 // Notify connection status
166                 if (this.client.state == Client.State.READY) {
167                         this.command(CONNECT, null);
168                         this.notify("Connected", android.R.drawable.presence_online);
169                 } else {
170                         this.command(DISCONNECT, null);
171                         this.notify("Connetion aborted", android.R.drawable.presence_offline);
172                 }
173
174                 // Process messages
175                 while (this.client.state == Client.State.READY) {
176                         Message msg = this.client.recv();
177                         if (msg == null)
178                                 break;
179                         this.command(MESSAGE, msg);
180                 }
181
182                 // Notify disconnect disconnected
183                 this.notify("Disconnected", android.R.drawable.presence_offline);
184                 this.command(DISCONNECT, null);
185
186                 // Shutdown the client
187                 this.client.abort();
188                 this.thread = null;
189
190                 Os.debug("Task: thread exit");
191         }
192
193         /* Service Methods */
194         @Override
195         public void onCreate()
196         {
197                 Os.debug("Task: onCreate");
198                 super.onCreate();
199
200                 this.log    = new LinkedList<Object>();
201                 this.lock   = new ReentrantLock();
202                 this.client = new Client();
203                 this.prefs  = PreferenceManager.getDefaultSharedPreferences(this);
204         }
205
206         @Override
207         public void onDestroy()
208         {
209                 Os.debug("Task: onDestroy");
210                 this.handle(DISCONNECT, null);
211         }
212
213         @Override
214         @SuppressWarnings("deprecation")
215         public void onStart(Intent intent, int startId)
216         {
217                 Os.debug("Task: onStart");
218                 super.onStart(intent, startId);
219                 int       cmd = intent.getExtras().getInt("Command");
220                 Messenger mgr = (Messenger)intent.getExtras().get("Messenger");
221                 this.handle(cmd, mgr);
222         }
223
224         @Override
225         public IBinder onBind(Intent intent)
226         {
227                 Os.debug("Task: onBind");
228                 return null;
229         }
230 }