assets/src/org/ruboto/EntryPointActivity.java in ruboto-0.13.0 vs assets/src/org/ruboto/EntryPointActivity.java in ruboto-0.14.0

- old
+ new

@@ -1,69 +1,35 @@ package org.ruboto; -import android.app.DownloadManager; -import android.app.DownloadManager.Query; -import android.app.DownloadManager.Request; -import android.app.ProgressDialog; -import android.content.BroadcastReceiver; import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.net.Uri; import android.os.Bundle; -import android.provider.Settings; -import android.view.View; -import android.widget.TextView; -import android.widget.Toast; /** * This Activity acts as an entry point to the app. It must initialize the * JRuby runtime before continuing its life cycle. * While JRuby is initializing, a progress dialog is shown. * If R.layout.splash is defined, by adding a res/layout/splash.xml file, * this layout is displayed instead of the progress dialog. */ public class EntryPointActivity extends org.ruboto.RubotoActivity { - private int splash = 0; - private ProgressDialog loadingDialog; - private boolean dialogCancelled = false; - private BroadcastReceiver receiver; - private long enqueue; - java.io.File localFile; - private static final int INSTALL_REQUEST_CODE = 4242; - // FIXME(uwe): Remove this field? Duplicated by ScriptInfo.isLoaded() ? - protected boolean appStarted = false; - // EMXIF - - public void onCreate(Bundle bundle) { + public void onCreate(Bundle bundle) { Log.d("EntryPointActivity onCreate:"); - getScriptInfo().setRubyClassName(getClass().getSimpleName()); + getScriptInfo().setRubyClassName(getClass().getSimpleName()); - localFile = new java.io.File(getFilesDir(), RUBOTO_APK); - try { - splash = Class.forName(getPackageName() + ".R$layout").getField("splash").getInt(null); - } catch (Exception e) { - splash = -1; - } + if (!JRubyAdapter.isInitialized()) { + showSplash(); + finish(); + } + super.onCreate(bundle); + } - if (JRubyAdapter.isInitialized()) { - appStarted = true; - } else { - initJRuby(true); - } - super.onCreate(bundle); - } - public void onResume() { Log.d("onResume: "); - if(appStarted) { + if(getScriptInfo().isLoaded()) { Log.d("onResume: App already started!"); super.onResume(); return; } @@ -71,359 +37,47 @@ if (JRubyAdapter.isInitialized()) { Log.d("Already initialized"); fireRubotoActivity(); } else { Log.d("Not initialized"); - super.onResume(); - initJRuby(true); + showSplash(); + finish(); } + super.onResume(); } public void onPause() { Log.d("onPause: "); - - if (receiver != null) { - unregisterReceiver(receiver); - receiver = null; - } super.onPause(); } public void onDestroy() { Log.d("onDestroy: "); - super.onDestroy(); - if (dialogCancelled) { - System.runFinalizersOnExit(true); - System.exit(0); - } } - private void initJRuby(final boolean firstTime) { - showProgress(); - new Thread(new Runnable() { - public void run() { - final boolean jrubyOk = JRubyAdapter.setUpJRuby(EntryPointActivity.this); - if (jrubyOk) { - Log.d("onResume: JRuby OK"); - fireRubotoActivity(); - } else { - registerPackageInstallReceiver(); - runOnUiThread(new Runnable() { - public void run() { - if (localFile.exists()) { - installDownload(); - } else { - if (firstTime) { - Log.d("onResume: Checking JRuby - IN UI thread"); - try { - setContentView(Class.forName(getPackageName() + ".R$layout").getField("get_ruboto_core").getInt(null)); - if (hasInternetPermission()) { - getRubotoCore(null); - return; - } - } catch (Exception e) { - } - } else { - Toast.makeText(EntryPointActivity.this,"Failed to initialize Ruboto Core.",Toast.LENGTH_LONG).show(); - try { - TextView textView = (TextView) findViewById(Class.forName(getPackageName() + ".R$id").getField("text").getInt(null)); - 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/"); - } catch (Exception e) { - } - } - } - hideProgress(); - } - }); - } - } - }).start(); - } - private static final String RUBOTO_APK = "RubotoCore-release.apk"; - private static final String RUBOTO_URL = "http://ruboto.org/downloads/" + RUBOTO_APK; - - // Called when the button is pressed. - public void getRubotoCore(View view) { - try { - if (hasInternetPermission() && canInstallFromUnknownSources()) { - if (enqueue <= 0) { - DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); - Request request = new Request(Uri.parse(RUBOTO_URL)); - enqueue = dm.enqueue(request); - hideProgress(); - showDownloadProgress("Downloading RubotoCore..."); - new Thread(new Runnable() { - public void run() { - while (loadingDialog != null && enqueue > 0) { - // FIXME(uwe): Also set total bytes and bytes downloaded. - loadingDialog.setProgress(getProgressPercentage()); - try { - Thread.sleep(1000); - } catch (InterruptedException ie) { - Log.e("Interupted!"); - } - } - } - }).start(); - } - return; - } - } catch (Exception e) { - Log.e("Exception in direct RubotoCore download: " + e); - } - try { - startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("market://details?id=org.ruboto.core"))); - } catch (android.content.ActivityNotFoundException anfe) { - Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(RUBOTO_URL)); - startActivity(intent); - } - } - protected void fireRubotoActivity() { - if(appStarted) return; - appStarted = true; + if(getScriptInfo().isLoaded()) return; Log.i("Starting activity"); ScriptLoader.loadScript(this); runOnUiThread(new Runnable() { - public void run() { - ScriptLoader.callOnCreate(EntryPointActivity.this, args[0]); - onStart(); - onResume(); - hideProgress(); - } - }); + public void run() { + ScriptLoader.callOnCreate(EntryPointActivity.this, args[0]); + onStart(); + onResume(); + } + }); } - private void showProgress() { - if (loadingDialog == null) { - if (splash > 0) { - Log.i("Showing splash"); - requestWindowFeature(android.view.Window.FEATURE_NO_TITLE); - setContentView(splash); - } else { - Log.i("Showing progress"); - loadingDialog = ProgressDialog.show(this, null, "Starting...", true, true); - loadingDialog.setCanceledOnTouchOutside(false); - loadingDialog.setOnCancelListener(new OnCancelListener() { - public void onCancel(DialogInterface dialog) { - dialogCancelled = true; - finish(); - } - }); - } - } + private void showSplash() { + Intent splashIntent = new Intent(this, SplashActivity.class); + splashIntent.putExtra(Intent.EXTRA_INTENT, futureIntent()); + startActivity(splashIntent); } - - private void showDownloadProgress(String message) { - if (loadingDialog == null) { - if (splash > 0) { - Log.i("Showing splash"); - requestWindowFeature(android.view.Window.FEATURE_NO_TITLE); - setContentView(splash); - } else { - Log.i("Showing progress"); - loadingDialog = new ProgressDialog(this); - loadingDialog.setTitle(null); - loadingDialog.setMessage(message); - loadingDialog.setIndeterminate(false); - loadingDialog.setMax(100); - loadingDialog.setProgressStyle(android.app.ProgressDialog.STYLE_HORIZONTAL); - loadingDialog.setCancelable(true); - loadingDialog.setCanceledOnTouchOutside(false); - loadingDialog.setOnCancelListener(new OnCancelListener() { - public void onCancel(DialogInterface dialog) { - dialogCancelled = true; - finish(); - } - }); - loadingDialog.show(); - } - } else { - loadingDialog.setMessage(message); - } + + // The Intent to to call when done. Defaults to calling this Activity again. + // Override to change. + protected Intent futureIntent() { + return new Intent(this, this.getClass()); } - - private void hideProgress() { - if (loadingDialog != null) { - Log.d("Hide progress"); - loadingDialog.dismiss(); - loadingDialog = null; - } - } - - private void registerPackageInstallReceiver() { - receiver = new BroadcastReceiver(){ - public void onReceive(Context context, Intent intent) { - Log.d("Received intent: " + intent + " (" + intent.getExtras() + ")"); - if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) { - long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0); - if (downloadId == enqueue) { - if (localFile.exists()) { - return; - } - Query query = new Query(); - query.setFilterById(enqueue); - DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); - Cursor c = dm.query(query); - if (c.moveToFirst()) { - hideProgress(); - int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)); - if (DownloadManager.STATUS_SUCCESSFUL == status) { - storeDownload(dm, downloadId); - installDownload(); - } else { - int reason = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_REASON)); - Toast.makeText(context,"Download failed (" + status + "): " + reason, Toast.LENGTH_LONG).show(); - } - } else { - Toast.makeText(context,"Download diappeared!", Toast.LENGTH_LONG).show(); - } - c.close(); - } - } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { - if (intent.getData().toString().equals("package:org.ruboto.core")) { - Toast.makeText(context,"Ruboto Core is now installed.",Toast.LENGTH_LONG).show(); - deleteFile(RUBOTO_APK); - if (receiver != null) { - unregisterReceiver(receiver); - receiver = null; - } - initJRuby(false); - } else { - Toast.makeText(context,"Installed: " + intent.getData().toString(),Toast.LENGTH_LONG).show(); - } - } - } - }; - IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); - filter.addDataScheme("package"); - registerReceiver(receiver, filter); - IntentFilter download_filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); - registerReceiver(receiver, download_filter); - } - - private void storeDownload(DownloadManager dm, long downloadId) { - try { - android.os.ParcelFileDescriptor file = dm.openDownloadedFile(downloadId); - java.io.InputStream fileStream = new java.io.FileInputStream(file.getFileDescriptor()); - java.io.FileOutputStream fos = openFileOutput(RUBOTO_APK, MODE_WORLD_READABLE); - byte[] buffer = new byte[1024]; - int length; - while((length = fileStream.read(buffer)) > 0) { - fos.write(buffer, 0, length); - } - fos.flush(); - fileStream.close(); - fos.close(); - dm.remove(downloadId); - enqueue = 0; - } catch (java.io.IOException ioe) { - Log.e("Exception copying RubotoCore: " + ioe); - Toast.makeText(this, "Exception copying RubotoCore: " + ioe, Toast.LENGTH_LONG).show(); - } - } - - // FIXME(uwe): Remove when we stop supporting Android < 4.0.3 - private void installDownload() { - if (android.os.Build.VERSION.SDK_INT < 15) { - installDownload_10(); - } else { - installDownload_15(); - } - } - // EMXIF - - // FIXME(uwe): Remove when we stop supporting Android < 4.0.3 - private void installDownload_10() { - Uri uri = Uri.fromFile(localFile); - EntryPointActivity.this.grantUriPermission("com.android.packageinstaller", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); - Intent installIntent = new Intent(Intent.ACTION_VIEW); - installIntent.setDataAndType(uri, "application/vnd.android.package-archive"); - installIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivityForResult(installIntent, INSTALL_REQUEST_CODE); - } - // EMXIF - - // FIXME(uwe): Use constants when we stop suporting Android < 4.0.3 - private void installDownload_15() { - Uri uri = Uri.fromFile(localFile); - EntryPointActivity.this.grantUriPermission("com.android.packageinstaller", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); - Intent installIntent = new Intent("android.intent.action.INSTALL_PACKAGE"); // Intent.ACTION_INSTALL_PACKAGE - installIntent.setDataAndType(uri, "application/vnd.android.package-archive"); - installIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); - // FIXME(uwe): Remove when we stop supporting Android api level < 16 - installIntent.putExtra("android.intent.extra.ALLOW_REPLACE", true); // Intent.EXTRA_ALLOW_REPLACE - // EMXIF - installIntent.putExtra("android.intent.extra.INSTALLER_PACKAGE_NAME", getPackageName()); // Intent.EXTRA_INSTALLER_PACKAGE_NAME - installIntent.putExtra("android.intent.extra.NOT_UNKNOWN_SOURCE", true); // Intent.EXTRA_NOT_UNKNOWN_SOURCE - installIntent.putExtra("android.intent.extra.RETURN_RESULT", true); // Intent.EXTRA_RETURN_RESULT - startActivityForResult(installIntent, INSTALL_REQUEST_CODE); - } - // EMXIF - - public void onActivityResult(int requestCode, int resultCode, Intent data) { - Log.d("onActivityResult: " + requestCode + ", " + resultCode + ", " + data); - Log.d("onActivityResult: " + INSTALL_REQUEST_CODE + ", " + RESULT_OK + ", " + RESULT_CANCELED); - if (requestCode == INSTALL_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - Log.d("onActivityResult: Install OK."); - } else if (resultCode == RESULT_CANCELED) { - Log.d("onActivityResult: Install canceled."); - // FIXME(uwe): Maybe show a dialog explaining that RubotoCore is needed and try again? - deleteFile(RUBOTO_APK); - if (!JRubyAdapter.isInitialized()) { - finish(); - } - // EMXIF - } else { - Log.e("onActivityResult: resultCode: " + resultCode); - } - } - super.onActivityResult(requestCode, resultCode, data); - } - - private boolean hasInternetPermission() { - String permission = "android.permission.INTERNET"; - int res = checkCallingOrSelfPermission(permission); - return (res == PackageManager.PERMISSION_GRANTED); - } - - private boolean canInstallFromUnknownSources() { - Uri settingsUri = Settings.Secure.CONTENT_URI; - String[] projection = new String[]{Settings.System.VALUE}; - String selection = Settings.Secure.NAME + " = ? AND " + Settings.Secure.VALUE + " = ?"; - - // FIXME(uwe): Use android.provider.Settings.Global.INSTALL_NON_MARKET_APPS - // when we stop supporting Android api level < 17 - String[] selectionArgs = {Settings.Secure.INSTALL_NON_MARKET_APPS, String.valueOf(1)}; - // EMXIF - - Cursor query = getContentResolver().query(settingsUri, projection, - selection, selectionArgs, null); - return query.getCount() == 1; - } - - // Get the downloaded percent - private int getProgressPercentage() { - int downloadedBytesSoFar = 0, totalBytes = 0, percentage = 0; - DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); - try { - Cursor c = dm.query(new DownloadManager.Query().setFilterById(enqueue)); - if (c.moveToFirst()) { - int soFarIndex =c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR); - downloadedBytesSoFar = (int) c.getLong(soFarIndex); - int totalSizeIndex = c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES); - totalBytes = (int) c.getLong(totalSizeIndex); - } - System.out.println("PERCEN ------" + downloadedBytesSoFar - + " ------ " + totalBytes + "****" + percentage); - percentage = (downloadedBytesSoFar * 100 / totalBytes); - System.out.println("percentage % " + percentage); - } catch (Exception e) { - e.printStackTrace(); - } - return percentage; - } - }