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));
      }
    }
  }
  @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 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));
   }
 }
 @Override
 public void onLowMemory() {
   Log.e(LOG_FILE_NAME, "low memory");
   if (checkLaunchState(LaunchState.GeckoRunning)) GeckoAppShell.onLowMemory();
   super.onLowMemory();
 }
  String[] getPluginDirectories() {

    ArrayList<String> directories = new ArrayList<String>();
    PackageManager pm = this.mAppContext.getPackageManager();
    List<ResolveInfo> plugins =
        pm.queryIntentServices(
            new Intent(PLUGIN_ACTION), PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);

    synchronized (mPackageInfoCache) {

      // clear the list of existing packageInfo objects
      mPackageInfoCache.clear();

      for (ResolveInfo info : plugins) {

        // retrieve the plugin's service information
        ServiceInfo serviceInfo = info.serviceInfo;
        if (serviceInfo == null) {
          Log.w(LOGTAG, "Ignore bad plugin");
          continue;
        }

        Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName);

        // retrieve information from the plugin's manifest
        PackageInfo pkgInfo;
        try {
          pkgInfo =
              pm.getPackageInfo(
                  serviceInfo.packageName,
                  PackageManager.GET_PERMISSIONS | PackageManager.GET_SIGNATURES);
        } catch (Exception e) {
          Log.w(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
          continue;
        }
        if (pkgInfo == null) {
          Log.w(
              LOGTAG,
              "Loading plugin: "
                  + serviceInfo.packageName
                  + ". Could not load package information.");
          continue;
        }

        /*
         * find the location of the plugin's shared library. The default
         * is to assume the app is either a user installed app or an
         * updated system app. In both of these cases the library is
         * stored in the app's data directory.
         */
        String directory = pkgInfo.applicationInfo.dataDir + "/lib";
        final int appFlags = pkgInfo.applicationInfo.flags;
        final int updatedSystemFlags =
            ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
        // preloaded system app with no user updates
        if ((appFlags & updatedSystemFlags) == ApplicationInfo.FLAG_SYSTEM) {
          directory = PLUGIN_SYSTEM_LIB + pkgInfo.packageName;
        }

        // check if the plugin has the required permissions
        String permissions[] = pkgInfo.requestedPermissions;
        if (permissions == null) {
          Log.w(
              LOGTAG,
              "Loading plugin: "
                  + serviceInfo.packageName
                  + ". Does not have required permission.");
          continue;
        }
        boolean permissionOk = false;
        for (String permit : permissions) {
          if (PLUGIN_PERMISSION.equals(permit)) {
            permissionOk = true;
            break;
          }
        }
        if (!permissionOk) {
          Log.w(
              LOGTAG,
              "Loading plugin: "
                  + serviceInfo.packageName
                  + ". Does not have required permission (2).");
          continue;
        }

        // check to ensure the plugin is properly signed
        Signature signatures[] = pkgInfo.signatures;
        if (signatures == null) {
          Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Not signed.");
          continue;
        }

        // determine the type of plugin from the manifest
        if (serviceInfo.metaData == null) {
          Log.e(LOGTAG, "The plugin '" + serviceInfo.name + "' has no type defined");
          continue;
        }

        String pluginType = serviceInfo.metaData.getString(PLUGIN_TYPE);
        if (!TYPE_NATIVE.equals(pluginType)) {
          Log.e(LOGTAG, "Unrecognized plugin type: " + pluginType);
          continue;
        }

        try {
          Class<?> cls = getPluginClass(serviceInfo.packageName, serviceInfo.name);

          // TODO implement any requirements of the plugin class here!
          boolean classFound = true;

          if (!classFound) {
            Log.e(
                LOGTAG,
                "The plugin's class' "
                    + serviceInfo.name
                    + "' does not extend the appropriate class.");
            continue;
          }

        } catch (NameNotFoundException e) {
          Log.e(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
          continue;
        } catch (ClassNotFoundException e) {
          Log.e(LOGTAG, "Can't find plugin's class: " + serviceInfo.name);
          continue;
        }

        // if all checks have passed then make the plugin available
        mPackageInfoCache.add(pkgInfo);
        directories.add(directory);
      }
    }

    return directories.toArray(new String[directories.size()]);
  }
  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)");
  }