protected void unpackComponents() throws IOException, FileNotFoundException { File applicationPackage = new File(getApplication().getPackageResourcePath()); File componentsDir = new File(sGREDir, "components"); if (componentsDir.lastModified() == applicationPackage.lastModified()) return; componentsDir.mkdir(); componentsDir.setLastModified(applicationPackage.lastModified()); GeckoAppShell.killAnyZombies(); ZipFile zip = new ZipFile(applicationPackage); byte[] buf = new byte[32768]; try { if (unpackFile(zip, buf, null, "removed-files")) removeFiles(); } catch (Exception ex) { // This file may not be there, so just log any errors and move on Log.w(LOG_FILE_NAME, "error removing files", ex); } // copy any .xpi file into an extensions/ directory Enumeration<? extends ZipEntry> zipEntries = zip.entries(); while (zipEntries.hasMoreElements()) { ZipEntry entry = zipEntries.nextElement(); if (entry.getName().startsWith("extensions/") && entry.getName().endsWith(".xpi")) { Log.i("GeckoAppJava", "installing extension : " + entry.getName()); unpackFile(zip, buf, entry, entry.getName()); } } }
public void doRestart() { try { String action = "org.mozilla.gecko.restart"; Intent intent = new Intent(action); intent.setClassName(getPackageName(), getPackageName() + ".Restarter"); addEnvToIntent(intent); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); Log.i(LOG_FILE_NAME, intent.toString()); GeckoAppShell.killAnyZombies(); startActivity(intent); } catch (Exception e) { Log.i(LOG_FILE_NAME, "error doing restart", e); } finish(); // Give the restart process time to start before we die GeckoAppShell.waitForAnotherGeckoProc(); }
@Override protected void onNewIntent(Intent intent) { if (checkLaunchState(LaunchState.GeckoExiting)) { // We're exiting and shouldn't try to do anything else just incase // we're hung for some reason we'll force the process to exit System.exit(0); return; } final String action = intent.getAction(); if (ACTION_DEBUG.equals(action) && checkAndSetLaunchState(LaunchState.Launching, LaunchState.WaitForDebugger)) { mMainHandler.postDelayed( new Runnable() { public void run() { Log.i(LOG_FILE_NAME, "Launching from debug intent after 5s wait"); setLaunchState(LaunchState.Launching); launch(null); } }, 1000 * 5 /* 5 seconds */); Log.i(LOG_FILE_NAME, "Intent : ACTION_DEBUG - waiting 5s before launching"); return; } if (checkLaunchState(LaunchState.WaitForDebugger) || launch(intent)) return; if (Intent.ACTION_MAIN.equals(action)) { Log.i(LOG_FILE_NAME, "Intent : ACTION_MAIN"); GeckoAppShell.sendEventToGecko(new GeckoEvent("")); } else if (Intent.ACTION_VIEW.equals(action)) { String uri = intent.getDataString(); GeckoAppShell.sendEventToGecko(new GeckoEvent(uri)); Log.i(LOG_FILE_NAME, "onNewIntent: " + uri); } else if (ACTION_WEBAPP.equals(action)) { String uri = intent.getStringExtra("args"); GeckoAppShell.sendEventToGecko(new GeckoEvent(uri)); Log.i(LOG_FILE_NAME, "Intent : WEBAPP - " + uri); } else if (ACTION_BOOKMARK.equals(action)) { String args = intent.getStringExtra("args"); GeckoAppShell.sendEventToGecko(new GeckoEvent(args)); Log.i(LOG_FILE_NAME, "Intent : BOOKMARK - " + args); } }
public String showFilePicker(String aMimeType) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType(aMimeType); GeckoApp.this.startActivityForResult( Intent.createChooser(intent, getString(R.string.choose_file)), FILE_PICKER_REQUEST); String filePickerResult = ""; try { while (null == (filePickerResult = mFilePickerResult.poll(1, TimeUnit.MILLISECONDS))) { Log.i("GeckoApp", "processing events from showFilePicker "); GeckoAppShell.processNextNativeEvent(); } } catch (InterruptedException e) { Log.i(LOG_FILE_NAME, "showing file picker ", e); } return filePickerResult; }
private String readUpdateStatus(File statusFile) { String status = ""; try { BufferedReader reader = new BufferedReader(new FileReader(statusFile)); status = reader.readLine(); reader.close(); } catch (Exception e) { Log.i(LOG_FILE_NAME, "error reading update status", e); } return status; }
public void start() { if (myThread == null) { Log.i(getClass().getName(), "Main thread.start()"); myThread = new Thread(this); myThread.start(); } else { Log.w( getClass().getName(), "Requested a thread.start(), but the thread is already running - ignoring this request! (myThread = " + myThread); } }
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { String filePickerResult = ""; if (data != null && resultCode == RESULT_OK) { try { ContentResolver cr = getContentResolver(); Uri uri = data.getData(); Cursor cursor = GeckoApp.mAppContext .getContentResolver() .query(uri, new String[] {OpenableColumns.DISPLAY_NAME}, null, null, null); String name = null; if (cursor != null) { try { if (cursor.moveToNext()) { name = cursor.getString(0); } } finally { cursor.close(); } } String fileName = "tmp_"; String fileExt = null; int period; if (name == null || (period = name.lastIndexOf('.')) == -1) { String mimeType = cr.getType(uri); fileExt = "." + GeckoAppShell.getExtensionFromMimeType(mimeType); } else { fileExt = name.substring(period); fileName = name.substring(0, period); } File file = File.createTempFile(fileName, fileExt, sGREDir); FileOutputStream fos = new FileOutputStream(file); InputStream is = cr.openInputStream(uri); byte[] buf = new byte[4096]; int len = is.read(buf); while (len != -1) { fos.write(buf, 0, len); len = is.read(buf); } fos.close(); filePickerResult = file.getAbsolutePath(); } catch (Exception e) { Log.e(LOG_FILE_NAME, "showing file picker", e); } } try { mFilePickerResult.put(filePickerResult); } catch (InterruptedException e) { Log.i(LOG_FILE_NAME, "error returning file picker result", e); } }
/** Simulate Thread.stop, because Sun refuses to. */ public void waitUntilStoppedBecauseAndroidHasABrokenJVM() { if (myThread != null) { Log.i( getClass().getSimpleName(), "Thread is running, but a stop is required; starting the busy-wait for thread to die (thanks for nothing, Android!)..."); boolean retry = true; myThread = null; while (retry) { try { join(); retry = false; } catch (InterruptedException e) { Log.i(getClass().getSimpleName(), "I'm busy-waiting for the main render thread to die.."); } } Log.i( getClass().getSimpleName(), "Thread is NOW DEAD, according to the Android JVM (thanks for nothing, Android!)..."); } }
@Override public void onResume() { Log.i(LOG_FILE_NAME, "resume"); if (checkLaunchState(LaunchState.GeckoRunning)) GeckoAppShell.onResume(); // After an onPause, the activity is back in the foreground. // Undo whatever we did in onPause. super.onResume(); // Just in case. Normally we start in onNewIntent if (checkLaunchState(LaunchState.PreLaunch) || checkLaunchState(LaunchState.Launching)) onNewIntent(getIntent()); registerReceiver(mConnectivityReceiver, mConnectivityFilter); GeckoNetworkManager.getInstance().start(); GeckoScreenOrientationListener.getInstance().start(); }
private void checkAndLaunchUpdate() { Log.i(LOG_FILE_NAME, "Checking for an update"); int statusCode = 8; // UNEXPECTED_ERROR File baseUpdateDir = null; if (Build.VERSION.SDK_INT >= 8) baseUpdateDir = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); else baseUpdateDir = new File(Environment.getExternalStorageDirectory().getPath(), "download"); File updateDir = new File(new File(baseUpdateDir, "updates"), "0"); File updateFile = new File(updateDir, "update.apk"); File statusFile = new File(updateDir, "update.status"); if (!statusFile.exists() || !readUpdateStatus(statusFile).equals("pending")) return; if (!updateFile.exists()) return; Log.i(LOG_FILE_NAME, "Update is available!"); // Launch APK File updateFileToRun = new File(updateDir, getPackageName() + "-update.apk"); try { if (updateFile.renameTo(updateFileToRun)) { String amCmd = "/system/bin/am start -a android.intent.action.VIEW " + "-n com.android.packageinstaller/.PackageInstallerActivity -d file://" + updateFileToRun.getPath(); Log.i(LOG_FILE_NAME, amCmd); Runtime.getRuntime().exec(amCmd); statusCode = 0; // OK } else { Log.i(LOG_FILE_NAME, "Cannot rename the update file!"); statusCode = 7; // WRITE_ERROR } } catch (Exception e) { Log.i(LOG_FILE_NAME, "error launching installer to update", e); } // Update the status file String status = statusCode == 0 ? "succeeded\n" : "failed: " + statusCode + "\n"; OutputStream outStream; try { byte[] buf = status.getBytes("UTF-8"); outStream = new FileOutputStream(statusFile); outStream.write(buf, 0, buf.length); outStream.close(); } catch (Exception e) { Log.i(LOG_FILE_NAME, "error writing status file", e); } if (statusCode == 0) System.exit(0); }
@Override public void onPause() { Log.i(LOG_FILE_NAME, "pause"); GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_PAUSING)); // The user is navigating away from this activity, but nothing // has come to the foreground yet; for Gecko, we may want to // stop repainting, for example. // Whatever we do here should be fast, because we're blocking // the next activity from showing up until we finish. // onPause will be followed by either onResume or onStop. super.onPause(); unregisterReceiver(mConnectivityReceiver); GeckoNetworkManager.getInstance().stop(); GeckoScreenOrientationListener.getInstance().stop(); }
@Override public void onStop() { Log.i(LOG_FILE_NAME, "stop"); // We're about to be stopped, potentially in preparation for // being destroyed. We're killable after this point -- as I // understand it, in extreme cases the process can be terminated // without going through onDestroy. // // We might also get an onRestart after this; not sure what // that would mean for Gecko if we were to kill it here. // Instead, what we should do here is save prefs, session, // etc., and generally mark the profile as 'clean', and then // dirty it again if we get an onResume. GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_STOPPING)); super.onStop(); GeckoAppShell.putChildInBackground(); }
@Override public void onDestroy() { Log.i(LOG_FILE_NAME, "destroy"); // Tell Gecko to shutting down; we'll end up calling System.exit() // in onXreExit. if (isFinishing()) GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_SHUTDOWN)); if (SmsManager.getInstance() != null) { SmsManager.getInstance().stop(); if (isFinishing()) SmsManager.getInstance().shutdown(); } GeckoNetworkManager.getInstance().stop(); GeckoScreenOrientationListener.getInstance().stop(); super.onDestroy(); unregisterReceiver(mBatteryReceiver); }
@Override public void onComplete(String response, Object state) { try { Log.i(TAG, response); json = Util.parseJson(response); // photos are in the form of a json array child = json.getJSONArray("data"); int total = child.length(); // contains links to photos links = new ArrayList<String>(total); // adds link to each photo to our list after replacing the "https" from url // DownloadManager does not support https in gingerbread for (int i = 0; i < total; i++) { photo_json = child.getJSONObject(i); if (dl_high_res_pics) { JSONArray image_set = photo_json.getJSONArray("images"); // highest resolution picture has the index zero in the images jsonarray JSONObject highest_res_pic = image_set.getJSONObject(0); String http_replaced = highest_res_pic.getString("source").replaceFirst("https", "http"); links.add(i, http_replaced); } else { // source property of the json object points to the photo's link String http_replaced = photo_json.getString("source").replaceFirst("https", "http"); links.add(i, http_replaced); } } download_photos.this.runOnUiThread( new Runnable() { public void run() { // mytask = new DownloadImageTask(); // mytask.execute(links); // start downloading using asynctask // new DownloadImageTask().execute(links); // downloadThread.setPath(path); // downloadThread.setWholeTasks(links.size()); if (resume_file.exists()) { initial_value = readProgress()[0]; final_value = links.size(); // case if the task is already completed if (initial_value == final_value) { completed = true; resume_pause.setVisibility(View.GONE); progress_download.setMax(final_value); progress_download.setProgress(0); // bug in progress bar progress_download.setProgress(initial_value); progress_text.setText("Completed."); mtext.setText( getText(R.string.download_textview_message_1) + " " + path.toString() + ". "); } // case if some of the photos are already downloaded else { progress_download.setMax(links.size()); // progress_download.setProgress(0); //bug in progress bar progress_download.setProgress(initial_value); // N.B if i= initial_value -1, then one image will be downloaded again. so to // save cost we start with i = initial_value for (int i = initial_value; i < links.size(); i++) { mtext.setText( getText(R.string.download_textview_message_1) + " " + path.toString() + ". "); // downloadThread.setRunningTask(i + 1); downloadThread.enqueueDownload( new DownloadTask( links.get(i), path, i + 1, final_value, download_photos.this)); } } } // case if the task is entirely new task else { for (int i = 0; i < links.size(); i++) { mtext.setText( getText(R.string.download_textview_message_1) + " " + path.toString() + ". "); // downloadThread.setRunningTask(i + 1); downloadThread.enqueueDownload( new DownloadTask( links.get(i), path, i + 1, links.size(), download_photos.this)); } } } }); } catch (JSONException ex) { Log.e(TAG, "JSONEXception : " + ex.getMessage()); } }
public void run() { Log.i(getClass().getSimpleName(), "Starting thread (run method started)"); boolean gameOverTriggered = false; long currentFrameIndex = 0; long currentFrameTimesAccumulated = 0; long lastLoopStartTime = System.currentTimeMillis(); // Debug.startMethodTracing( "escapePitTrace" ); // gameResult.status = GameResultStatus.RUNNING; loadFirstLevel(); if (orderedSubSystems == null) throw new IllegalStateException( "Cannot start a MainRunThread until you've loaded all SubSystems; try calling loadAllCoreSubSystems() first"); /** * ********************************************************************* START OF MAIN BODY OF * RUN LOOP ********************************************************************** */ while (myThread != null) { long loopStartTime = System.currentTimeMillis(); long lastFrameTime = loopStartTime - lastLoopStartTime; currentFrameTimesAccumulated += lastFrameTime; Canvas c = surfaceView.getHolder().lockCanvas(null); try { /** * Critical: lots of things in rendering depend on the size / shape of the Canvas; => we * must make sure the renderingSystem has the latest, current, correct Canvas before we do * anything else */ renderingSystem.canvas = c; for (SubSystem system : orderedSubSystems) { system.processOneGameTick(lastFrameTime); } synchronized (surfaceView.getHolder()) { renderingSystem.drawBackground(); renderingSystem.processOneGameTick(lastFrameTime); } Thread.sleep(5); } catch (GameOverError goe) { Log.i(getClass().getSimpleName(), "GameOver; killing thread"); myThread = null; Log.i(getClass().getSimpleName(), "GameOver; locking Entity System"); es.freeze(); gameOverTriggered = true; } catch (Throwable t) { Log.e( getClass().getSimpleName(), "Inside main draw loop, a major exception, killing draw thread:" + t); t.printStackTrace(); myThread = null; } finally { // ANDROID EXAMPLE CODE COMMENT: // do this in a finally so that if an exception is thrown // during the above, we don't leave the Surface in an // inconsistent state if (c != null) { surfaceView.getHolder().unlockCanvasAndPost(c); } currentFrameIndex++; lastLoopStartTime = loopStartTime; int frameTimesPerSample = 25; if (currentFrameIndex % frameTimesPerSample == 0) { // DEBUG: Log.i( getClass().getSimpleName(), "Averaged frame rate = " + // frameTimesPerSample * 1000 / currentFrameTimesAccumulated + " fps" ); currentFrameTimesAccumulated = 0; } } } // Debug.stopMethodTracing(); if (gameOverTriggered) { /** * Another bad design decision from the Android authors? This is not a great way to manage * inter-Activity communication (is there a better way?) */ Intent i = parentActivity.getIntent(); parentActivity.setResult(Activity.RESULT_OK, i); parentActivity.finish(); } Log.i( getClass().getSimpleName(), "Thread-stop COMPLETE: (run method expired; mythread was set to null)"); }
@Override public void onBackPressed() { if (BuildConfig.DEBUG) { Log.i("[" + TAG + "]", "onBackPressed() : Clicked"); } }
public void nextLevel() { boolean loaded = false; final GameBoard boardView = (GameBoard) this.findViewById(R.id.gameBoard); this.level++; AssetManager am = getResources().getAssets(); try { List<String> allTutoLevels = new LinkedList<String>(Arrays.asList(am.list("levels/tutorial"))); // if(addMsg){ // allTutoLevels.addAll(Arrays.asList(am.list("msg"))); // } Log.d(TAG, allTutoLevels.toString()); for (String name : allTutoLevels) { if (name.startsWith(this.level + ".")) { BufferedReader br = new BufferedReader(new InputStreamReader(am.open("levels/tutorial/" + name))); String line; String levelJSON = ""; while ((line = br.readLine()) != null) { levelJSON += line + "\n"; } br.close(); game.initGame( levelJSON, boardView.getMeasuredWidth() / 60, boardView.getMeasuredHeight() / 60); loaded = true; } } } catch (IOException e) { e.printStackTrace(); } if (!loaded) { Random r = new Random(); List<String> allLevels = new ArrayList<>(); try { allLevels = Arrays.asList(am.list("levels")); } catch (IOException e) { } if (r.nextBoolean() && !allLevels.isEmpty() && allLevels.size() != allDoneLevels.size()) { try { int nLevel; do { nLevel = r.nextInt(allLevels.size()); } while (allDoneLevels.contains(allLevels.get(nLevel))); String name = allLevels.get(nLevel); BufferedReader br = new BufferedReader(new InputStreamReader(am.open("levels/" + name))); String line; String levelJSON = ""; while ((line = br.readLine()) != null) { levelJSON += line + "\n"; } br.close(); allDoneLevels.add(name); game.initGame( levelJSON, boardView.getMeasuredWidth() / 60, boardView.getMeasuredHeight() / 60); } catch (IOException e) { this.game.initGame( level, boardView.getMeasuredWidth() / 60, boardView.getMeasuredHeight() / 60); } } else { this.game.initGame( level, boardView.getMeasuredWidth() / 60, boardView.getMeasuredHeight() / 60); } } // am.close(); boardView.setGame(this.game); boardView.invalidate(); boardView.getHowdyShadeView().invalidate(); Toast.makeText(this, this.level + "", Toast.LENGTH_SHORT).show(); Log.i( TAG, "Max tiles : " + (boardView.getMeasuredWidth() / 60) * (boardView.getMeasuredHeight() / 60)); }
/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { mAppContext = this; mMainHandler = new Handler(); if (!sTryCatchAttached) { sTryCatchAttached = true; mMainHandler.post( new Runnable() { public void run() { try { Looper.loop(); } catch (Exception e) { Log.e(LOG_FILE_NAME, "top level exception", e); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); pw.flush(); GeckoAppShell.reportJavaCrash(sw.toString()); } // resetting this is kinda pointless, but oh well sTryCatchAttached = false; } }); } SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE); String localeCode = settings.getString(getPackageName() + ".locale", ""); if (localeCode != null && localeCode.length() > 0) GeckoAppShell.setSelectedLocale(localeCode); Log.i(LOG_FILE_NAME, "create"); super.onCreate(savedInstanceState); if (sGREDir == null) sGREDir = new File(this.getApplicationInfo().dataDir); getWindow() .setFlags( mFullscreen ? WindowManager.LayoutParams.FLAG_FULLSCREEN : 0, WindowManager.LayoutParams.FLAG_FULLSCREEN); if (cameraView == null) { cameraView = new SurfaceView(this); cameraView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } if (surfaceView == null) surfaceView = new GeckoSurfaceView(this); else mainLayout.removeAllViews(); mainLayout = new AbsoluteLayout(this); mainLayout.addView( surfaceView, new AbsoluteLayout.LayoutParams( AbsoluteLayout.LayoutParams.MATCH_PARENT, // level 8 AbsoluteLayout.LayoutParams.MATCH_PARENT, 0, 0)); setContentView( mainLayout, new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT)); mConnectivityFilter = new IntentFilter(); mConnectivityFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mConnectivityReceiver = new GeckoConnectivityReceiver(); IntentFilter batteryFilter = new IntentFilter(); batteryFilter.addAction(Intent.ACTION_BATTERY_CHANGED); mBatteryReceiver = new GeckoBatteryManager(); registerReceiver(mBatteryReceiver, batteryFilter); if (SmsManager.getInstance() != null) { SmsManager.getInstance().start(); } GeckoNetworkManager.getInstance().init(); if (!checkAndSetLaunchState(LaunchState.PreLaunch, LaunchState.Launching)) return; checkAndLaunchUpdate(); mLibLoadThread = new Thread( new Runnable() { public void run() { // At some point while loading the gecko libs our default locale gets set // so just save it to locale here and reset it as default after the join Locale locale = Locale.getDefault(); GeckoAppShell.loadGeckoLibs(getApplication().getPackageResourcePath()); Locale.setDefault(locale); Resources res = getBaseContext().getResources(); Configuration config = res.getConfiguration(); config.locale = locale; res.updateConfiguration(config, res.getDisplayMetrics()); } }); mLibLoadThread.start(); }
@Override public void onRestart() { Log.i(LOG_FILE_NAME, "restart"); GeckoAppShell.putChildInForeground(); super.onRestart(); }
@Override public void onConfigurationChanged(android.content.res.Configuration newConfig) { Log.i(LOG_FILE_NAME, "configuration changed"); // nothing, just ignore super.onConfigurationChanged(newConfig); }
@Override public void onStart() { Log.i(LOG_FILE_NAME, "start"); GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_START)); super.onStart(); }