ruboto 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,8 @@
1
1
  package org.ruboto;
2
2
 
3
- import android.app.DownloadManager;
4
- import android.app.DownloadManager.Query;
5
- import android.app.DownloadManager.Request;
6
- import android.app.ProgressDialog;
7
- import android.content.BroadcastReceiver;
8
3
  import android.content.Context;
9
- import android.content.DialogInterface;
10
- import android.content.DialogInterface.OnCancelListener;
11
4
  import android.content.Intent;
12
- import android.content.IntentFilter;
13
- import android.content.pm.PackageManager;
14
- import android.database.Cursor;
15
- import android.net.Uri;
16
5
  import android.os.Bundle;
17
- import android.provider.Settings;
18
- import android.view.View;
19
- import android.widget.TextView;
20
- import android.widget.Toast;
21
6
 
22
7
  /**
23
8
  * This Activity acts as an entry point to the app. It must initialize the
@@ -27,41 +12,22 @@ import android.widget.Toast;
27
12
  * this layout is displayed instead of the progress dialog.
28
13
  */
29
14
  public class EntryPointActivity extends org.ruboto.RubotoActivity {
30
- private int splash = 0;
31
- private ProgressDialog loadingDialog;
32
- private boolean dialogCancelled = false;
33
- private BroadcastReceiver receiver;
34
- private long enqueue;
35
- java.io.File localFile;
36
- private static final int INSTALL_REQUEST_CODE = 4242;
37
15
 
38
- // FIXME(uwe): Remove this field? Duplicated by ScriptInfo.isLoaded() ?
39
- protected boolean appStarted = false;
40
- // EMXIF
41
-
42
- public void onCreate(Bundle bundle) {
16
+ public void onCreate(Bundle bundle) {
43
17
  Log.d("EntryPointActivity onCreate:");
44
- getScriptInfo().setRubyClassName(getClass().getSimpleName());
45
-
46
- localFile = new java.io.File(getFilesDir(), RUBOTO_APK);
47
- try {
48
- splash = Class.forName(getPackageName() + ".R$layout").getField("splash").getInt(null);
49
- } catch (Exception e) {
50
- splash = -1;
51
- }
18
+ getScriptInfo().setRubyClassName(getClass().getSimpleName());
52
19
 
53
- if (JRubyAdapter.isInitialized()) {
54
- appStarted = true;
55
- } else {
56
- initJRuby(true);
57
- }
58
- super.onCreate(bundle);
59
- }
20
+ if (!JRubyAdapter.isInitialized()) {
21
+ showSplash();
22
+ finish();
23
+ }
24
+ super.onCreate(bundle);
25
+ }
60
26
 
61
27
  public void onResume() {
62
28
  Log.d("onResume: ");
63
29
 
64
- if(appStarted) {
30
+ if(getScriptInfo().isLoaded()) {
65
31
  Log.d("onResume: App already started!");
66
32
  super.onResume();
67
33
  return;
@@ -73,357 +39,45 @@ public class EntryPointActivity extends org.ruboto.RubotoActivity {
73
39
  fireRubotoActivity();
74
40
  } else {
75
41
  Log.d("Not initialized");
76
- super.onResume();
77
- initJRuby(true);
42
+ showSplash();
43
+ finish();
78
44
  }
45
+ super.onResume();
79
46
  }
80
47
 
81
48
  public void onPause() {
82
49
  Log.d("onPause: ");
83
-
84
- if (receiver != null) {
85
- unregisterReceiver(receiver);
86
- receiver = null;
87
- }
88
50
  super.onPause();
89
51
  }
90
52
 
91
53
  public void onDestroy() {
92
54
  Log.d("onDestroy: ");
93
-
94
55
  super.onDestroy();
95
- if (dialogCancelled) {
96
- System.runFinalizersOnExit(true);
97
- System.exit(0);
98
- }
99
- }
100
-
101
- private void initJRuby(final boolean firstTime) {
102
- showProgress();
103
- new Thread(new Runnable() {
104
- public void run() {
105
- final boolean jrubyOk = JRubyAdapter.setUpJRuby(EntryPointActivity.this);
106
- if (jrubyOk) {
107
- Log.d("onResume: JRuby OK");
108
- fireRubotoActivity();
109
- } else {
110
- registerPackageInstallReceiver();
111
- runOnUiThread(new Runnable() {
112
- public void run() {
113
- if (localFile.exists()) {
114
- installDownload();
115
- } else {
116
- if (firstTime) {
117
- Log.d("onResume: Checking JRuby - IN UI thread");
118
- try {
119
- setContentView(Class.forName(getPackageName() + ".R$layout").getField("get_ruboto_core").getInt(null));
120
- if (hasInternetPermission()) {
121
- getRubotoCore(null);
122
- return;
123
- }
124
- } catch (Exception e) {
125
- }
126
- } else {
127
- Toast.makeText(EntryPointActivity.this,"Failed to initialize Ruboto Core.",Toast.LENGTH_LONG).show();
128
- try {
129
- TextView textView = (TextView) findViewById(Class.forName(getPackageName() + ".R$id").getField("text").getInt(null));
130
- textView.setText("Woops! Ruboto Core was installed, but it failed to initialize properly! I am not sure how to proceed from here. If you can, please file an error report at http://ruboto.org/");
131
- } catch (Exception e) {
132
- }
133
- }
134
- }
135
- hideProgress();
136
- }
137
- });
138
- }
139
- }
140
- }).start();
141
56
  }
142
57
 
143
- private static final String RUBOTO_APK = "RubotoCore-release.apk";
144
- private static final String RUBOTO_URL = "http://ruboto.org/downloads/" + RUBOTO_APK;
145
-
146
- // Called when the button is pressed.
147
- public void getRubotoCore(View view) {
148
- try {
149
- if (hasInternetPermission() && canInstallFromUnknownSources()) {
150
- if (enqueue <= 0) {
151
- DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
152
- Request request = new Request(Uri.parse(RUBOTO_URL));
153
- enqueue = dm.enqueue(request);
154
- hideProgress();
155
- showDownloadProgress("Downloading RubotoCore...");
156
- new Thread(new Runnable() {
157
- public void run() {
158
- while (loadingDialog != null && enqueue > 0) {
159
- // FIXME(uwe): Also set total bytes and bytes downloaded.
160
- loadingDialog.setProgress(getProgressPercentage());
161
- try {
162
- Thread.sleep(1000);
163
- } catch (InterruptedException ie) {
164
- Log.e("Interupted!");
165
- }
166
- }
167
- }
168
- }).start();
169
- }
170
- return;
171
- }
172
- } catch (Exception e) {
173
- Log.e("Exception in direct RubotoCore download: " + e);
174
- }
175
- try {
176
- startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("market://details?id=org.ruboto.core")));
177
- } catch (android.content.ActivityNotFoundException anfe) {
178
- Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(RUBOTO_URL));
179
- startActivity(intent);
180
- }
181
- }
182
58
 
183
59
  protected void fireRubotoActivity() {
184
- if(appStarted) return;
185
- appStarted = true;
60
+ if(getScriptInfo().isLoaded()) return;
186
61
  Log.i("Starting activity");
187
62
  ScriptLoader.loadScript(this);
188
63
  runOnUiThread(new Runnable() {
189
- public void run() {
190
- ScriptLoader.callOnCreate(EntryPointActivity.this, args[0]);
191
- onStart();
192
- onResume();
193
- hideProgress();
194
- }
195
- });
196
- }
197
-
198
- private void showProgress() {
199
- if (loadingDialog == null) {
200
- if (splash > 0) {
201
- Log.i("Showing splash");
202
- requestWindowFeature(android.view.Window.FEATURE_NO_TITLE);
203
- setContentView(splash);
204
- } else {
205
- Log.i("Showing progress");
206
- loadingDialog = ProgressDialog.show(this, null, "Starting...", true, true);
207
- loadingDialog.setCanceledOnTouchOutside(false);
208
- loadingDialog.setOnCancelListener(new OnCancelListener() {
209
- public void onCancel(DialogInterface dialog) {
210
- dialogCancelled = true;
211
- finish();
212
- }
213
- });
214
- }
215
- }
216
- }
217
-
218
- private void showDownloadProgress(String message) {
219
- if (loadingDialog == null) {
220
- if (splash > 0) {
221
- Log.i("Showing splash");
222
- requestWindowFeature(android.view.Window.FEATURE_NO_TITLE);
223
- setContentView(splash);
224
- } else {
225
- Log.i("Showing progress");
226
- loadingDialog = new ProgressDialog(this);
227
- loadingDialog.setTitle(null);
228
- loadingDialog.setMessage(message);
229
- loadingDialog.setIndeterminate(false);
230
- loadingDialog.setMax(100);
231
- loadingDialog.setProgressStyle(android.app.ProgressDialog.STYLE_HORIZONTAL);
232
- loadingDialog.setCancelable(true);
233
- loadingDialog.setCanceledOnTouchOutside(false);
234
- loadingDialog.setOnCancelListener(new OnCancelListener() {
235
- public void onCancel(DialogInterface dialog) {
236
- dialogCancelled = true;
237
- finish();
238
- }
239
- });
240
- loadingDialog.show();
241
- }
242
- } else {
243
- loadingDialog.setMessage(message);
244
- }
245
- }
246
-
247
- private void hideProgress() {
248
- if (loadingDialog != null) {
249
- Log.d("Hide progress");
250
- loadingDialog.dismiss();
251
- loadingDialog = null;
252
- }
253
- }
254
-
255
- private void registerPackageInstallReceiver() {
256
- receiver = new BroadcastReceiver(){
257
- public void onReceive(Context context, Intent intent) {
258
- Log.d("Received intent: " + intent + " (" + intent.getExtras() + ")");
259
- if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
260
- long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
261
- if (downloadId == enqueue) {
262
- if (localFile.exists()) {
263
- return;
264
- }
265
- Query query = new Query();
266
- query.setFilterById(enqueue);
267
- DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
268
- Cursor c = dm.query(query);
269
- if (c.moveToFirst()) {
270
- hideProgress();
271
- int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
272
- if (DownloadManager.STATUS_SUCCESSFUL == status) {
273
- storeDownload(dm, downloadId);
274
- installDownload();
275
- } else {
276
- int reason = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_REASON));
277
- Toast.makeText(context,"Download failed (" + status + "): " + reason, Toast.LENGTH_LONG).show();
278
- }
279
- } else {
280
- Toast.makeText(context,"Download diappeared!", Toast.LENGTH_LONG).show();
281
- }
282
- c.close();
283
- }
284
- } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
285
- if (intent.getData().toString().equals("package:org.ruboto.core")) {
286
- Toast.makeText(context,"Ruboto Core is now installed.",Toast.LENGTH_LONG).show();
287
- deleteFile(RUBOTO_APK);
288
- if (receiver != null) {
289
- unregisterReceiver(receiver);
290
- receiver = null;
291
- }
292
- initJRuby(false);
293
- } else {
294
- Toast.makeText(context,"Installed: " + intent.getData().toString(),Toast.LENGTH_LONG).show();
295
- }
296
- }
297
- }
298
- };
299
- IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
300
- filter.addDataScheme("package");
301
- registerReceiver(receiver, filter);
302
- IntentFilter download_filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
303
- registerReceiver(receiver, download_filter);
304
- }
305
-
306
- private void storeDownload(DownloadManager dm, long downloadId) {
307
- try {
308
- android.os.ParcelFileDescriptor file = dm.openDownloadedFile(downloadId);
309
- java.io.InputStream fileStream = new java.io.FileInputStream(file.getFileDescriptor());
310
- java.io.FileOutputStream fos = openFileOutput(RUBOTO_APK, MODE_WORLD_READABLE);
311
- byte[] buffer = new byte[1024];
312
- int length;
313
- while((length = fileStream.read(buffer)) > 0) {
314
- fos.write(buffer, 0, length);
315
- }
316
- fos.flush();
317
- fileStream.close();
318
- fos.close();
319
- dm.remove(downloadId);
320
- enqueue = 0;
321
- } catch (java.io.IOException ioe) {
322
- Log.e("Exception copying RubotoCore: " + ioe);
323
- Toast.makeText(this, "Exception copying RubotoCore: " + ioe, Toast.LENGTH_LONG).show();
324
- }
325
- }
326
-
327
- // FIXME(uwe): Remove when we stop supporting Android < 4.0.3
328
- private void installDownload() {
329
- if (android.os.Build.VERSION.SDK_INT < 15) {
330
- installDownload_10();
331
- } else {
332
- installDownload_15();
333
- }
334
- }
335
- // EMXIF
336
-
337
- // FIXME(uwe): Remove when we stop supporting Android < 4.0.3
338
- private void installDownload_10() {
339
- Uri uri = Uri.fromFile(localFile);
340
- EntryPointActivity.this.grantUriPermission("com.android.packageinstaller", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
341
- Intent installIntent = new Intent(Intent.ACTION_VIEW);
342
- installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
343
- installIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
344
- startActivityForResult(installIntent, INSTALL_REQUEST_CODE);
345
- }
346
- // EMXIF
347
-
348
- // FIXME(uwe): Use constants when we stop suporting Android < 4.0.3
349
- private void installDownload_15() {
350
- Uri uri = Uri.fromFile(localFile);
351
- EntryPointActivity.this.grantUriPermission("com.android.packageinstaller", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
352
- Intent installIntent = new Intent("android.intent.action.INSTALL_PACKAGE"); // Intent.ACTION_INSTALL_PACKAGE
353
- installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
354
- installIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
355
- // FIXME(uwe): Remove when we stop supporting Android api level < 16
356
- installIntent.putExtra("android.intent.extra.ALLOW_REPLACE", true); // Intent.EXTRA_ALLOW_REPLACE
357
- // EMXIF
358
- installIntent.putExtra("android.intent.extra.INSTALLER_PACKAGE_NAME", getPackageName()); // Intent.EXTRA_INSTALLER_PACKAGE_NAME
359
- installIntent.putExtra("android.intent.extra.NOT_UNKNOWN_SOURCE", true); // Intent.EXTRA_NOT_UNKNOWN_SOURCE
360
- installIntent.putExtra("android.intent.extra.RETURN_RESULT", true); // Intent.EXTRA_RETURN_RESULT
361
- startActivityForResult(installIntent, INSTALL_REQUEST_CODE);
362
- }
363
- // EMXIF
364
-
365
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
366
- Log.d("onActivityResult: " + requestCode + ", " + resultCode + ", " + data);
367
- Log.d("onActivityResult: " + INSTALL_REQUEST_CODE + ", " + RESULT_OK + ", " + RESULT_CANCELED);
368
- if (requestCode == INSTALL_REQUEST_CODE) {
369
- if (resultCode == RESULT_OK) {
370
- Log.d("onActivityResult: Install OK.");
371
- } else if (resultCode == RESULT_CANCELED) {
372
- Log.d("onActivityResult: Install canceled.");
373
- // FIXME(uwe): Maybe show a dialog explaining that RubotoCore is needed and try again?
374
- deleteFile(RUBOTO_APK);
375
- if (!JRubyAdapter.isInitialized()) {
376
- finish();
377
- }
378
- // EMXIF
379
- } else {
380
- Log.e("onActivityResult: resultCode: " + resultCode);
381
- }
382
- }
383
- super.onActivityResult(requestCode, resultCode, data);
384
- }
385
-
386
- private boolean hasInternetPermission() {
387
- String permission = "android.permission.INTERNET";
388
- int res = checkCallingOrSelfPermission(permission);
389
- return (res == PackageManager.PERMISSION_GRANTED);
64
+ public void run() {
65
+ ScriptLoader.callOnCreate(EntryPointActivity.this, args[0]);
66
+ onStart();
67
+ onResume();
68
+ }
69
+ });
390
70
  }
391
71
 
392
- private boolean canInstallFromUnknownSources() {
393
- Uri settingsUri = Settings.Secure.CONTENT_URI;
394
- String[] projection = new String[]{Settings.System.VALUE};
395
- String selection = Settings.Secure.NAME + " = ? AND " + Settings.Secure.VALUE + " = ?";
396
-
397
- // FIXME(uwe): Use android.provider.Settings.Global.INSTALL_NON_MARKET_APPS
398
- // when we stop supporting Android api level < 17
399
- String[] selectionArgs = {Settings.Secure.INSTALL_NON_MARKET_APPS, String.valueOf(1)};
400
- // EMXIF
401
-
402
- Cursor query = getContentResolver().query(settingsUri, projection,
403
- selection, selectionArgs, null);
404
- return query.getCount() == 1;
72
+ private void showSplash() {
73
+ Intent splashIntent = new Intent(this, SplashActivity.class);
74
+ splashIntent.putExtra(Intent.EXTRA_INTENT, futureIntent());
75
+ startActivity(splashIntent);
405
76
  }
406
-
407
- // Get the downloaded percent
408
- private int getProgressPercentage() {
409
- int downloadedBytesSoFar = 0, totalBytes = 0, percentage = 0;
410
- DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
411
- try {
412
- Cursor c = dm.query(new DownloadManager.Query().setFilterById(enqueue));
413
- if (c.moveToFirst()) {
414
- int soFarIndex =c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
415
- downloadedBytesSoFar = (int) c.getLong(soFarIndex);
416
- int totalSizeIndex = c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
417
- totalBytes = (int) c.getLong(totalSizeIndex);
418
- }
419
- System.out.println("PERCEN ------" + downloadedBytesSoFar
420
- + " ------ " + totalBytes + "****" + percentage);
421
- percentage = (downloadedBytesSoFar * 100 / totalBytes);
422
- System.out.println("percentage % " + percentage);
423
- } catch (Exception e) {
424
- e.printStackTrace();
425
- }
426
- return percentage;
77
+
78
+ // The Intent to to call when done. Defaults to calling this Activity again.
79
+ // Override to change.
80
+ protected Intent futureIntent() {
81
+ return new Intent(this, this.getClass());
427
82
  }
428
-
429
83
  }
@@ -150,6 +150,7 @@ public class JRubyAdapter {
150
150
 
151
151
  // Used to enable JRuby to generate proxy classes
152
152
  System.setProperty("jruby.ji.proxyClassFactory", "org.ruboto.DalvikProxyClassFactory");
153
+ System.setProperty("jruby.ji.upper.case.package.name.allowed", "true");
153
154
  System.setProperty("jruby.class.cache.path", appContext.getDir("dex", 0).getAbsolutePath());
154
155
 
155
156
  ClassLoader classLoader;
@@ -49,61 +49,10 @@ public class Script {
49
49
  ).replace("__", "_").toLowerCase();
50
50
  }
51
51
 
52
- // Private static methods
53
-
54
- // private static void copyAssets(Context context, String directory) {
55
- // File dest = new File(new File(scriptsDirFile).getParentFile(), directory);
56
- // if (dest.exists() || dest.mkdir()) {
57
- // copyScripts(directory, dest, context.getAssets());
58
- // } else {
59
- // throw new RuntimeException("Unable to create scripts directory: " + dest);
60
- // }
61
- // }
62
-
63
- // private static void copyScripts(String from, File to, AssetManager assets) {
64
- // try {
65
- // byte[] buffer = new byte[8192];
66
- // for (String f : assets.list(from)) {
67
- // File dest = new File(to, f);
68
- //
69
- // if (dest.exists()) {
70
- // continue;
71
- // }
72
- //
73
- // Log.d("copying file from " + from + "/" + f + " to " + dest);
74
- //
75
- // if (assets.list(from + "/" + f).length == 0) {
76
- // InputStream is = assets.open(from + "/" + f);
77
- // OutputStream fos = new BufferedOutputStream(new FileOutputStream(dest), 8192);
78
- //
79
- // int n;
80
- // while ((n = is.read(buffer, 0, buffer.length)) != -1) {
81
- // fos.write(buffer, 0, n);
82
- // }
83
- // is.close();
84
- // fos.close();
85
- // } else {
86
- // dest.mkdir();
87
- // copyScripts(from + "/" + f, dest, assets);
88
- // }
89
- // }
90
- // } catch (IOException iox) {
91
- // Log.e("error copying scripts", iox);
92
- // }
93
- // }
94
-
95
- /*************************************************************************************************
96
- *
97
- * Constructors
98
- */
99
52
  public Script(String name) {
100
53
  this.name = name;
101
54
  }
102
55
 
103
- /*************************************************************************************************
104
- *
105
- * Instance methods
106
- */
107
56
  public String execute() throws IOException {
108
57
  return JRubyAdapter.runScriptlet(getContents()).toString();
109
58
  }