]> Joshua Wise's Git repositories - dumload.git/blame - src/com/joshuawise/dumload/Uploader.java
Invoke pscale remotely.
[dumload.git] / src / com / joshuawise / dumload / Uploader.java
CommitLineData
0763e16d
JW
1package com.joshuawise.dumload;
2
3import java.io.InputStream;
035767ac 4import java.io.OutputStream;
0763e16d
JW
5
6import com.jcraft.jsch.*;
7import java.lang.Boolean;
8
9import android.app.Activity;
10import android.app.Service;
11import android.content.Intent;
12import android.app.PendingIntent;
13import android.content.Context;
14import android.net.Uri;
15import android.os.Bundle;
16import android.os.IBinder;
17import android.widget.TextView;
18import android.widget.Toast;
19import android.util.Log;
20import android.app.NotificationManager;
21import android.app.Notification;
22import android.os.Handler;
23import android.os.Messenger;
24import android.os.Looper;
25import android.os.Message;
26import android.os.SystemClock;
ae61bba6 27import android.widget.RemoteViews;
0763e16d
JW
28
29public class Uploader extends Service implements Runnable, UserInfo, UIKeyboardInteractive {
30 private Uri uri;
31 private String homedir;
32 private Thread me;
33 private static final int HELPME_ID = 1;
ae61bba6
JW
34 private RemoteViews remote;
35 private int thenotifid;
36 private Notification thenotif;
37 private String headline;
0763e16d 38
035767ac
JW
39 private InputStream is;
40
0763e16d
JW
41 public Object _theObject;
42
ae61bba6
JW
43 private void sayNullNotification(final String scroller, final String headline, final String description)
44 {
45 int bogon = (int)SystemClock.elapsedRealtime();
46 NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
47 Notification notification = new Notification(R.drawable.icon, scroller, System.currentTimeMillis());
48
49 Intent intent = new Intent(this, NotifSlave.class);
50
51 intent.setAction("com.joshuawise.dumload.NotifSlave");
52 /* no extras to make the notifslave die */
53 intent.setData((Uri.parse("suckit://"+SystemClock.elapsedRealtime())));
54
55 PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
56 notification.defaults |= Notification.DEFAULT_VIBRATE;
57 notification.flags |= Notification.FLAG_AUTO_CANCEL;
58 notification.setLatestEventInfo(getApplicationContext(), headline, description, contentIntent);
59
60 mNotificationManager.notify(bogon, notification);
61 }
62
0763e16d
JW
63 private Object /* pick one type, and fixate on it */ dance(final String type, final String text) /* for inside the thread */
64 {
65 final Uploader thisupl = this;
66 final Message msg = Message.obtain();
67
68 /* t(*A*t) */
69 Thread t = new Thread() {
70 public void run() {
71 Looper.prepare();
72 int bogon = (int)SystemClock.elapsedRealtime();
73
74 NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
75 Notification notification = new Notification(R.drawable.icon, "Dumload prompt", System.currentTimeMillis());
76
77 Handler h = new Handler() {
78 public void handleMessage(Message M) {
79 msg.copyFrom(M);
80 Looper.myLooper().quit();
81 }
82 };
83 Messenger m = new Messenger(h);
84
85 Intent intent = new Intent(thisupl, NotifSlave.class);
86
87 intent.setAction("com.joshuawise.dumload.NotifSlave");
88 intent.putExtra("com.joshuawise.dumload.returnmessenger", m);
89 intent.putExtra("com.joshuawise.dumload.reqtype", type);
90 intent.putExtra("com.joshuawise.dumload.prompt", text);
91 intent.setData((Uri.parse("suckit://"+SystemClock.elapsedRealtime())));
92
93 PendingIntent contentIntent = PendingIntent.getActivity(thisupl, 0, intent, 0);
94 notification.defaults |= Notification.DEFAULT_VIBRATE;
ae61bba6 95 notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
0763e16d
JW
96 notification.setLatestEventInfo(getApplicationContext(), "I've been had!", "Dumload needs your input.", contentIntent);
97
98 Log.e("Dumload.Uploader[thread]", "Notifying...");
99
100 mNotificationManager.notify(bogon, notification);
101
102 Log.e("Dumload.Uploader[thread]", "About to go to 'sleep'...");
103 Looper.loop();
104 Log.e("Dumload.Uploader[thread]", "And we're alive!");
105
106 Log.e("Dumload.Uploader[thread]", "result was: "+(Integer.toString(msg.arg1)));
107
108 mNotificationManager.cancel(bogon);
109 }
110 };
111
112 t.start();
113 try {
114 t.join();
115 } catch (Exception e) {
116 return null;
117 }
118
119 if (type.equals("yesno"))
120 return new Boolean(msg.arg1 == 1);
121 else if (type.equals("message"))
122 return null;
123 else if (type.equals("password")) {
124 if (msg.arg1 == 0)
125 return null;
126 Bundle b = msg.getData();
127 return b.getString("response");
128 } else
129 return null;
130 }
131
132 /* UserInfo bits */
133 String _password = null;
134 public String getPassword()
135 {
136 return _password;
137 }
138 public boolean promptPassword(String message)
139 {
140 _password = (String)dance("password", message);
141 return (_password != null);
142 }
143
144 String _passphrase = null;
145 public String getPassphrase()
146 {
147 return _passphrase;
148 }
149 public boolean promptPassphrase(String message)
150 {
151 _passphrase = (String)dance("password", message);
152 return (_passphrase != null);
153 }
154
155 public boolean promptYesNo(String str)
156 {
157 return ((Boolean)dance("yesno", str)).booleanValue();
158 }
159
160 public void showMessage(String str)
161 {
162 dance("message", str);
163 }
164
165 public String[] promptKeyboardInteractive(String dest, String name, String instr, String[] prompt, boolean[] echo)
166 {
167 int i;
168 String [] responses = new String[prompt.length];
169
170 Log.e("Dumload.Uploader", "dest: "+dest);
171 Log.e("Dumload.Uploader", "name: "+name);
172 Log.e("Dumload.Uploader", "instr: "+instr);
173 for (i = 0; i < prompt.length; i++)
174 {
175 responses[i] = (String) dance("password", "[" + dest + "]\n" + prompt[i]);
ae61bba6
JW
176 if (responses[i] == null)
177 return null;
0763e16d
JW
178 }
179 return responses;
180 }
181
035767ac
JW
182 private void expect_ack(InputStream in) throws Exception, java.io.IOException
183 {
184 int b = in.read();
185
186 if (b == -1)
187 {
188 throw new Exception("unexpected EOF from remote end");
189 }
190
191 if (b == 1 /* error */ || b == 2 /* fatal error */)
192 {
193 StringBuffer sb = new StringBuffer();
194 int c = 0;
195
196 while ((c = in.read()) != '\n')
197 sb.append((char)c);
198
199 throw new Exception("error from remote end: " + sb.toString());
200 }
201 }
202
ae61bba6
JW
203 private void set_up_notif(final String _headline)
204 {
205 NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
206 thenotif = new Notification(R.drawable.icon, headline, System.currentTimeMillis());
207 thenotifid = (int)SystemClock.elapsedRealtime();
208
209 Intent intent = new Intent(this, NotifSlave.class);
210
211 headline = _headline;
212
213 intent.setAction("com.joshuawise.dumload.NotifSlave");
214 /* no extras to make the notifslave die */
215 intent.setData((Uri.parse("suckit://"+SystemClock.elapsedRealtime())));
216
217 PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
218 thenotif.defaults |= 0;
219 thenotif.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
220
221 remote = new RemoteViews(getPackageName(), R.layout.textnotif);
222 remote.setImageViewResource(R.id.image, R.drawable.icon);
223 remote.setTextViewText(R.id.headline, headline);
224 remote.setTextViewText(R.id.status, "Beginning upload...");
225 thenotif.contentView = remote;
226 thenotif.contentIntent = contentIntent;
227
228 mNotificationManager.notify(thenotifid, thenotif);
229 }
230
231 private void destroy_notif()
232 {
233 NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
234 mNotificationManager.cancel(thenotifid);
235 }
236
237 private void update_notif(String text)
238 {
239 NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
240
241 remote = new RemoteViews(getPackageName(), R.layout.textnotif);
242 remote.setImageViewResource(R.id.image, R.drawable.icon);
243 remote.setTextViewText(R.id.headline, headline);
244 remote.setTextViewText(R.id.status, text);
245 thenotif.contentView = remote;
246
247 mNotificationManager.notify(thenotifid, thenotif);
248 }
249
250 private void update_notif(int n, int total)
251 {
252 NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
253
254 remote = new RemoteViews(getPackageName(), R.layout.progressnotif);
255 remote.setImageViewResource(R.id.image, R.drawable.icon);
256 remote.setTextViewText(R.id.headline, headline);
257 remote.setProgressBar(R.id.status, total, n, false);
258 thenotif.contentView = remote;
259
260 mNotificationManager.notify(thenotifid, thenotif);
261 }
262
0763e16d
JW
263 @Override
264 public void run()
265 {
266 Looper.prepare();
267
268 Log.e("Dumload.Uploader[thread]", "This brought to you from the new thread.");
269
ae61bba6
JW
270 set_up_notif("Dumload upload in progress");
271
0763e16d 272 try {
035767ac
JW
273 say("Uploading "+(Integer.toString(is.available()))+" bytes");
274
ae61bba6
JW
275 update_notif("Connecting...");
276
0763e16d
JW
277 JSch jsch = new JSch();
278 jsch.setKnownHosts(homedir + "/known_hosts");
279 Session s = jsch.getSession("joshua", "nyus.joshuawise.com", 22);
280 s.setUserInfo(this);
281 s.connect();
282
283 Channel channel = s.openChannel("exec");
e1916520 284 ((ChannelExec)channel).setCommand("scp -t /tmp/lol.jpg");
0763e16d
JW
285 channel.connect();
286
035767ac
JW
287 OutputStream scp_out = channel.getOutputStream();
288 InputStream scp_in = channel.getInputStream();
289
ae61bba6
JW
290 update_notif("Starting send...");
291
035767ac
JW
292 /* Okay, BS out of the way. Now go send the file. */
293 expect_ack(scp_in);
294
e1916520 295 scp_out.write(("C0644 " + (Integer.toString(is.available())) + " lol.jpg\n").getBytes());
035767ac
JW
296 scp_out.flush();
297
298 expect_ack(scp_in);
299
ae61bba6
JW
300 int total, nbytes;
301 total = is.available();
302 nbytes = 0;
035767ac
JW
303 int len;
304 byte[] buf = new byte[4096];
305 while ((len = is.read(buf, 0, buf.length)) > 0)
ae61bba6 306 {
035767ac 307 scp_out.write(buf, 0, len);
ae61bba6
JW
308 nbytes += len;
309 update_notif(nbytes, total);
310 }
035767ac
JW
311
312 is.close();
313
e1916520 314 update_notif("Finishing file transfer...");
ae61bba6 315
035767ac
JW
316 scp_out.write("\0".getBytes());
317 scp_out.flush();
318
319 expect_ack(scp_in);
320
e1916520
JW
321 channel.disconnect();
322
323 update_notif("Preparing to resize image...");
324
325 channel = s.openChannel("exec");
326 ((ChannelExec)channel).setCommand("pscale /tmp/lol.jpg");
327 channel.connect();
328
329 scp_in = channel.getInputStream();
330
331 update_notif("Resizing image...");
332 while ((len = scp_in.read(buf, 0, buf.length)) > 0)
333 ;
334
335 channel.disconnect();
336 update_notif("Upload complete.");
337
ae61bba6 338 sayNullNotification("Dumload upload complete", "Upload complete", "Dumload has finished uploading your file.");
0763e16d 339
0763e16d 340 s.disconnect();
035767ac 341 } catch (Exception e) {
0763e16d 342 Log.e("Dumload.uploader[thread]", "JSchException: "+(e.toString()));
ae61bba6 343 sayNullNotification("Dumload upload failed", "Upload failed", e.toString());
0763e16d
JW
344 }
345
ae61bba6
JW
346 destroy_notif();
347
0763e16d
JW
348 Log.e("Dumload.uploader[thread]", "And now I'm back to life!");
349 }
350
351 private void say(String s) {
352 Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
353 }
354
355 @Override
356 public void onStart(Intent i, int startId)
357 {
358 uri = i.getData();
359 homedir = getApplicationContext().getFilesDir().getAbsolutePath();
360 int shits = 0;
361
362 super.onStart(i, startId);
363
364 Log.e("Dumload.Uploader", "Started.");
365 Log.e("Dumload.Uploader", "My path is "+homedir);
366
367 try {
035767ac 368 is = getContentResolver().openInputStream(uri);
0763e16d 369 } catch (Exception e) {
035767ac
JW
370 say("Failed to open input file.");
371 return;
0763e16d
JW
372 }
373
0763e16d
JW
374
375 me = new Thread(this, "Uploader thread");
376 me.start();
377 }
378
379 @Override
380 public IBinder onBind(Intent i) {
381 Log.e("Dumload.Uploader", "bound");
382
383 return null;
384 }
385}
This page took 0.058294 seconds and 4 git commands to generate.