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());
      }
    }
  }
  private void deleteLocation(LocationInfo info) {
    if (NavigineApp.Navigation == null) return;

    if (info != null) {
      try {
        (new File(info.archiveFile)).delete();
        info.localVersion = -1;
        info.localModified = false;

        String locationDir = LocationLoader.getLocationDir(mContext, info.title);
        File dir = new File(locationDir);
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; ++i) files[i].delete();
        dir.delete();

        String mapFile = NavigineApp.Settings.getString("map_file", "");
        if (mapFile.equals(info.archiveFile)) {
          NavigineApp.Navigation.loadArchive(null);
          SharedPreferences.Editor editor = NavigineApp.Settings.edit();
          editor.putString("map_file", "");
          editor.commit();
        }

        mAdapter.updateList();
      } catch (Throwable e) {
        Log.e(TAG, Log.getStackTraceString(e));
      }
    }
  }
 private void parseMapsXml() {
   try {
     String fileName = LocationLoader.getLocationDir(NavigineApp.AppContext, null) + "/maps.xml";
     List<LocationInfo> infoList = Parser.parseMapsXml(NavigineApp.AppContext, fileName);
     mInfoList = new ArrayList<LocationInfo>();
     if (infoList != null) mInfoList = infoList;
     mAdapter.updateList();
     new File(fileName).delete();
   } catch (Throwable e) {
     Log.e(TAG, Log.getStackTraceString(e));
   }
 }
 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);
    }
  }
  private Bitmap makeProperBitmap(final Bitmap aBitmap, final int aWidth, final int aHeight) {
    final Bitmap bitmap = Bitmap.createBitmap(aWidth, aHeight, Bitmap.Config.ARGB_8888);
    myTextureCloneCanvas.setBitmap(bitmap);
    myTextureCloneCanvas.drawBitmap(aBitmap, 0, 0, myTextureClonePaint);

    // #if DEBUG
    Log.debug("created proper texture bitmap");
    Log.debug("bitmap size: {}x{}", aBitmap.getWidth(), aBitmap.getHeight());
    Log.debug("proper size: {}x{}", aWidth, aHeight);
    // #endif

    return bitmap;
  }
 @Override
 protected Void doInBackground(Integer... params) {
   try {
     Log.v("drive", "2exit");
     if (driver.drive2Exit() == false) {
       Toast.makeText(StatePlay.this, "Fuel Empty", Toast.LENGTH_SHORT).show();
       Intent i = new Intent(StatePlay.this, AMazeActivity.class);
       startActivity(i);
     }
   } catch (Exception e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   }
   return (null);
 }
  /** Called when the activity is first created */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    Log.d(TAG, "LoaderActivity created");
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.content);

    // Instantiate custom adapter
    mAdapter = new LoaderAdapter();

    // Handle listview and assign adapter
    mListView = (ListView) findViewById(R.id.content_list_view);
    mListView.setAdapter(mAdapter);
    mListView.setVisibility(View.GONE);
    mListView.setOnItemLongClickListener(
        new AdapterView.OnItemLongClickListener() {
          public boolean onItemLongClick(AdapterView parent, View view, int position, long id) {
            selectItem(position);
            return true;
          }
        });

    mStatusLabel = (TextView) findViewById(R.id.content_status_label);
    mStatusLabel.setVisibility(View.VISIBLE);

    String userHash = NavigineApp.Settings.getString("user_hash", "");
    if (userHash.length() == 0) showUserHashDialog();
    else refreshMapList();
  }
    @Override
    protected void onDraw(Canvas canvas) {
      if (Globals.maze.state == 4) {
        Log.v("stateFinished", "activity");
        Intent i = new Intent(StatePlay.this, StateFinish.class);
        startActivity(i);
      } else {
        Globals.gw.setCanvas(canvas);
        Globals.gw.setColor(Color.DKGRAY);
        canvas.drawRect(0, 200, 400, 400, Globals.gw.paint);

        if (Globals.maze.firstpersondrawer == null) {
        } else {
          Globals.maze.start();
        }
      }
    }
 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
 public boolean onCreateOptionsMenu(Menu menu) {
   Log.d(TAG, "Create menu options");
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.loader_menu, menu);
   menu.findItem(R.id.loader_menu_refresh_map_list).setVisible(mLoader < 0);
   return true;
 }
  @Override
  public void onPause() {
    Log.d(TAG, "LoaderActivity paused");
    super.onPause();

    mTimerTask.cancel();
    mTimerTask = null;
  }
  private void updateLoader() {
    if (NavigineApp.Navigation == null) return;

    // Log.d(TAG, String.format(Locale.ENGLISH, "Update loader: %d", mLoader));

    long timeNow = DateTimeUtils.currentTimeMillis();
    if (mLoader < 0) return;

    int status = LocationLoader.checkLocationLoader(mLoader);
    if (status < 100) {
      if ((Math.abs(timeNow - mLoaderTime) > LOADER_TIMEOUT / 3 && status == 0)
          || (Math.abs(timeNow - mLoaderTime) > LOADER_TIMEOUT)) {
        mListView.setVisibility(View.GONE);
        mStatusLabel.setVisibility(View.VISIBLE);
        mStatusLabel.setText("Loading timeout!\nPlease, check your internet connection!");
        Log.d(TAG, String.format(Locale.ENGLISH, "Load stopped on timeout!"));
        LocationLoader.stopLocationLoader(mLoader);
        mLoader = -1;
      } else {
        mListView.setVisibility(View.GONE);
        mStatusLabel.setVisibility(View.VISIBLE);
        mStatusLabel.setText(String.format(Locale.ENGLISH, "Loading content (%d%%)", status));
      }
    } else {
      Log.d(TAG, String.format(Locale.ENGLISH, "Load finished with result: %d", status));
      LocationLoader.stopLocationLoader(mLoader);
      mLoader = -1;

      if (status == 100) {
        parseMapsXml();
        if (mInfoList.isEmpty()) {
          mListView.setVisibility(View.GONE);
          mStatusLabel.setVisibility(View.VISIBLE);
          mStatusLabel.setText("No locations available");
        } else {
          mListView.setVisibility(View.VISIBLE);
          mStatusLabel.setVisibility(View.GONE);
        }
      } else {
        mListView.setVisibility(View.GONE);
        mStatusLabel.setVisibility(View.VISIBLE);
        mStatusLabel.setText("Error loading!\nPlease, check your ID!");
      }
    }
  }
  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;
  }
  @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);
    }
  }
 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;
 }
  /** 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!)...");
    }
  }
  private void refreshMapList() {
    if (mLoader >= 0) return;

    String userHash = NavigineApp.Settings.getString("user_hash", "");
    if (userHash.length() == 0) return;

    // Starting new loader
    String fileName = LocationLoader.getLocationDir(NavigineApp.AppContext, null) + "/maps.xml";
    new File(fileName).delete();
    mLoader = LocationLoader.startLocationLoader(null, fileName, true);
    mLoaderTime = DateTimeUtils.currentTimeMillis();
    mInfoList = new ArrayList<LocationInfo>();
    Log.d(TAG, String.format(Locale.ENGLISH, "Location loader started: %d", mLoader));
  }
  @Override
  public void onResume() {
    Log.d(TAG, "LoaderActivity resumed");
    super.onResume();

    // Starting interface updates
    mTimerTask =
        new TimerTask() {
          @Override
          public void run() {
            mHandler.post(mRunnable);
          }
        };
    mTimer.schedule(mTimerTask, 100, 100);
  }
  @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 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 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();
  }
  private void updateLocationLoaders() {
    if (NavigineApp.Navigation == null) return;

    long timeNow = DateTimeUtils.currentTimeMillis();
    mUpdateLocationLoadersTime = timeNow;

    synchronized (mLoaderMap) {
      Iterator<Map.Entry<String, LoaderState>> iter = mLoaderMap.entrySet().iterator();
      while (iter.hasNext()) {
        Map.Entry<String, LoaderState> entry = iter.next();

        LoaderState loader = entry.getValue();
        if (loader.state < 100) {
          loader.timeLabel = timeNow;
          if (loader.type == DOWNLOAD) loader.state = LocationLoader.checkLocationLoader(loader.id);
          if (loader.type == UPLOAD) loader.state = LocationLoader.checkLocationUploader(loader.id);
        } else if (loader.state == 100) {
          String archivePath = NavigineApp.Navigation.getArchivePath();
          String locationFile =
              LocationLoader.getLocationFile(NavigineApp.AppContext, loader.location);
          if (archivePath != null && archivePath.equals(locationFile)) {
            Log.d(TAG, "Reloading archive " + archivePath);
            if (NavigineApp.Navigation.loadArchive(archivePath)) {
              SharedPreferences.Editor editor = NavigineApp.Settings.edit();
              editor.putString("map_file", archivePath);
              editor.commit();
            }
          }
          if (loader.type == DOWNLOAD) LocationLoader.stopLocationLoader(loader.id);
          if (loader.type == UPLOAD) LocationLoader.stopLocationUploader(loader.id);
          iter.remove();
        } else {
          // Load failed
          if (Math.abs(timeNow - loader.timeLabel) > 5000) {
            if (loader.type == DOWNLOAD) LocationLoader.stopLocationLoader(loader.id);
            if (loader.type == UPLOAD) LocationLoader.stopLocationUploader(loader.id);
            iter.remove();
          }
        }
      }
    }
    updateLocalVersions();
    mAdapter.updateList();
  }
  @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);
  }
  private void startUpload(int index) {
    if (NavigineApp.Navigation == null) return;

    String userHash = NavigineApp.Settings.getString("user_hash", "");
    if (userHash.length() == 0) return;

    LocationInfo info = mInfoList.get(index);
    String location = new String(info.title);
    Log.d(TAG, String.format(Locale.ENGLISH, "Start upload: %s", location));

    synchronized (mLoaderMap) {
      if (!mLoaderMap.containsKey(location)) {
        LoaderState loader = new LoaderState();
        loader.location = location;
        loader.type = UPLOAD;
        loader.id = LocationLoader.startLocationUploader(location, info.archiveFile, true);
        mLoaderMap.put(location, loader);
      }
    }
    mAdapter.updateList();
  }
 @Override
 public void onLowMemory() {
   Log.e(LOG_FILE_NAME, "low memory");
   if (checkLaunchState(LaunchState.GeckoRunning)) GeckoAppShell.onLowMemory();
   super.onLowMemory();
 }
 @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();
 }
 @Override
 public void onRestart() {
   Log.i(LOG_FILE_NAME, "restart");
   GeckoAppShell.putChildInForeground();
   super.onRestart();
 }