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.
@@ -0,0 +1,394 @@
1
+ package org.ruboto;
2
+
3
+ import android.app.Activity;
4
+ import android.app.DownloadManager;
5
+ import android.app.DownloadManager.Query;
6
+ import android.app.DownloadManager.Request;
7
+ import android.app.ProgressDialog;
8
+ import android.content.BroadcastReceiver;
9
+ import android.content.Context;
10
+ import android.content.DialogInterface;
11
+ import android.content.DialogInterface.OnCancelListener;
12
+ import android.content.Intent;
13
+ import android.content.IntentFilter;
14
+ import android.content.pm.PackageManager;
15
+ import android.database.Cursor;
16
+ import android.net.Uri;
17
+ import android.os.Bundle;
18
+ import android.provider.Settings;
19
+ import android.view.View;
20
+ import android.widget.TextView;
21
+ import android.widget.Toast;
22
+
23
+
24
+ public class SplashActivity extends Activity {
25
+ private int splash = 0;
26
+ private ProgressDialog loadingDialog;
27
+ private boolean dialogCancelled = false;
28
+ private BroadcastReceiver receiver;
29
+ private long enqueue;
30
+ java.io.File localFile;
31
+ private static final int INSTALL_REQUEST_CODE = 4242;
32
+
33
+ public void onCreate(Bundle bundle) {
34
+ Log.d("SplashActivity onCreate:");
35
+ localFile = new java.io.File(getFilesDir(), RUBOTO_APK);
36
+ try {
37
+ splash = Class.forName(getPackageName() + ".R$layout").getField("splash").getInt(null);
38
+ } catch (Exception e) {
39
+ splash = -1;
40
+ }
41
+ if (!JRubyAdapter.isInitialized()) {
42
+ initJRuby(true);
43
+ }
44
+ super.onCreate(bundle);
45
+ }
46
+
47
+ public void onResume() {
48
+ Log.d("onResume: ");
49
+ if (!JRubyAdapter.isInitialized() && receiver == null) {
50
+ registerPackageInstallReceiver();
51
+ }
52
+ super.onResume();
53
+ }
54
+
55
+ public void onPause() {
56
+ Log.d("onPause: ");
57
+ if (receiver != null) {
58
+ unregisterReceiver(receiver);
59
+ receiver = null;
60
+ }
61
+ super.onPause();
62
+ }
63
+
64
+ public void onDestroy() {
65
+ Log.d("onDestroy: ");
66
+ super.onDestroy();
67
+ if (dialogCancelled) {
68
+ System.runFinalizersOnExit(true);
69
+ System.exit(0);
70
+ }
71
+ }
72
+
73
+ private void initJRuby(final boolean firstTime) {
74
+ showProgress();
75
+ new Thread(new Runnable() {
76
+ public void run() {
77
+ final boolean jrubyOk = JRubyAdapter.setUpJRuby(SplashActivity.this);
78
+ if (jrubyOk) {
79
+ Log.d("onResume: JRuby OK");
80
+ startUserActivity();
81
+ hideProgress();
82
+ finish();
83
+ } else {
84
+ registerPackageInstallReceiver();
85
+ runOnUiThread(new Runnable() {
86
+ public void run() {
87
+ if (localFile.exists()) {
88
+ installDownload();
89
+ } else {
90
+ if (firstTime) {
91
+ Log.d("onResume: Checking JRuby - IN UI thread");
92
+ try {
93
+ setContentView(Class.forName(getPackageName() + ".R$layout").getField("get_ruboto_core").getInt(null));
94
+ if (hasInternetPermission()) {
95
+ getRubotoCore(null);
96
+ return;
97
+ }
98
+ } catch (Exception e) {
99
+ }
100
+ } else {
101
+ Toast.makeText(SplashActivity.this,"Failed to initialize Ruboto Core.",Toast.LENGTH_LONG).show();
102
+ try {
103
+ TextView textView = (TextView) findViewById(Class.forName(getPackageName() + ".R$id").getField("text").getInt(null));
104
+ 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/");
105
+ } catch (Exception e) {
106
+ }
107
+ }
108
+ }
109
+ hideProgress();
110
+ }
111
+ });
112
+ }
113
+ }
114
+ }).start();
115
+ }
116
+
117
+ private static final String RUBOTO_APK = "RubotoCore-release.apk";
118
+ private static final String RUBOTO_URL = "http://ruboto.org/downloads/" + RUBOTO_APK;
119
+
120
+ // Called when the button is pressed.
121
+ public void getRubotoCore(View view) {
122
+ try {
123
+ if (hasInternetPermission() && canInstallFromUnknownSources()) {
124
+ if (enqueue <= 0) {
125
+ DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
126
+ Request request = new Request(Uri.parse(RUBOTO_URL));
127
+ enqueue = dm.enqueue(request);
128
+ hideProgress();
129
+ showDownloadProgress("Downloading RubotoCore...");
130
+ new Thread(new Runnable() {
131
+ public void run() {
132
+ while (loadingDialog != null && enqueue > 0) {
133
+ // FIXME(uwe): Also set total bytes and bytes downloaded.
134
+ loadingDialog.setProgress(getProgressPercentage());
135
+ try {
136
+ Thread.sleep(1000);
137
+ } catch (InterruptedException ie) {
138
+ Log.e("Interupted!");
139
+ }
140
+ }
141
+ }
142
+ }).start();
143
+ }
144
+ return;
145
+ }
146
+ } catch (Exception e) {
147
+ Log.e("Exception in direct RubotoCore download: " + e);
148
+ }
149
+ try {
150
+ startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("market://details?id=org.ruboto.core")));
151
+ } catch (android.content.ActivityNotFoundException anfe) {
152
+ Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(RUBOTO_URL));
153
+ startActivity(intent);
154
+ }
155
+ }
156
+
157
+ private void showProgress() {
158
+ if (loadingDialog == null) {
159
+ if (splash > 0) {
160
+ Log.i("Showing splash");
161
+ requestWindowFeature(android.view.Window.FEATURE_NO_TITLE);
162
+ setContentView(splash);
163
+ } else {
164
+ Log.i("Showing progress");
165
+ loadingDialog = ProgressDialog.show(this, null, "Starting...", true, true);
166
+ loadingDialog.setCanceledOnTouchOutside(false);
167
+ loadingDialog.setOnCancelListener(new OnCancelListener() {
168
+ public void onCancel(DialogInterface dialog) {
169
+ dialogCancelled = true;
170
+ finish();
171
+ }
172
+ });
173
+ }
174
+ }
175
+ }
176
+
177
+ private void showDownloadProgress(String message) {
178
+ if (loadingDialog == null) {
179
+ if (splash > 0) {
180
+ Log.i("Showing splash");
181
+ requestWindowFeature(android.view.Window.FEATURE_NO_TITLE);
182
+ setContentView(splash);
183
+ } else {
184
+ Log.i("Showing progress");
185
+ loadingDialog = new ProgressDialog(this);
186
+ loadingDialog.setTitle(null);
187
+ loadingDialog.setMessage(message);
188
+ loadingDialog.setIndeterminate(false);
189
+ loadingDialog.setMax(100);
190
+ loadingDialog.setProgressStyle(android.app.ProgressDialog.STYLE_HORIZONTAL);
191
+ loadingDialog.setCancelable(true);
192
+ loadingDialog.setCanceledOnTouchOutside(false);
193
+ loadingDialog.setOnCancelListener(new OnCancelListener() {
194
+ public void onCancel(DialogInterface dialog) {
195
+ dialogCancelled = true;
196
+ finish();
197
+ }
198
+ });
199
+ loadingDialog.show();
200
+ }
201
+ } else {
202
+ loadingDialog.setMessage(message);
203
+ }
204
+ }
205
+
206
+ private void hideProgress() {
207
+ if (loadingDialog != null) {
208
+ Log.d("Hide progress");
209
+ loadingDialog.dismiss();
210
+ loadingDialog = null;
211
+ }
212
+ }
213
+
214
+ private void registerPackageInstallReceiver() {
215
+ receiver = new BroadcastReceiver(){
216
+ public void onReceive(Context context, Intent intent) {
217
+ Log.d("Received intent: " + intent + " (" + intent.getExtras() + ")");
218
+ if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
219
+ long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
220
+ if (downloadId == enqueue) {
221
+ if (localFile.exists()) {
222
+ return;
223
+ }
224
+ Query query = new Query();
225
+ query.setFilterById(enqueue);
226
+ DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
227
+ Cursor c = dm.query(query);
228
+ if (c.moveToFirst()) {
229
+ hideProgress();
230
+ int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
231
+ if (DownloadManager.STATUS_SUCCESSFUL == status) {
232
+ storeDownload(dm, downloadId);
233
+ installDownload();
234
+ } else {
235
+ int reason = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_REASON));
236
+ Toast.makeText(context,"Download failed (" + status + "): " + reason, Toast.LENGTH_LONG).show();
237
+ }
238
+ } else {
239
+ Toast.makeText(context,"Download diappeared!", Toast.LENGTH_LONG).show();
240
+ }
241
+ c.close();
242
+ }
243
+ } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
244
+ if (intent.getData().toString().equals("package:org.ruboto.core")) {
245
+ Toast.makeText(context,"Ruboto Core is now installed.",Toast.LENGTH_LONG).show();
246
+ deleteFile(RUBOTO_APK);
247
+ if (receiver != null) {
248
+ unregisterReceiver(receiver);
249
+ receiver = null;
250
+ }
251
+ initJRuby(false);
252
+ } else {
253
+ Toast.makeText(context,"Installed: " + intent.getData().toString(),Toast.LENGTH_LONG).show();
254
+ }
255
+ }
256
+ }
257
+ };
258
+ IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
259
+ filter.addDataScheme("package");
260
+ registerReceiver(receiver, filter);
261
+ IntentFilter download_filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
262
+ registerReceiver(receiver, download_filter);
263
+ }
264
+
265
+ private void storeDownload(DownloadManager dm, long downloadId) {
266
+ try {
267
+ android.os.ParcelFileDescriptor file = dm.openDownloadedFile(downloadId);
268
+ java.io.InputStream fileStream = new java.io.FileInputStream(file.getFileDescriptor());
269
+ java.io.FileOutputStream fos = openFileOutput(RUBOTO_APK, MODE_WORLD_READABLE);
270
+ byte[] buffer = new byte[1024];
271
+ int length;
272
+ while((length = fileStream.read(buffer)) > 0) {
273
+ fos.write(buffer, 0, length);
274
+ }
275
+ fos.flush();
276
+ fileStream.close();
277
+ fos.close();
278
+ dm.remove(downloadId);
279
+ enqueue = 0;
280
+ } catch (java.io.IOException ioe) {
281
+ Log.e("Exception copying RubotoCore: " + ioe);
282
+ Toast.makeText(this, "Exception copying RubotoCore: " + ioe, Toast.LENGTH_LONG).show();
283
+ }
284
+ }
285
+
286
+ // FIXME(uwe): Remove when we stop supporting Android < 4.0.3
287
+ private void installDownload() {
288
+ if (android.os.Build.VERSION.SDK_INT < 15) {
289
+ installDownload_10();
290
+ } else {
291
+ installDownload_15();
292
+ }
293
+ }
294
+ // EMXIF
295
+
296
+ // FIXME(uwe): Remove when we stop supporting Android < 4.0.3
297
+ private void installDownload_10() {
298
+ Uri uri = Uri.fromFile(localFile);
299
+ SplashActivity.this.grantUriPermission("com.android.packageinstaller", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
300
+ Intent installIntent = new Intent(Intent.ACTION_VIEW);
301
+ installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
302
+ installIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
303
+ startActivityForResult(installIntent, INSTALL_REQUEST_CODE);
304
+ }
305
+ // EMXIF
306
+
307
+ // FIXME(uwe): Use constants when we stop suporting Android < 4.0.3
308
+ private void installDownload_15() {
309
+ Uri uri = Uri.fromFile(localFile);
310
+ SplashActivity.this.grantUriPermission("com.android.packageinstaller", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
311
+ Intent installIntent = new Intent("android.intent.action.INSTALL_PACKAGE"); // Intent.ACTION_INSTALL_PACKAGE
312
+ installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
313
+ installIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
314
+ // FIXME(uwe): Remove when we stop supporting Android api level < 16
315
+ installIntent.putExtra("android.intent.extra.ALLOW_REPLACE", true); // Intent.EXTRA_ALLOW_REPLACE
316
+ // EMXIF
317
+ installIntent.putExtra("android.intent.extra.INSTALLER_PACKAGE_NAME", getPackageName()); // Intent.EXTRA_INSTALLER_PACKAGE_NAME
318
+ installIntent.putExtra("android.intent.extra.NOT_UNKNOWN_SOURCE", true); // Intent.EXTRA_NOT_UNKNOWN_SOURCE
319
+ installIntent.putExtra("android.intent.extra.RETURN_RESULT", true); // Intent.EXTRA_RETURN_RESULT
320
+ startActivityForResult(installIntent, INSTALL_REQUEST_CODE);
321
+ }
322
+ // EMXIF
323
+
324
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
325
+ Log.d("onActivityResult: " + requestCode + ", " + resultCode + ", " + data);
326
+ Log.d("onActivityResult: " + INSTALL_REQUEST_CODE + ", " + RESULT_OK + ", " + RESULT_CANCELED);
327
+ if (requestCode == INSTALL_REQUEST_CODE) {
328
+ if (resultCode == RESULT_OK) {
329
+ Log.d("onActivityResult: Install OK.");
330
+ } else if (resultCode == RESULT_CANCELED) {
331
+ Log.d("onActivityResult: Install canceled.");
332
+ // FIXME(uwe): Maybe show a dialog explaining that RubotoCore is needed and try again?
333
+ deleteFile(RUBOTO_APK);
334
+ if (!JRubyAdapter.isInitialized()) {
335
+ finish();
336
+ }
337
+ // EMXIF
338
+ } else {
339
+ Log.e("onActivityResult: resultCode: " + resultCode);
340
+ }
341
+ }
342
+ super.onActivityResult(requestCode, resultCode, data);
343
+ }
344
+
345
+ private boolean hasInternetPermission() {
346
+ String permission = "android.permission.INTERNET";
347
+ int res = checkCallingOrSelfPermission(permission);
348
+ return (res == PackageManager.PERMISSION_GRANTED);
349
+ }
350
+
351
+ private boolean canInstallFromUnknownSources() {
352
+ Uri settingsUri = Settings.Secure.CONTENT_URI;
353
+ String[] projection = new String[]{Settings.System.VALUE};
354
+ String selection = Settings.Secure.NAME + " = ? AND " + Settings.Secure.VALUE + " = ?";
355
+
356
+ // FIXME(uwe): Use android.provider.Settings.Global.INSTALL_NON_MARKET_APPS
357
+ // when we stop supporting Android api level < 17
358
+ String[] selectionArgs = {Settings.Secure.INSTALL_NON_MARKET_APPS, String.valueOf(1)};
359
+ // EMXIF
360
+
361
+ Cursor query = getContentResolver().query(settingsUri, projection,
362
+ selection, selectionArgs, null);
363
+ return query.getCount() == 1;
364
+ }
365
+
366
+ // Get the downloaded percent
367
+ private int getProgressPercentage() {
368
+ int downloadedBytesSoFar = 0, totalBytes = 0, percentage = 0;
369
+ DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
370
+ try {
371
+ Cursor c = dm.query(new DownloadManager.Query().setFilterById(enqueue));
372
+ if (c.moveToFirst()) {
373
+ int soFarIndex =c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
374
+ downloadedBytesSoFar = (int) c.getLong(soFarIndex);
375
+ int totalSizeIndex = c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
376
+ totalBytes = (int) c.getLong(totalSizeIndex);
377
+ }
378
+ System.out.println("PERCEN ------" + downloadedBytesSoFar
379
+ + " ------ " + totalBytes + "****" + percentage);
380
+ percentage = (downloadedBytesSoFar * 100 / totalBytes);
381
+ System.out.println("percentage % " + percentage);
382
+ } catch (Exception e) {
383
+ e.printStackTrace();
384
+ }
385
+ return percentage;
386
+ }
387
+
388
+ private void startUserActivity() {
389
+ if (getIntent().hasExtra(Intent.EXTRA_INTENT)) {
390
+ startActivity((Intent)getIntent().getParcelableExtra(Intent.EXTRA_INTENT));
391
+ }
392
+ }
393
+
394
+ }
@@ -14,9 +14,24 @@ require 'ruboto/package'
14
14
  #
15
15
  module Ruboto
16
16
  module Context
17
- def start_ruboto_dialog(remote_variable, theme=Java::android.R.style::Theme_Dialog, &block)
18
- java_import 'org.ruboto.RubotoDialog'
19
- start_ruboto_activity(remote_variable, RubotoDialog, theme, &block)
17
+ def start_ruboto_dialog(class_name = nil, options = nil, &block)
18
+ if options.nil?
19
+ if class_name.is_a?(Hash)
20
+ options = class_name
21
+ class_name = nil
22
+ else
23
+ options = {}
24
+ end
25
+ end
26
+
27
+ unless options.key?(:java_class)
28
+ java_import 'org.ruboto.RubotoDialog'
29
+ options[:java_class] = RubotoDialog
30
+ end
31
+
32
+ options[:theme] = android.R.style::Theme_Dialog unless options.key?(:theme)
33
+
34
+ start_ruboto_activity(class_name, options, &block)
20
35
  end
21
36
 
22
37
  def start_ruboto_activity(class_name = nil, options = nil, &block)
@@ -43,6 +58,7 @@ module Ruboto
43
58
  # EMXIF
44
59
 
45
60
  script_name = options.delete(:script)
61
+ extras = options.delete(:extras)
46
62
  raise "Unknown options: #{options}" unless options.empty?
47
63
 
48
64
  if class_name.nil? && block_given?
@@ -50,6 +66,8 @@ module Ruboto
50
66
  "#{java_class.name.split('::').last}_#{source_descriptor(block)[0].split('/').last.gsub(/[.-]+/, '_')}_#{source_descriptor(block)[1]}"
51
67
  end
52
68
 
69
+ class_name = class_name.to_s
70
+
53
71
  if Object.const_defined?(class_name)
54
72
  Object.const_get(class_name).class_eval(&block) if block_given?
55
73
  else
@@ -60,6 +78,7 @@ module Ruboto
60
78
  i.putExtra(Ruboto::THEME_KEY, theme) if theme
61
79
  i.putExtra(Ruboto::CLASS_NAME_KEY, class_name) if class_name
62
80
  i.putExtra(Ruboto::SCRIPT_NAME_KEY, script_name) if script_name
81
+ extras.each { |k, v| i.putExtra(k.to_s, v) } if extras
63
82
  startActivity i
64
83
  self
65
84
  end
@@ -103,10 +103,10 @@ module Ruboto
103
103
  update_assets
104
104
  update_ruboto true
105
105
  update_icons true
106
- update_classes nil, true
106
+ update_classes nil, 'exclude'
107
107
  update_jruby true if with_jruby
108
108
  update_dx_jar true if with_jruby
109
- update_core_classes 'include'
109
+ update_core_classes 'exclude'
110
110
 
111
111
  log_action('Generating the default Activity and script') do
112
112
  generate_inheriting_file 'Activity', activity, package
@@ -351,7 +351,7 @@ module Ruboto
351
351
  update_jruby force
352
352
  update_manifest nil, nil, force
353
353
  update_icons force
354
- update_core_classes 'include'
354
+ update_core_classes 'exclude'
355
355
  update_bundle
356
356
  when 'jruby' then
357
357
  update_jruby(params['force'].value, true) || abort
@@ -394,12 +394,14 @@ module Ruboto
394
394
  api_level = project_api_level
395
395
 
396
396
  option('target', 't') {
397
- description 'sets the target Android API level for the emulator (example: -t android-15)'
397
+ extend Ruboto::Util::Emulator
398
+ description 'sets the target Android API level for the emulator'
399
+ examples Ruboto::Util::Emulator::API_LEVEL_TO_VERSION.keys.join(', ')
398
400
  required unless api_level
399
401
  argument :required
400
402
  default(api_level) if api_level
401
403
  cast {|t| t =~ /^(\d+)$/ ? "android-#$1" : t}
402
- validate {|t| t =~ /^android-\d+$/}
404
+ validate {|t| t =~ /^android-(\d+)$/ && sdk_level_name($1.to_i)}
403
405
  }
404
406
 
405
407
  def run
@@ -6,8 +6,8 @@ module Ruboto
6
6
  ON_WINDOWS = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/i)
7
7
 
8
8
  API_LEVEL_TO_VERSION = {
9
- 7 => '2.1', 8 => '2.2', 10 => '2.3.3', 11 => '3.0', 12 => '3.1',
10
- 13 => '3.2', 14 => '4.0', 15 => '4.0.3', 16 => '4.1.2', 17 => '4.2.2',
9
+ 10 => '2.3.3', 11 => '3.0', 12 => '3.1', 13 => '3.2', 14 => '4.0',
10
+ 15 => '4.0.3', 16 => '4.1.2', 17 => '4.2.2',
11
11
  }
12
12
 
13
13
  def sdk_level_name(sdk_level)
@@ -52,6 +52,7 @@ module Ruboto
52
52
  puts 'No emulator is running.'
53
53
  end
54
54
 
55
+ # FIXME(uwe): Change use of "killall" to use the Ruby Process API
55
56
  loop do
56
57
  `killall -0 #{emulator_cmd} 2> /dev/null`
57
58
  if $? == 0
@@ -83,16 +84,18 @@ module Ruboto
83
84
  abi_opt = '--abi armeabi'
84
85
  end
85
86
 
86
- unless File.exists? "#{ENV['HOME']}/.android/avd/#{avd_name}.avd"
87
+ avd_home = "#{ENV['HOME'].gsub('\\', '/')}/.android/avd/#{avd_name}.avd"
88
+ unless File.exists? avd_home
87
89
  puts "Creating AVD #{avd_name}"
88
90
  puts `echo n | android create avd -a -n #{avd_name} -t android-#{sdk_level} #{abi_opt} -c 64M -s HVGA`
89
91
  if $? != 0
90
92
  puts 'Failed to create AVD.'
91
93
  exit 3
92
94
  end
93
- avd_config_file_name = "#{ENV['HOME']}/.android/avd/#{avd_name}.avd/config.ini"
95
+ avd_config_file_name = "#{avd_home}/config.ini"
94
96
  old_avd_config = File.read(avd_config_file_name)
95
- heap_size = (File.read('AndroidManifest.xml') =~ /largeHeap/) ? 256 : 48
97
+ manifest_file = 'AndroidManifest.xml'
98
+ heap_size = (File.exists?(manifest_file) && File.read(manifest_file) =~ /largeHeap/) ? 256 : 48
96
99
  new_avd_config = old_avd_config.gsub(/vm.heapSize=([0-9]*)/) { |m| p m; m.to_i < heap_size ? "vm.heapSize=#{heap_size}" : m }
97
100
  File.write(avd_config_file_name, new_avd_config) if new_avd_config != old_avd_config
98
101
  new_snapshot = true
@@ -163,7 +166,7 @@ module Ruboto
163
166
  for i in 1 2 3 4 5 6 7 8 9 10 ; do
164
167
  sleep 6
165
168
  adb shell input keyevent 82 >/dev/null 2>&1
166
- if [ "$?" == "0" ] ; then
169
+ if [ "$?" = "0" ] ; then
167
170
  set -e
168
171
  adb shell input keyevent 82 >/dev/null 2>&1
169
172
  adb shell input keyevent 4 >/dev/null 2>&1
@@ -46,7 +46,7 @@ module Ruboto
46
46
  case RbConfig::CONFIG['host_os']
47
47
  when /^darwin(.*)/ then
48
48
  'macosx'
49
- when /^linux(.*)/ then
49
+ when /linux/ then
50
50
  'linux'
51
51
  when /^mswin32|windows(.*)/ then
52
52
  'windows'
@@ -60,7 +60,7 @@ module Ruboto
60
60
  if RbConfig::CONFIG['host_os'] =~ /^mswin32|windows(.*)/
61
61
  'AppData/Local/Android/android-sdk'
62
62
  else
63
- "android-sdk-#{android_package_os_id}"
63
+ ENV['ANDROID_HOME'] ? ENV['ANDROID_HOME'] : File.join(File.expand_path('~'), "android-sdk-#{android_package_os_id}")
64
64
  end
65
65
  end
66
66
 
@@ -68,7 +68,7 @@ module Ruboto
68
68
  case RbConfig::CONFIG['host_os']
69
69
  when /^darwin(.*)/ then
70
70
  '.profile'
71
- when /^linux(.*)/ then
71
+ when /linux/ then
72
72
  '.bashrc'
73
73
  when /^mswin32|windows(.*)/ then
74
74
  'windows'
@@ -118,22 +118,22 @@ module Ruboto
118
118
 
119
119
  def check_for_emulator
120
120
  @emulator_loc = check_for('emulator', 'Android Emulator',
121
- File.join(File.expand_path('~'), android_package_directory, 'tools', 'emulator'))
121
+ File.join(android_package_directory, 'tools', 'emulator'))
122
122
  end
123
123
 
124
124
  def check_for_platform_tools
125
125
  @adb_loc = check_for('adb', 'Android SDK Command adb',
126
- File.join(File.expand_path('~'), android_package_directory, 'platform-tools', 'adb'))
126
+ File.join(android_package_directory, 'platform-tools', 'adb'))
127
127
  end
128
128
 
129
129
  def check_for_build_tools
130
130
  @dx_loc = check_for('dx', 'Android SDK Command dx',
131
- Dir[File.join(File.expand_path('~'), android_package_directory, 'build-tools', '*', 'dx')][-1])
131
+ Dir[File.join(android_package_directory, 'build-tools', '*', 'dx')][-1])
132
132
  end
133
133
 
134
134
  def check_for_android_sdk
135
135
  @android_loc = check_for('android', 'Android Package Installer',
136
- File.join(File.expand_path('~'), android_package_directory, 'tools', 'android'))
136
+ File.join(android_package_directory, 'tools', 'android'))
137
137
  end
138
138
 
139
139
  def check_for(cmd, pretty_name=nil, alt_dir=nil)
@@ -172,6 +172,7 @@ module Ruboto
172
172
  install_java(accept_all) unless @java_loc && @javac_loc
173
173
  install_ant(accept_all) unless @ant_loc
174
174
  install_android_sdk(accept_all) unless @android_loc
175
+ check_all(api_levels)
175
176
  install_android_tools(accept_all) unless @dx_loc && @adb_loc && @emulator_loc # build-tools, platform-tools and tools
176
177
  if @android_loc
177
178
  api_levels.each do |api_level|
@@ -183,7 +184,7 @@ module Ruboto
183
184
  def install_java(accept_all)
184
185
  case RbConfig::CONFIG['host_os']
185
186
  when /^darwin(.*)/
186
- when /^linux(.*)/
187
+ when /linux/
187
188
  when /^mswin32|windows(.*)/
188
189
  # FIXME(uwe): Detect and warn if we are not "elevated" with adminstrator rights.
189
190
  #set IS_ELEVATED=0
@@ -238,7 +239,7 @@ module Ruboto
238
239
  def install_ant(accept_all)
239
240
  case RbConfig::CONFIG['host_os']
240
241
  when /^darwin(.*)/
241
- when /^linux(.*)/
242
+ when /linux/
242
243
  when /^mswin32|windows(.*)/
243
244
  # FIXME(uwe): Detect and warn if we are not "elevated" with adminstrator rights.
244
245
  #set IS_ELEVATED=0
@@ -357,7 +358,7 @@ module Ruboto
357
358
  system "wget http://dl.google.com/android/#{asdk_file_name}"
358
359
  system "unzip #{'-o ' if accept_all}#{asdk_file_name}"
359
360
  system "rm #{asdk_file_name}"
360
- when /^linux(.*)/
361
+ when /linux/
361
362
  asdk_file_name = "android-sdk_r#{get_tools_version}-#{android_package_os_id}.tgz"
362
363
  system "wget http://dl.google.com/android/#{asdk_file_name}"
363
364
  system "tar -xzf #{asdk_file_name}"
@@ -389,10 +390,12 @@ module Ruboto
389
390
  end
390
391
  end
391
392
  check_for_android_sdk
392
- unless @android_loc
393
- ENV['ANDROID_HOME'] = @android_loc.gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
393
+ unless @android_loc.nil?
394
+ ENV['ANDROID_HOME'] = (File.expand_path File.dirname(@android_loc)+"/..").gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
394
395
  puts "Setting the ANDROID_HOME environment variable to #{ENV['ANDROID_HOME']}"
395
- system %Q{setx ANDROID_HOME "#{ENV['ANDROID_HOME']}"}
396
+ if RbConfig::CONFIG['host_os'] =~ /^mswin32|windows(.*)/
397
+ system %Q{setx ANDROID_HOME "#{ENV['ANDROID_HOME']}"}
398
+ end
396
399
  @missing_paths << "#{File.dirname(@android_loc)}"
397
400
  end
398
401
  end
@@ -406,7 +409,7 @@ module Ruboto
406
409
  a = STDIN.gets.chomp.upcase
407
410
  end
408
411
  if accept_all || a == 'Y' || a.empty?
409
- update_cmd = "android --silent update sdk --no-ui --filter build-tools-#{get_tools_version('build-tool')},platform-tool,tool --force"
412
+ update_cmd = "android --silent update sdk --no-ui --filter build-tools-#{get_tools_version('build-tool')},platform-tool,tool -a --force"
410
413
  update_sdk(update_cmd, accept_all)
411
414
  check_for_build_tools
412
415
  check_for_platform_tools
@@ -489,11 +492,6 @@ module Ruboto
489
492
  config_file_name = File.expand_path("~/#{a.nil? || a.empty? ? path_setup_file : a}")
490
493
  old_config = File.read(config_file_name)
491
494
  new_config = old_config.dup
492
-
493
- # FIXME(uwe): Remove for Ruboto > 0.13.0
494
- new_config.gsub! /\n*# BEGIN Ruboto PATH setup\n.*?\n# END Ruboto PATH setup\n*/m, ''
495
- # EMXIF
496
-
497
495
  new_config.gsub! /\n*# BEGIN Ruboto setup\n.*?\n# END Ruboto setup\n*/m, ''
498
496
  new_config << "\n\n# BEGIN Ruboto setup\n"
499
497
  new_config << "source #{rubotorc}\n"