1 | //========================================================================
|
---|
2 | //$Id: IJetty.java 474 2012-01-23 03:07:14Z janb.webtide $
|
---|
3 | //Copyright 2008 Mort Bay Consulting Pty. Ltd.
|
---|
4 | //------------------------------------------------------------------------
|
---|
5 | //Licensed under the Apache License, Version 2.0 (the "License");
|
---|
6 | //you may not use this file except in compliance with the License.
|
---|
7 | //You may obtain a copy of the License at
|
---|
8 | //http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | //Unless required by applicable law or agreed to in writing, software
|
---|
10 | //distributed under the License is distributed on an "AS IS" BASIS,
|
---|
11 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
12 | //See the License for the specific language governing permissions and
|
---|
13 | //limitations under the License.
|
---|
14 | //========================================================================
|
---|
15 |
|
---|
16 | package org.mortbay.ijetty;
|
---|
17 |
|
---|
18 | import java.io.File;
|
---|
19 | import java.io.FileInputStream;
|
---|
20 | import java.io.FileOutputStream;
|
---|
21 | import java.io.InputStream;
|
---|
22 | import java.io.ObjectInputStream;
|
---|
23 | import java.io.ObjectOutputStream;
|
---|
24 | import java.io.OutputStream;
|
---|
25 | import java.net.InetAddress;
|
---|
26 | import java.net.NetworkInterface;
|
---|
27 | import java.net.SocketException;
|
---|
28 | import java.util.Collections;
|
---|
29 | import java.util.Date;
|
---|
30 | import java.util.Enumeration;
|
---|
31 |
|
---|
32 | import org.eclipse.jetty.util.IO;
|
---|
33 | import org.mortbay.ijetty.log.AndroidLog;
|
---|
34 | import org.mortbay.ijetty.util.AndroidInfo;
|
---|
35 | import org.mortbay.ijetty.util.IJettyToast;
|
---|
36 |
|
---|
37 | import android.app.Activity;
|
---|
38 | import android.app.Dialog;
|
---|
39 | import android.app.ProgressDialog;
|
---|
40 | import android.content.BroadcastReceiver;
|
---|
41 | import android.content.Context;
|
---|
42 | import android.content.Intent;
|
---|
43 | import android.content.IntentFilter;
|
---|
44 | import android.content.pm.PackageInfo;
|
---|
45 | import android.content.pm.PackageManager.NameNotFoundException;
|
---|
46 | import android.os.Bundle;
|
---|
47 | import android.os.Environment;
|
---|
48 | import android.os.Handler;
|
---|
49 | import android.os.Message;
|
---|
50 | import android.text.Html;
|
---|
51 | import android.util.Log;
|
---|
52 | import android.view.View;
|
---|
53 | import android.view.View.OnClickListener;
|
---|
54 | import android.widget.Button;
|
---|
55 | import android.widget.ScrollView;
|
---|
56 | import android.widget.TextView;
|
---|
57 |
|
---|
58 | /**
|
---|
59 | * IJetty
|
---|
60 | *
|
---|
61 | * Main Jetty activity. Can start other activities: + configure + download
|
---|
62 | *
|
---|
63 | * Can start/stop services: + IJettyService
|
---|
64 | */
|
---|
65 | public class IJetty extends Activity
|
---|
66 | {
|
---|
67 |
|
---|
68 | private static final String TAG = "Jetty";
|
---|
69 |
|
---|
70 | public static final String __START_ACTION = "org.mortbay.ijetty.start";
|
---|
71 | public static final String __STOP_ACTION = "org.mortbay.ijetty.stop";
|
---|
72 |
|
---|
73 | public static final String __PORT = "org.mortbay.ijetty.port";
|
---|
74 | public static final String __NIO = "org.mortbay.ijetty.nio";
|
---|
75 | public static final String __SSL = "org.mortbay.ijetty.ssl";
|
---|
76 |
|
---|
77 | public static final String __CONSOLE_PWD = "org.mortbay.ijetty.console";
|
---|
78 | public static final String __PORT_DEFAULT = "8080";
|
---|
79 | public static final boolean __NIO_DEFAULT = true;
|
---|
80 | public static final boolean __SSL_DEFAULT = false;
|
---|
81 |
|
---|
82 | public static final String __CONSOLE_PWD_DEFAULT = "admin";
|
---|
83 |
|
---|
84 | public static final String __WEBAPP_DIR = "webapps";
|
---|
85 | public static final String __ETC_DIR = "etc";
|
---|
86 | public static final String __CONTEXTS_DIR = "contexts";
|
---|
87 |
|
---|
88 | public static final String __TMP_DIR = "tmp";
|
---|
89 | public static final String __WORK_DIR = "work";
|
---|
90 | public static final int __SETUP_PROGRESS_DIALOG = 0;
|
---|
91 | public static final int __SETUP_DONE = 2;
|
---|
92 | public static final int __SETUP_RUNNING = 1;
|
---|
93 | public static final int __SETUP_NOTDONE = 0;
|
---|
94 |
|
---|
95 |
|
---|
96 | public static final File __JETTY_DIR;
|
---|
97 | private Button startButton;
|
---|
98 | private Button stopButton;
|
---|
99 | private Button configButton;
|
---|
100 | private TextView footer;
|
---|
101 | private TextView info;
|
---|
102 | private TextView console;
|
---|
103 | private ScrollView consoleScroller;
|
---|
104 | private StringBuilder consoleBuffer = new StringBuilder();
|
---|
105 | private Runnable scrollTask;
|
---|
106 | private ProgressDialog progressDialog;
|
---|
107 | private Thread progressThread;
|
---|
108 | private Handler handler;
|
---|
109 | private BroadcastReceiver bcastReceiver;
|
---|
110 |
|
---|
111 | class ConsoleScrollTask implements Runnable
|
---|
112 | {
|
---|
113 | public void run()
|
---|
114 | {
|
---|
115 | consoleScroller.fullScroll(View.FOCUS_DOWN);
|
---|
116 | }
|
---|
117 | }
|
---|
118 |
|
---|
119 | /**
|
---|
120 | * ProgressThread
|
---|
121 | *
|
---|
122 | * Handles finishing install tasks for Jetty.
|
---|
123 | */
|
---|
124 | class ProgressThread extends Thread
|
---|
125 | {
|
---|
126 | private Handler _handler;
|
---|
127 |
|
---|
128 | public ProgressThread(Handler h) {
|
---|
129 | _handler = h;
|
---|
130 | }
|
---|
131 |
|
---|
132 | public void sendProgressUpdate (int prog)
|
---|
133 | {
|
---|
134 | Message msg = _handler.obtainMessage();
|
---|
135 | Bundle b = new Bundle();
|
---|
136 | b.putInt("prog", prog);
|
---|
137 | msg.setData(b);
|
---|
138 | _handler.sendMessage(msg);
|
---|
139 | }
|
---|
140 |
|
---|
141 | public void run ()
|
---|
142 | {
|
---|
143 | boolean updateNeeded = isUpdateNeeded();
|
---|
144 |
|
---|
145 | //create the jetty dir structure
|
---|
146 | File jettyDir = __JETTY_DIR;
|
---|
147 | if (!jettyDir.exists())
|
---|
148 | {
|
---|
149 | boolean made = jettyDir.mkdirs();
|
---|
150 | Log.i(TAG,"Made " + __JETTY_DIR + ": " + made);
|
---|
151 | }
|
---|
152 |
|
---|
153 | sendProgressUpdate(10);
|
---|
154 |
|
---|
155 |
|
---|
156 | //Do not make a work directory to preserve unpacked
|
---|
157 | //webapps - this seems to clash with Android when
|
---|
158 | //out-of-date webapps are deleted and then re-unpacked
|
---|
159 | //on a jetty restart: Android remembers where the dex
|
---|
160 | //file of the old webapp was installed, but it's now
|
---|
161 | //been replaced by a new file of the same name. Strangely,
|
---|
162 | //this does not seem to affect webapps unpacked to tmp?
|
---|
163 | //Original versions of i-jetty created a work directory. So
|
---|
164 | //we will delete it here if found to ensure webapps can be
|
---|
165 | //updated successfully.
|
---|
166 | File workDir = new File(jettyDir, __WORK_DIR);
|
---|
167 | if (workDir.exists())
|
---|
168 | {
|
---|
169 | Installer.delete(workDir);
|
---|
170 | Log.i(TAG, "removed work dir");
|
---|
171 | }
|
---|
172 |
|
---|
173 |
|
---|
174 | //make jetty/tmp
|
---|
175 | File tmpDir = new File(jettyDir,__TMP_DIR);
|
---|
176 | if (!tmpDir.exists())
|
---|
177 | {
|
---|
178 | boolean made = tmpDir.mkdirs();
|
---|
179 | Log.i(TAG,"Made " + tmpDir + ": " + made);
|
---|
180 | }
|
---|
181 | else
|
---|
182 | {
|
---|
183 | Log.i(TAG,tmpDir + " exists");
|
---|
184 | }
|
---|
185 |
|
---|
186 | //make jetty/webapps
|
---|
187 | File webappsDir = new File(jettyDir,__WEBAPP_DIR);
|
---|
188 | if (!webappsDir.exists())
|
---|
189 | {
|
---|
190 | boolean made = webappsDir.mkdirs();
|
---|
191 | Log.i(TAG,"Made " + webappsDir + ": " + made);
|
---|
192 | }
|
---|
193 | else
|
---|
194 | {
|
---|
195 | Log.i(TAG,webappsDir + " exists");
|
---|
196 | }
|
---|
197 |
|
---|
198 | //make jetty/etc
|
---|
199 | File etcDir = new File(jettyDir,__ETC_DIR);
|
---|
200 | if (!etcDir.exists())
|
---|
201 | {
|
---|
202 | boolean made = etcDir.mkdirs();
|
---|
203 | Log.i(TAG,"Made " + etcDir + ": " + made);
|
---|
204 | }
|
---|
205 | else
|
---|
206 | {
|
---|
207 | Log.i(TAG,etcDir + " exists");
|
---|
208 | }
|
---|
209 | sendProgressUpdate(30);
|
---|
210 |
|
---|
211 |
|
---|
212 | File webdefaults = new File(etcDir,"webdefault.xml");
|
---|
213 | if (!webdefaults.exists() || updateNeeded)
|
---|
214 | {
|
---|
215 | //get the webdefaults.xml file out of resources
|
---|
216 | try
|
---|
217 | {
|
---|
218 | InputStream is = getResources().openRawResource(R.raw.webdefault);
|
---|
219 | OutputStream os = new FileOutputStream(webdefaults);
|
---|
220 | IO.copy(is,os);
|
---|
221 | Log.i(TAG,"Loaded webdefault.xml");
|
---|
222 | }
|
---|
223 | catch (Exception e)
|
---|
224 | {
|
---|
225 | Log.e(TAG,"Error loading webdefault.xml",e);
|
---|
226 | }
|
---|
227 | }
|
---|
228 | sendProgressUpdate(40);
|
---|
229 |
|
---|
230 | File realm = new File(etcDir,"realm.properties");
|
---|
231 | if (!realm.exists() || updateNeeded)
|
---|
232 | {
|
---|
233 | try
|
---|
234 | {
|
---|
235 | //get the realm.properties file out resources
|
---|
236 | InputStream is = getResources().openRawResource(R.raw.realm_properties);
|
---|
237 | OutputStream os = new FileOutputStream(realm);
|
---|
238 | IO.copy(is,os);
|
---|
239 | Log.i(TAG,"Loaded realm.properties");
|
---|
240 | }
|
---|
241 | catch (Exception e)
|
---|
242 | {
|
---|
243 | Log.e(TAG,"Error loading realm.properties",e);
|
---|
244 | }
|
---|
245 | }
|
---|
246 | sendProgressUpdate(50);
|
---|
247 |
|
---|
248 | File keystore = new File(etcDir,"keystore");
|
---|
249 | if (!keystore.exists() || updateNeeded)
|
---|
250 | {
|
---|
251 | try
|
---|
252 | {
|
---|
253 | //get the keystore out of resources
|
---|
254 | InputStream is = getResources().openRawResource(R.raw.keystore);
|
---|
255 | OutputStream os = new FileOutputStream(keystore);
|
---|
256 | IO.copy(is,os);
|
---|
257 | Log.i(TAG,"Loaded keystore");
|
---|
258 | }
|
---|
259 | catch (Exception e)
|
---|
260 | {
|
---|
261 | Log.e(TAG,"Error loading keystore",e);
|
---|
262 | }
|
---|
263 | }
|
---|
264 | sendProgressUpdate(60);
|
---|
265 |
|
---|
266 | //make jetty/contexts
|
---|
267 | File contextsDir = new File(jettyDir,__CONTEXTS_DIR);
|
---|
268 | if (!contextsDir.exists())
|
---|
269 | {
|
---|
270 | boolean made = contextsDir.mkdirs();
|
---|
271 | Log.i(TAG,"Made " + contextsDir + ": " + made);
|
---|
272 | }
|
---|
273 | else
|
---|
274 | {
|
---|
275 | Log.i(TAG,contextsDir + " exists");
|
---|
276 | }
|
---|
277 | sendProgressUpdate(70);
|
---|
278 |
|
---|
279 | try
|
---|
280 | {
|
---|
281 | PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(),0);
|
---|
282 | if (pi != null)
|
---|
283 | {
|
---|
284 | setStoredJettyVersion(pi.versionCode);
|
---|
285 | }
|
---|
286 | }
|
---|
287 | catch (Exception e)
|
---|
288 | {
|
---|
289 | Log.w(TAG, "Unable to get PackageInfo for i-jetty");
|
---|
290 | }
|
---|
291 |
|
---|
292 | //if there was a .update file indicating an update was needed, remove it now we've updated
|
---|
293 | File update = new File(__JETTY_DIR, ".update");
|
---|
294 | if (update.exists())
|
---|
295 | update.delete();
|
---|
296 |
|
---|
297 | sendProgressUpdate(100);
|
---|
298 | }
|
---|
299 | };
|
---|
300 |
|
---|
301 | static
|
---|
302 | {
|
---|
303 | __JETTY_DIR = new File(Environment.getExternalStorageDirectory(),"jetty");
|
---|
304 | // Ensure parsing is not validating - does not work with android
|
---|
305 | System.setProperty("org.eclipse.jetty.xml.XmlParser.Validating","false");
|
---|
306 |
|
---|
307 | // Bridge Jetty logging to Android logging
|
---|
308 | System.setProperty("org.eclipse.jetty.util.log.class","org.mortbay.ijetty.AndroidLog");
|
---|
309 | org.eclipse.jetty.util.log.Log.setLog(new AndroidLog());
|
---|
310 | }
|
---|
311 |
|
---|
312 | public IJetty ()
|
---|
313 | {
|
---|
314 | super();
|
---|
315 |
|
---|
316 | handler = new Handler ()
|
---|
317 | {
|
---|
318 | public void handleMessage(Message msg) {
|
---|
319 | int total = msg.getData().getInt("prog");
|
---|
320 | progressDialog.setProgress(total);
|
---|
321 | if (total >= 100){
|
---|
322 | dismissDialog(__SETUP_PROGRESS_DIALOG);
|
---|
323 | }
|
---|
324 | }
|
---|
325 |
|
---|
326 | };
|
---|
327 | }
|
---|
328 |
|
---|
329 | public String formatJettyInfoLine (String format, Object ... args)
|
---|
330 | {
|
---|
331 | String ms = "";
|
---|
332 | if (format != null)
|
---|
333 | ms = String.format(format, args);
|
---|
334 | return ms+"<br/>";
|
---|
335 | }
|
---|
336 |
|
---|
337 |
|
---|
338 |
|
---|
339 | public void consolePrint(String format, Object... args)
|
---|
340 | {
|
---|
341 | String msg = String.format(format,args);
|
---|
342 | if (msg.length() > 0)
|
---|
343 | {
|
---|
344 | consoleBuffer.append(msg).append("<br/>");
|
---|
345 | console.setText(Html.fromHtml(consoleBuffer.toString()));
|
---|
346 | Log.i(TAG,msg); // Only interested in non-empty lines being output to Log
|
---|
347 | }
|
---|
348 | else
|
---|
349 | {
|
---|
350 | consoleBuffer.append(msg).append("<br/>");
|
---|
351 | console.setText(Html.fromHtml(consoleBuffer.toString()));
|
---|
352 | }
|
---|
353 |
|
---|
354 | if (scrollTask == null)
|
---|
355 | {
|
---|
356 | scrollTask = new ConsoleScrollTask();
|
---|
357 | }
|
---|
358 |
|
---|
359 | consoleScroller.post(scrollTask);
|
---|
360 | }
|
---|
361 |
|
---|
362 |
|
---|
363 |
|
---|
364 | protected int getStoredJettyVersion()
|
---|
365 | {
|
---|
366 | File jettyDir = __JETTY_DIR;
|
---|
367 | if (!jettyDir.exists())
|
---|
368 | {
|
---|
369 | return -1;
|
---|
370 | }
|
---|
371 | File versionFile = new File(jettyDir,"version.code");
|
---|
372 | if (!versionFile.exists())
|
---|
373 | {
|
---|
374 | return -1;
|
---|
375 | }
|
---|
376 | int val = -1;
|
---|
377 | ObjectInputStream ois = null;
|
---|
378 | try
|
---|
379 | {
|
---|
380 | ois = new ObjectInputStream(new FileInputStream(versionFile));
|
---|
381 | val = ois.readInt();
|
---|
382 | return val;
|
---|
383 | }
|
---|
384 | catch (Exception e)
|
---|
385 | {
|
---|
386 | Log.e(TAG,"Problem reading version.code",e);
|
---|
387 | return -1;
|
---|
388 | }
|
---|
389 | finally
|
---|
390 | {
|
---|
391 | if (ois != null)
|
---|
392 | {
|
---|
393 | try
|
---|
394 | {
|
---|
395 | ois.close();
|
---|
396 | }
|
---|
397 | catch (Exception e)
|
---|
398 | {
|
---|
399 | Log.d(TAG,"Error closing version.code input stream",e);
|
---|
400 | }
|
---|
401 | }
|
---|
402 | }
|
---|
403 | }
|
---|
404 |
|
---|
405 |
|
---|
406 |
|
---|
407 |
|
---|
408 | @Override
|
---|
409 | protected void onDestroy()
|
---|
410 | {
|
---|
411 | if (bcastReceiver != null)
|
---|
412 | unregisterReceiver(bcastReceiver);
|
---|
413 | super.onDestroy();
|
---|
414 | }
|
---|
415 |
|
---|
416 |
|
---|
417 |
|
---|
418 | @Override
|
---|
419 | public void onCreate(Bundle icicle)
|
---|
420 | {
|
---|
421 | super.onCreate(icicle);
|
---|
422 |
|
---|
423 | setContentView(R.layout.jetty_controller);
|
---|
424 |
|
---|
425 | startButton = (Button)findViewById(R.id.start);
|
---|
426 | stopButton = (Button)findViewById(R.id.stop);
|
---|
427 | configButton = (Button)findViewById(R.id.config);
|
---|
428 | final Button downloadButton = (Button)findViewById(R.id.download);
|
---|
429 |
|
---|
430 |
|
---|
431 | IntentFilter filter = new IntentFilter();
|
---|
432 | filter.addAction(__START_ACTION);
|
---|
433 | filter.addAction(__STOP_ACTION);
|
---|
434 | filter.addCategory("default");
|
---|
435 |
|
---|
436 | bcastReceiver =
|
---|
437 | new BroadcastReceiver()
|
---|
438 | {
|
---|
439 |
|
---|
440 | public void onReceive(Context context, Intent intent)
|
---|
441 | {
|
---|
442 | if (__START_ACTION.equalsIgnoreCase(intent.getAction()))
|
---|
443 | {
|
---|
444 | startButton.setEnabled(false);
|
---|
445 | configButton.setEnabled(false);
|
---|
446 | stopButton.setEnabled(true);
|
---|
447 | consolePrint("<br/>Started Jetty at %s", new Date());
|
---|
448 | String[] connectors = intent.getExtras().getStringArray("connectors");
|
---|
449 | if (null != connectors)
|
---|
450 | {
|
---|
451 | for (int i=0;i<connectors.length;i++)
|
---|
452 | consolePrint(connectors[i]);
|
---|
453 | }
|
---|
454 |
|
---|
455 | printNetworkInterfaces();
|
---|
456 |
|
---|
457 | if (AndroidInfo.isOnEmulator(IJetty.this))
|
---|
458 | consolePrint("Set up port forwarding to see i-jetty outside of the emulator.");
|
---|
459 | }
|
---|
460 | else if (__STOP_ACTION.equalsIgnoreCase(intent.getAction()))
|
---|
461 | {
|
---|
462 | startButton.setEnabled(true);
|
---|
463 | configButton.setEnabled(true);
|
---|
464 | stopButton.setEnabled(false);
|
---|
465 | consolePrint("<br/> Jetty stopped at %s",new Date());
|
---|
466 | }
|
---|
467 | }
|
---|
468 |
|
---|
469 | };
|
---|
470 |
|
---|
471 | registerReceiver(bcastReceiver, filter);
|
---|
472 |
|
---|
473 |
|
---|
474 | // Watch for button clicks.
|
---|
475 | startButton.setOnClickListener(new OnClickListener()
|
---|
476 | {
|
---|
477 | public void onClick(View v)
|
---|
478 | {
|
---|
479 | if (isUpdateNeeded())
|
---|
480 | IJettyToast.showQuickToast(IJetty.this,R.string.loading);
|
---|
481 | else
|
---|
482 | {
|
---|
483 | //TODO get these values from editable UI elements
|
---|
484 | Intent intent = new Intent(IJetty.this,IJettyService.class);
|
---|
485 | intent.putExtra(__PORT,__PORT_DEFAULT);
|
---|
486 | intent.putExtra(__NIO,__NIO_DEFAULT);
|
---|
487 | intent.putExtra(__SSL,__SSL_DEFAULT);
|
---|
488 | intent.putExtra(__CONSOLE_PWD,__CONSOLE_PWD_DEFAULT);
|
---|
489 | startService(intent);
|
---|
490 | }
|
---|
491 | }
|
---|
492 | });
|
---|
493 |
|
---|
494 | stopButton.setOnClickListener(new OnClickListener()
|
---|
495 | {
|
---|
496 | public void onClick(View v)
|
---|
497 | {
|
---|
498 | stopService(new Intent(IJetty.this,IJettyService.class));
|
---|
499 | }
|
---|
500 | });
|
---|
501 |
|
---|
502 |
|
---|
503 | configButton.setOnClickListener(new OnClickListener()
|
---|
504 | {
|
---|
505 | public void onClick(View v)
|
---|
506 | {
|
---|
507 | IJettyEditor.show(IJetty.this);
|
---|
508 | }
|
---|
509 | });
|
---|
510 |
|
---|
511 |
|
---|
512 | downloadButton.setOnClickListener(new OnClickListener()
|
---|
513 | {
|
---|
514 | public void onClick(View v)
|
---|
515 | {
|
---|
516 | IJettyDownloader.show(IJetty.this);
|
---|
517 | }
|
---|
518 | });
|
---|
519 |
|
---|
520 | info = (TextView)findViewById(R.id.info);
|
---|
521 | footer = (TextView)findViewById(R.id.footer);
|
---|
522 | console = (TextView)findViewById(R.id.console);
|
---|
523 | consoleScroller = (ScrollView)findViewById(R.id.consoleScroller);
|
---|
524 |
|
---|
525 | StringBuilder infoBuffer = new StringBuilder();
|
---|
526 | try
|
---|
527 | {
|
---|
528 | PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(),0);
|
---|
529 | infoBuffer.append(formatJettyInfoLine ("i-jetty version %s (%s)",pi.versionName,pi.versionCode));
|
---|
530 | }
|
---|
531 | catch (NameNotFoundException e)
|
---|
532 | {
|
---|
533 | infoBuffer.append(formatJettyInfoLine ("i-jetty version unknown"));
|
---|
534 | }
|
---|
535 | infoBuffer.append(formatJettyInfoLine("On %s using Android version %s",AndroidInfo.getDeviceModel(), AndroidInfo.getOSVersion()));
|
---|
536 | info.setText(Html.fromHtml(infoBuffer.toString()));
|
---|
537 | /*
|
---|
538 | StringBuilder footerBuffer = new StringBuilder();
|
---|
539 | footerBuffer.append("<b>Project:</b> <a href=\"http://code.google.com/p/i-jetty\">http://code.google.com/p/i-jetty</a> <br/>");
|
---|
540 | footerBuffer.append("<b>Server:</b> http://www.eclipse.org/jetty <br/>");
|
---|
541 | footerBuffer.append("<b>Support:</b> http://www.intalio.com/jetty/services <br/>");
|
---|
542 | footer.setText(Html.fromHtml(footerBuffer.toString()));
|
---|
543 | */
|
---|
544 |
|
---|
545 | }
|
---|
546 |
|
---|
547 | public static void show(Context context)
|
---|
548 | {
|
---|
549 | final Intent intent = new Intent(context,IJetty.class);
|
---|
550 | context.startActivity(intent);
|
---|
551 | }
|
---|
552 |
|
---|
553 | @Override
|
---|
554 | protected void onResume()
|
---|
555 | {
|
---|
556 | if (!SdCardUnavailableActivity.isExternalStorageAvailable())
|
---|
557 | {
|
---|
558 | SdCardUnavailableActivity.show(this);
|
---|
559 | }
|
---|
560 | else
|
---|
561 | {
|
---|
562 | //work out if we need to do the installation finish step
|
---|
563 | //or not. We do it iff:
|
---|
564 | // - there is no previous jetty version on disk
|
---|
565 | // - the previous version does not match the current version
|
---|
566 | // - we're not already doing the update
|
---|
567 |
|
---|
568 | if (isUpdateNeeded())
|
---|
569 | {
|
---|
570 | setupJetty();
|
---|
571 | }
|
---|
572 | }
|
---|
573 |
|
---|
574 |
|
---|
575 | if (IJettyService.isRunning())
|
---|
576 | {
|
---|
577 | startButton.setEnabled(false);
|
---|
578 | configButton.setEnabled(false);
|
---|
579 | stopButton.setEnabled(true);
|
---|
580 | }
|
---|
581 | else
|
---|
582 | {
|
---|
583 | startButton.setEnabled(true);
|
---|
584 | configButton.setEnabled(true);
|
---|
585 | stopButton.setEnabled(false);
|
---|
586 | }
|
---|
587 | super.onResume();
|
---|
588 | }
|
---|
589 |
|
---|
590 |
|
---|
591 |
|
---|
592 | @Override
|
---|
593 | protected Dialog onCreateDialog(int id)
|
---|
594 | {
|
---|
595 | switch(id)
|
---|
596 | {
|
---|
597 | case __SETUP_PROGRESS_DIALOG:
|
---|
598 | {
|
---|
599 | progressDialog = new ProgressDialog(IJetty.this);
|
---|
600 | progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
---|
601 | progressDialog.setMessage("Finishing initial install ...");
|
---|
602 |
|
---|
603 | return progressDialog;
|
---|
604 | }
|
---|
605 | default:
|
---|
606 | return null;
|
---|
607 | }
|
---|
608 | }
|
---|
609 |
|
---|
610 | private void printNetworkInterfaces()
|
---|
611 | {
|
---|
612 | try
|
---|
613 | {
|
---|
614 | Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
|
---|
615 | for (NetworkInterface ni : Collections.list(nis))
|
---|
616 | {
|
---|
617 | Enumeration<InetAddress> iis = ni.getInetAddresses();
|
---|
618 | for (InetAddress ia : Collections.list(iis))
|
---|
619 | {
|
---|
620 | consoleBuffer.append(formatJettyInfoLine("Network interface: %s: %s",ni.getDisplayName(),ia.getHostAddress()));
|
---|
621 | }
|
---|
622 | }
|
---|
623 | }
|
---|
624 | catch (SocketException e)
|
---|
625 | {
|
---|
626 | Log.w(TAG, e);
|
---|
627 | }
|
---|
628 | }
|
---|
629 |
|
---|
630 |
|
---|
631 |
|
---|
632 | protected void setStoredJettyVersion(int version)
|
---|
633 | {
|
---|
634 | File jettyDir = __JETTY_DIR;
|
---|
635 | if (!jettyDir.exists())
|
---|
636 | {
|
---|
637 | return;
|
---|
638 | }
|
---|
639 | File versionFile = new File(jettyDir,"version.code");
|
---|
640 | ObjectOutputStream oos = null;
|
---|
641 | try
|
---|
642 | {
|
---|
643 | FileOutputStream fos = new FileOutputStream(versionFile);
|
---|
644 | oos = new ObjectOutputStream(fos);
|
---|
645 | oos.writeInt(version);
|
---|
646 | oos.flush();
|
---|
647 | }
|
---|
648 | catch (Exception e)
|
---|
649 | {
|
---|
650 | Log.e(TAG,"Problem writing jetty version",e);
|
---|
651 | }
|
---|
652 | finally
|
---|
653 | {
|
---|
654 | if (oos != null)
|
---|
655 | {
|
---|
656 | try
|
---|
657 | {
|
---|
658 | oos.close();
|
---|
659 | }
|
---|
660 | catch (Exception e)
|
---|
661 | {
|
---|
662 | Log.d(TAG,"Error closing version.code output stream",e);
|
---|
663 | }
|
---|
664 | }
|
---|
665 | }
|
---|
666 | }
|
---|
667 |
|
---|
668 | /**
|
---|
669 | * We need to an update iff we don't know the current
|
---|
670 | * jetty version or it is different to the last version
|
---|
671 | * that was installed.
|
---|
672 | *
|
---|
673 | * @return
|
---|
674 | */
|
---|
675 | public boolean isUpdateNeeded ()
|
---|
676 | {
|
---|
677 | //if no previous version file, assume update is required
|
---|
678 | int storedVersion = getStoredJettyVersion();
|
---|
679 | if (storedVersion <= 0)
|
---|
680 | return true;
|
---|
681 |
|
---|
682 | try
|
---|
683 | {
|
---|
684 | //if different previous version, update is required
|
---|
685 | PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(),0);
|
---|
686 | if (pi == null)
|
---|
687 | return true;
|
---|
688 | if (pi.versionCode != storedVersion)
|
---|
689 | return true;
|
---|
690 |
|
---|
691 | //if /sdcard/jetty/.update file exists, then update is required
|
---|
692 | File alwaysUpdate = new File(__JETTY_DIR,".update");
|
---|
693 | if (alwaysUpdate.exists())
|
---|
694 | {
|
---|
695 | Log.i(TAG,"Always Update tag found " + alwaysUpdate);
|
---|
696 | return true;
|
---|
697 | }
|
---|
698 | }
|
---|
699 | catch (Exception e)
|
---|
700 | {
|
---|
701 | //if any of these tests go wrong, best to assume update is true?
|
---|
702 | return true;
|
---|
703 | }
|
---|
704 |
|
---|
705 | return false;
|
---|
706 | }
|
---|
707 |
|
---|
708 | public void setupJetty()
|
---|
709 | {
|
---|
710 | showDialog(__SETUP_PROGRESS_DIALOG);
|
---|
711 | progressThread = new ProgressThread(handler);
|
---|
712 | progressThread.start();
|
---|
713 | };
|
---|
714 |
|
---|
715 | }
|
---|