ruboto 0.14.0 → 0.15.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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +3 -5
- data/README.md +41 -36
- data/RELEASE_CANDICATE_DOC +12 -5
- data/RELEASE_DOC +29 -50
- data/Rakefile +13 -7
- data/assets/rakelib/ruboto.rake +63 -16
- data/assets/samples/sample_activity.rb +1 -1
- data/assets/src/RubotoActivity.java +5 -5
- data/assets/src/org/ruboto/EntryPointActivity.java +13 -52
- data/assets/src/org/ruboto/JRubyAdapter.java +1 -1
- data/assets/src/org/ruboto/SplashActivity.java +117 -119
- data/assets/src/ruboto/activity/reload.rb +66 -0
- data/lib/java_class_gen/android_api.xml +1 -1
- data/lib/ruboto/core_ext/rexml.rb +2 -0
- data/lib/ruboto/util/emulator.rb +1 -1
- data/lib/ruboto/util/setup.rb +12 -9
- data/lib/ruboto/util/update.rb +30 -2
- data/lib/ruboto/version.rb +1 -1
- data/test/ruboto_gen_test.rb +8 -5
- data/test/ruboto_update_test.rb +2 -2
- data/test/splash_test.rb +0 -3
- data/test/sqldroid_test.rb +0 -3
- data/test/test_helper.rb +23 -37
- data/test/update_test_methods.rb +0 -1
- data/test/updated_example_test_methods.rb +4 -1
- metadata +5 -17
@@ -16,7 +16,7 @@ class SampleActivity
|
|
16
16
|
:gravity => :center, :text_size => 48.0
|
17
17
|
button :text => 'M-x butterfly', :width => :match_parent, :id => 43, :on_click_listener => proc { butterfly }
|
18
18
|
end
|
19
|
-
rescue
|
19
|
+
rescue Exception
|
20
20
|
puts "Exception creating activity: #{$!}"
|
21
21
|
puts $!.backtrace.join("\n")
|
22
22
|
end
|
@@ -22,17 +22,17 @@ public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
|
|
22
22
|
*/
|
23
23
|
@Override
|
24
24
|
public void onCreate(Bundle bundle) {
|
25
|
-
System.out.println("THE_RUBOTO_CLASS onCreate(): " + getClass().getName());
|
25
|
+
System.out.println("THE_RUBOTO_CLASS onCreate(): " + getClass().getName() + ", finishing: " + isFinishing());
|
26
26
|
|
27
|
-
// Shut this RubotoActivity down if it's not able to restart
|
27
|
+
// Shut this RubotoActivity down if it's not able to restart
|
28
28
|
if (this.getClass().getName().equals("org.ruboto.THE_RUBOTO_CLASS") && !JRubyAdapter.isInitialized()) {
|
29
29
|
super.onCreate(bundle);
|
30
|
-
|
30
|
+
System.out.println("Shutting down stale THE_RUBOTO_CLASS: " + getClass().getName());
|
31
31
|
finish();
|
32
32
|
return;
|
33
33
|
}
|
34
|
-
|
35
|
-
if (ScriptLoader.isCalledFromJRuby()) {
|
34
|
+
|
35
|
+
if (isFinishing() || ScriptLoader.isCalledFromJRuby()) {
|
36
36
|
super.onCreate(bundle);
|
37
37
|
return;
|
38
38
|
}
|
@@ -6,67 +6,24 @@ import android.os.Bundle;
|
|
6
6
|
|
7
7
|
/**
|
8
8
|
* This Activity acts as an entry point to the app. It must initialize the
|
9
|
-
* JRuby runtime before
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
9
|
+
* JRuby runtime before restarting its life cycle. While JRuby is initializing,
|
10
|
+
* a progress dialog is shown. If R.layout.splash is defined, by adding a
|
11
|
+
* res/layout/splash.xml file, this layout is displayed instead of the progress
|
12
|
+
* dialog.
|
13
13
|
*/
|
14
14
|
public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
15
15
|
|
16
16
|
public void onCreate(Bundle bundle) {
|
17
17
|
Log.d("EntryPointActivity onCreate:");
|
18
|
-
getScriptInfo().setRubyClassName(getClass().getSimpleName());
|
19
18
|
|
20
|
-
if (!JRubyAdapter.isInitialized()) {
|
21
|
-
showSplash();
|
22
|
-
finish();
|
23
|
-
}
|
24
|
-
super.onCreate(bundle);
|
25
|
-
}
|
26
|
-
|
27
|
-
public void onResume() {
|
28
|
-
Log.d("onResume: ");
|
29
|
-
|
30
|
-
if(getScriptInfo().isLoaded()) {
|
31
|
-
Log.d("onResume: App already started!");
|
32
|
-
super.onResume();
|
33
|
-
return;
|
34
|
-
}
|
35
|
-
|
36
|
-
Log.d("onResume: Checking JRuby");
|
37
19
|
if (JRubyAdapter.isInitialized()) {
|
38
|
-
|
39
|
-
fireRubotoActivity();
|
20
|
+
getScriptInfo().setRubyClassName(getClass().getSimpleName());
|
40
21
|
} else {
|
41
|
-
|
42
|
-
|
43
|
-
finish();
|
22
|
+
showSplash();
|
23
|
+
finish();
|
44
24
|
}
|
45
|
-
super.onResume();
|
46
|
-
}
|
47
25
|
|
48
|
-
|
49
|
-
Log.d("onPause: ");
|
50
|
-
super.onPause();
|
51
|
-
}
|
52
|
-
|
53
|
-
public void onDestroy() {
|
54
|
-
Log.d("onDestroy: ");
|
55
|
-
super.onDestroy();
|
56
|
-
}
|
57
|
-
|
58
|
-
|
59
|
-
protected void fireRubotoActivity() {
|
60
|
-
if(getScriptInfo().isLoaded()) return;
|
61
|
-
Log.i("Starting activity");
|
62
|
-
ScriptLoader.loadScript(this);
|
63
|
-
runOnUiThread(new Runnable() {
|
64
|
-
public void run() {
|
65
|
-
ScriptLoader.callOnCreate(EntryPointActivity.this, args[0]);
|
66
|
-
onStart();
|
67
|
-
onResume();
|
68
|
-
}
|
69
|
-
});
|
26
|
+
super.onCreate(bundle);
|
70
27
|
}
|
71
28
|
|
72
29
|
private void showSplash() {
|
@@ -78,6 +35,10 @@ public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
|
78
35
|
// The Intent to to call when done. Defaults to calling this Activity again.
|
79
36
|
// Override to change.
|
80
37
|
protected Intent futureIntent() {
|
81
|
-
|
38
|
+
if (getIntent().getAction().equals(Intent.ACTION_MAIN)) {
|
39
|
+
return new Intent(getIntent()).setAction(Intent.ACTION_VIEW);
|
40
|
+
} else {
|
41
|
+
return getIntent();
|
42
|
+
}
|
82
43
|
}
|
83
44
|
}
|
@@ -270,7 +270,7 @@ public class JRubyAdapter {
|
|
270
270
|
}
|
271
271
|
|
272
272
|
addLoadPath(scriptsDirName(appContext));
|
273
|
-
|
273
|
+
put("$package_name", appContext.getPackageName());
|
274
274
|
|
275
275
|
initialized = true;
|
276
276
|
} catch (ClassNotFoundException e) {
|
@@ -31,25 +31,25 @@ public class SplashActivity extends Activity {
|
|
31
31
|
private static final int INSTALL_REQUEST_CODE = 4242;
|
32
32
|
|
33
33
|
public void onCreate(Bundle bundle) {
|
34
|
-
|
34
|
+
Log.d("SplashActivity onCreate:");
|
35
35
|
localFile = new java.io.File(getFilesDir(), RUBOTO_APK);
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
try {
|
37
|
+
splash = Class.forName(getPackageName() + ".R$layout").getField("splash").getInt(null);
|
38
|
+
} catch (Exception e) {
|
39
|
+
splash = -1;
|
40
|
+
}
|
41
41
|
if (!JRubyAdapter.isInitialized()) {
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
initJRuby(true);
|
43
|
+
}
|
44
|
+
super.onCreate(bundle);
|
45
45
|
}
|
46
46
|
|
47
47
|
public void onResume() {
|
48
48
|
Log.d("onResume: ");
|
49
49
|
if (!JRubyAdapter.isInitialized() && receiver == null) {
|
50
|
-
|
50
|
+
registerPackageInstallReceiver();
|
51
51
|
}
|
52
|
-
|
52
|
+
super.onResume();
|
53
53
|
}
|
54
54
|
|
55
55
|
public void onPause() {
|
@@ -73,45 +73,43 @@ public class SplashActivity extends Activity {
|
|
73
73
|
private void initJRuby(final boolean firstTime) {
|
74
74
|
showProgress();
|
75
75
|
new Thread(new Runnable() {
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
}
|
114
|
-
}).start();
|
76
|
+
public void run() {
|
77
|
+
final boolean jrubyOk = JRubyAdapter.setUpJRuby(SplashActivity.this);
|
78
|
+
if (jrubyOk) {
|
79
|
+
Log.d("onResume: JRuby OK");
|
80
|
+
startUserActivity();
|
81
|
+
} else {
|
82
|
+
registerPackageInstallReceiver();
|
83
|
+
runOnUiThread(new Runnable() {
|
84
|
+
public void run() {
|
85
|
+
if (localFile.exists()) {
|
86
|
+
installDownload();
|
87
|
+
} else {
|
88
|
+
if (firstTime) {
|
89
|
+
Log.d("onResume: Checking JRuby - IN UI thread");
|
90
|
+
try {
|
91
|
+
setContentView(Class.forName(getPackageName() + ".R$layout").getField("get_ruboto_core").getInt(null));
|
92
|
+
if (hasInternetPermission()) {
|
93
|
+
getRubotoCore(null);
|
94
|
+
return;
|
95
|
+
}
|
96
|
+
} catch (Exception e) {
|
97
|
+
}
|
98
|
+
} else {
|
99
|
+
Toast.makeText(SplashActivity.this,"Failed to initialize Ruboto Core.",Toast.LENGTH_LONG).show();
|
100
|
+
try {
|
101
|
+
TextView textView = (TextView) findViewById(Class.forName(getPackageName() + ".R$id").getField("text").getInt(null));
|
102
|
+
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/");
|
103
|
+
} catch (Exception e) {
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
hideProgress();
|
108
|
+
}
|
109
|
+
});
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}).start();
|
115
113
|
}
|
116
114
|
|
117
115
|
private static final String RUBOTO_APK = "RubotoCore-release.apk";
|
@@ -128,18 +126,18 @@ public class SplashActivity extends Activity {
|
|
128
126
|
hideProgress();
|
129
127
|
showDownloadProgress("Downloading RubotoCore...");
|
130
128
|
new Thread(new Runnable() {
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
129
|
+
public void run() {
|
130
|
+
while (loadingDialog != null && enqueue > 0) {
|
131
|
+
// FIXME(uwe): Also set total bytes and bytes downloaded.
|
132
|
+
loadingDialog.setProgress(getProgressPercentage());
|
133
|
+
try {
|
134
|
+
Thread.sleep(1000);
|
135
|
+
} catch (InterruptedException ie) {
|
136
|
+
Log.e("Interupted!");
|
137
|
+
}
|
138
|
+
}
|
139
|
+
}
|
140
|
+
}).start();
|
143
141
|
}
|
144
142
|
return;
|
145
143
|
}
|
@@ -165,11 +163,11 @@ public class SplashActivity extends Activity {
|
|
165
163
|
loadingDialog = ProgressDialog.show(this, null, "Starting...", true, true);
|
166
164
|
loadingDialog.setCanceledOnTouchOutside(false);
|
167
165
|
loadingDialog.setOnCancelListener(new OnCancelListener() {
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
166
|
+
public void onCancel(DialogInterface dialog) {
|
167
|
+
dialogCancelled = true;
|
168
|
+
finish();
|
169
|
+
}
|
170
|
+
});
|
173
171
|
}
|
174
172
|
}
|
175
173
|
}
|
@@ -191,11 +189,11 @@ public class SplashActivity extends Activity {
|
|
191
189
|
loadingDialog.setCancelable(true);
|
192
190
|
loadingDialog.setCanceledOnTouchOutside(false);
|
193
191
|
loadingDialog.setOnCancelListener(new OnCancelListener() {
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
192
|
+
public void onCancel(DialogInterface dialog) {
|
193
|
+
dialogCancelled = true;
|
194
|
+
finish();
|
195
|
+
}
|
196
|
+
});
|
199
197
|
loadingDialog.show();
|
200
198
|
}
|
201
199
|
} else {
|
@@ -213,48 +211,48 @@ public class SplashActivity extends Activity {
|
|
213
211
|
|
214
212
|
private void registerPackageInstallReceiver() {
|
215
213
|
receiver = new BroadcastReceiver(){
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
214
|
+
public void onReceive(Context context, Intent intent) {
|
215
|
+
Log.d("Received intent: " + intent + " (" + intent.getExtras() + ")");
|
216
|
+
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
|
217
|
+
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
|
218
|
+
if (downloadId == enqueue) {
|
219
|
+
if (localFile.exists()) {
|
220
|
+
return;
|
221
|
+
}
|
222
|
+
Query query = new Query();
|
223
|
+
query.setFilterById(enqueue);
|
224
|
+
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
|
225
|
+
Cursor c = dm.query(query);
|
226
|
+
if (c.moveToFirst()) {
|
227
|
+
hideProgress();
|
228
|
+
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
|
229
|
+
if (DownloadManager.STATUS_SUCCESSFUL == status) {
|
230
|
+
storeDownload(dm, downloadId);
|
231
|
+
installDownload();
|
232
|
+
} else {
|
233
|
+
int reason = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_REASON));
|
234
|
+
Toast.makeText(context,"Download failed (" + status + "): " + reason, Toast.LENGTH_LONG).show();
|
235
|
+
}
|
236
|
+
} else {
|
237
|
+
Toast.makeText(context,"Download diappeared!", Toast.LENGTH_LONG).show();
|
238
|
+
}
|
239
|
+
c.close();
|
240
|
+
}
|
241
|
+
} else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
|
242
|
+
if (intent.getData().toString().equals("package:org.ruboto.core")) {
|
243
|
+
Toast.makeText(context,"Ruboto Core is now installed.",Toast.LENGTH_LONG).show();
|
244
|
+
deleteFile(RUBOTO_APK);
|
245
|
+
if (receiver != null) {
|
246
|
+
unregisterReceiver(receiver);
|
247
|
+
receiver = null;
|
248
|
+
}
|
249
|
+
initJRuby(false);
|
250
|
+
} else {
|
251
|
+
Toast.makeText(context,"Installed: " + intent.getData().toString(),Toast.LENGTH_LONG).show();
|
252
|
+
}
|
253
|
+
}
|
254
|
+
}
|
255
|
+
};
|
258
256
|
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
|
259
257
|
filter.addDataScheme("package");
|
260
258
|
registerReceiver(receiver, filter);
|
@@ -359,7 +357,7 @@ public class SplashActivity extends Activity {
|
|
359
357
|
// EMXIF
|
360
358
|
|
361
359
|
Cursor query = getContentResolver().query(settingsUri, projection,
|
362
|
-
|
360
|
+
selection, selectionArgs, null);
|
363
361
|
return query.getCount() == 1;
|
364
362
|
}
|
365
363
|
|
@@ -376,7 +374,7 @@ public class SplashActivity extends Activity {
|
|
376
374
|
totalBytes = (int) c.getLong(totalSizeIndex);
|
377
375
|
}
|
378
376
|
System.out.println("PERCEN ------" + downloadedBytesSoFar
|
379
|
-
|
377
|
+
+ " ------ " + totalBytes + "****" + percentage);
|
380
378
|
percentage = (downloadedBytesSoFar * 100 / totalBytes);
|
381
379
|
System.out.println("percentage % " + percentage);
|
382
380
|
} catch (Exception e) {
|
@@ -386,9 +384,9 @@ public class SplashActivity extends Activity {
|
|
386
384
|
}
|
387
385
|
|
388
386
|
private void startUserActivity() {
|
389
|
-
|
390
|
-
|
391
|
-
|
387
|
+
if (getIntent().hasExtra(Intent.EXTRA_INTENT)) {
|
388
|
+
startActivity((Intent)getIntent().getParcelableExtra(Intent.EXTRA_INTENT));
|
389
|
+
}
|
392
390
|
}
|
393
391
|
|
394
392
|
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Ruboto::Activity::Reload
|
2
|
+
import org.ruboto.Log
|
3
|
+
|
4
|
+
def onResume
|
5
|
+
Log.d "Ruboto::Activity::Reload onResume"
|
6
|
+
super
|
7
|
+
|
8
|
+
@ruboto_activity_reload_receiver = ReloadReceiver.new(self)
|
9
|
+
filter = android.content.IntentFilter.new(android.content.Intent::ACTION_VIEW)
|
10
|
+
registerReceiver(@ruboto_activity_reload_receiver, filter)
|
11
|
+
Log.d "Ruboto::Activity::Reload registered reload receiver"
|
12
|
+
rescue Exception
|
13
|
+
Log.e "Exception registering reload listener: #{$!.message}"
|
14
|
+
Log.e $!.backtrace.join("\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
def onPause
|
18
|
+
super
|
19
|
+
unregisterReceiver(@ruboto_activity_reload_receiver)
|
20
|
+
@ruboto_activity_reload_receiver = nil
|
21
|
+
Log.d "Ruboto::Activity::Reload unregistered reload receiver"
|
22
|
+
rescue Exception
|
23
|
+
Log.e "Exception unregistering reload listener: #{$!.message}"
|
24
|
+
Log.e $!.backtrace.join("\n")
|
25
|
+
end
|
26
|
+
|
27
|
+
def ruboto_activity_reload(scripts)
|
28
|
+
Log.d "Got reload intent: #{scripts}"
|
29
|
+
end
|
30
|
+
|
31
|
+
class ReloadReceiver < android.content.BroadcastReceiver
|
32
|
+
def initialize(activity)
|
33
|
+
super()
|
34
|
+
@activity = activity
|
35
|
+
end
|
36
|
+
|
37
|
+
# FIXME(uwe): I would like to receive a string array,
|
38
|
+
# but have not found a way to do that.
|
39
|
+
def onReceive(context, reload_intent)
|
40
|
+
Log.d "Got reload intent: #{reload_intent.inspect}"
|
41
|
+
file = reload_intent.get_string_extra('file')
|
42
|
+
if file
|
43
|
+
Log.d "load file: #{file.inspect}"
|
44
|
+
load file
|
45
|
+
end
|
46
|
+
if (reload_intent.get_string_extra('restart'))
|
47
|
+
Log.d 'restart activity'
|
48
|
+
if @activity.intent.action == android.content.Intent::ACTION_MAIN
|
49
|
+
restart_intent = android.content.Intent.new(@activity.intent).setAction(android.content.Intent::ACTION_VIEW)
|
50
|
+
else
|
51
|
+
restart_intent = @activity.intent
|
52
|
+
end
|
53
|
+
@activity.startActivity(restart_intent)
|
54
|
+
@activity.finish
|
55
|
+
Log.d 'activity restarted'
|
56
|
+
end
|
57
|
+
Log.d 'reload complete.'
|
58
|
+
true
|
59
|
+
rescue Exception
|
60
|
+
Log.e "Exception handling reload broadcast: #{$!.message}"
|
61
|
+
Log.e $!.backtrace.join("\n")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|