]> Pileus Git - ~andy/spades/blob - src/org/pileus/spades/Task.java
Improve connection handling
[~andy/spades] / src / org / pileus / spades / Task.java
1 package org.pileus.spades;
2
3 import android.app.Notification;
4 import android.app.PendingIntent;
5 import android.app.Service;
6 import android.content.Context;
7 import android.content.Intent;
8 import android.os.IBinder;
9 import android.os.Looper;
10 import android.os.Messenger;
11 import android.widget.Toast;
12
13 public class Task extends Service implements Runnable
14 {
15         /* Commands */
16         public static final int REGISTER   = 0;
17         public static final int MESSAGE    = 1;
18         public static final int CONNECT    = 2;
19         public static final int DISCONNECT = 3;
20
21         /* Configuration */
22         private String    server    = "irc.freenode.net";
23         private String    nickname  = "andydroid";
24         private String    channel   = "#rhnoise";
25
26         /* Private data */
27         private Messenger messenger = null;
28         private Thread    thread    = null;
29         private Client    client    = null;
30         private Toast     toast     = null;
31
32         /* Private methods */
33         private void command(int cmd, Object value)
34         {
35                 try {
36                         android.os.Message msg = android.os.Message.obtain();
37                         msg.what = cmd;
38                         msg.obj  = value;
39                         this.messenger.send(msg);
40                 } catch (Exception e) {
41                         Os.debug("Task: error sending message");
42                 }
43         }
44
45         private void notify(String text, int icon)
46         {
47                 // Log
48                 Os.debug("Task: notify - " + text);
49
50                 // Toast
51                 this.toast.setText(text);
52                 this.toast.show();
53
54                 // Notify
55                 Notification  note   = new Notification(icon, null, 0);
56                 Intent        intent = new Intent(this, Main.class);
57                 PendingIntent pend   = PendingIntent.getActivity(this, 0, intent, 0);
58
59                 note.setLatestEventInfo(this, "Spades!", text, pend);
60                 this.startForeground(1, note);
61         }
62
63         /* Public methods */
64         public Message send(String txt)
65         {
66                 if (this.client == null)
67                         return null;
68                 Message msg = this.client.send(txt);
69                 if (msg != null)
70                         this.command(MESSAGE, msg);
71                 return msg;
72         }
73
74         /* Runnable methods */
75         @Override
76         public void run()
77         {
78                 Os.debug("Task: thread run");
79
80                 // Android Toast setup
81                 Looper.prepare();
82
83                 // Setup notification bar
84                 this.notify("Connecting..", android.R.drawable.presence_invisible);
85
86                 // Start connecting
87                 if (!this.client.connect(server, nickname, channel)) {
88                         this.command(DISCONNECT, null);
89                         this.notify("Unable to connect", android.R.drawable.presence_offline);
90                         this.thread = null;
91                         return;
92                 }
93
94                 // Wait for login
95                 while (!this.client.ready) {
96                         Message msg = this.client.recv();
97                         if (msg == null)
98                                 break;
99                         this.command(MESSAGE, msg);
100                 }
101
102                 // Notify connection status
103                 if (this.client.ready) {
104                         this.command(CONNECT, null);
105                         this.notify("Connected", android.R.drawable.presence_online);
106                 } else {
107                         this.command(DISCONNECT, null);
108                         this.notify("Connetion aborted", android.R.drawable.presence_offline);
109                 }
110
111                 // Process messages
112                 while (this.client.ready) {
113                         Message msg = this.client.recv();
114                         if (msg == null)
115                                 break;
116                         this.command(MESSAGE, msg);
117                 }
118
119                 // Notify disconnect disconnected
120                 this.notify("Disconnected", android.R.drawable.presence_offline);
121                 this.command(DISCONNECT, null);
122
123                 // Shutdown the client
124                 this.client.abort();
125                 this.thread = null;
126
127                 Os.debug("Task: thread exit");
128         }
129
130         /* Service Methods */
131         @Override
132         public void onCreate()
133         {
134                 Os.debug("Task: onCreate");
135                 super.onCreate();
136
137                 // Setup toast
138                 Context context = this.getApplicationContext();
139                 this.toast = Toast.makeText(context, "", Toast.LENGTH_SHORT);
140
141                 // Create the client
142                 this.client = new Client();
143         }
144         
145         @Override
146         public void onDestroy()
147         {
148                 Os.debug("Task: onDestroy");
149                 try {
150                         this.client.abort();
151                         this.thread.join();
152                 } catch (Exception e) {
153                         Os.debug("Task: error stopping service", e);
154                 }
155         }
156         
157         @Override
158         public void onStart(Intent intent, int startId)
159         {
160                 Os.debug("Task: onStart");
161                 super.onStart(intent, startId);
162
163                 // Setup communication with Main
164                 this.messenger = (Messenger)intent.getExtras().get("Messenger");
165                 this.command(REGISTER, this);
166
167                 // Create client thread
168                 if (this.thread == null) {
169                         this.thread = new Thread(this);
170                         this.thread.start();
171                 }
172         }
173
174         @Override
175         public IBinder onBind(Intent intent)
176         {
177                 Os.debug("Task: onBind");
178                 return null;
179         }
180 }