--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -692,21 +692,21 @@ public class GeckoAppShell
}
static void scheduleRestart() {
Log.i("GeckoAppJava", "scheduling restart");
gRestartScheduled = true;
}
// "Installs" an application by creating a shortcut
static void createShortcut(String aTitle, String aURI, String aIconData, String aType) {
- Log.w("GeckoAppJava", "createShortcut for " + aURI + " [" + aTitle + "]");
+ Log.w("GeckoAppJava", "createShortcut for " + aURI + " [" + aTitle + "] > " + aType);
// the intent to be launched by the shortcut
Intent shortcutIntent = new Intent();
- if (aType == "webapp") {
+ if (aType.equalsIgnoreCase("webapp")) {
shortcutIntent.setAction("org.mozilla.gecko.WEBAPP");
shortcutIntent.putExtra("args", "--webapp=" + aURI);
} else {
shortcutIntent.setAction("org.mozilla.gecko.BOOKMARK");
shortcutIntent.putExtra("args", "--url=" + aURI);
}
shortcutIntent.setClassName(GeckoApp.mAppContext,
GeckoApp.mAppContext.getPackageName() + ".App");
--- a/embedding/android/LauncherShortcuts.java.in
+++ b/embedding/android/LauncherShortcuts.java.in
@@ -36,16 +36,19 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#filter substitution
package @ANDROID_PACKAGE_NAME@;
import java.io.*;
+import java.util.*;
+
+import org.json.*;
import org.mozilla.gecko.*;
import android.os.*;
import android.content.*;
import android.app.*;
import android.text.*;
import android.util.*;
@@ -53,132 +56,177 @@ import android.widget.*;
import android.database.sqlite.*;
import android.database.*;
import android.view.*;
import android.net.Uri;
import android.graphics.*;
public class LauncherShortcuts extends ListActivity {
- public static final String CREATE_SHORTCUT = "org.mozilla.gecko.CREATE_SHORTCUT";
- public class LauncherCursorAdapter extends SimpleCursorAdapter {
- private Cursor _cursor;
- private Context _context;
-
- public LauncherCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
- // Using the older, deprecated constructor so we can work on API < 11
- super(context, layout, c, from, to);
- _cursor = c;
- _context = context;
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- ImageView imageView = (ImageView) view.findViewById(R.id.favicon);
-
- String favicon = cursor.getString(3);
- byte[] raw = Base64.decode(favicon.substring(22), Base64.DEFAULT);
- Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(raw, 0, raw.length), 48, 48, true);
- imageView.setImageBitmap(bitmap);
-
- super.bindView(view, context, cursor);
- }
- }
-
- private Cursor getCursor(Context context) {
- File home = new File(context.getFilesDir(), "mozilla");
- if (!home.exists())
- return null;
-
- File profile = null;
- String[] files = home.list();
- for (int i = 0; i < files.length; i++) {
- if (files[i].endsWith(".default")) {
- profile = new File(home, files[i]);
- break;
- }
- }
-
- if (profile == null)
- return null;
-
- File webapps = new File(profile, "webapps.sqlite");
- if (!webapps.exists())
- return null;
-
- Log.i("LauncherShortcuts", "Opening: " + webapps.getPath());
- mDb = SQLiteDatabase.openDatabase(webapps.getPath(), null, SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
- return mDb.rawQuery("SELECT rowid as _id, title, uri, icon FROM webapps", null);
- }
-
- private Cursor mCursor;
- private SQLiteDatabase mDb;
+ private ArrayList <HashMap<String, String>> mWebappsList;
+ private File mWebappsFolder;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.launch_app_list);
final Intent intent = getIntent();
final String action = intent.getAction();
if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
- mCursor = getCursor(this);
- if (mCursor != null) {
- // After selecting an item, the empty view can flash on screen. Clear
- // the text so we don't see it.
- TextView emptyText = (TextView)findViewById(android.R.id.empty);
- emptyText.setText("");
-
- // Load the list using a custom adapter so we can create the bitmaps
- ListAdapter adapter = new LauncherCursorAdapter(
- this,
- R.layout.launch_app_listitem,
- mCursor,
- new String[] {"title"},
- new int[] {R.id.title}
- );
- setListAdapter(adapter);
- }
+ // Doing it as a background task, as it involves file access
+ new FetchWebApps().execute();
}
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
- mCursor.moveToPosition(position);
-
+ HashMap<String, String> map = mWebappsList.get((int) id);
+
+ String uri = map.get("uri").toString();
+ String title = map.get("title").toString();
+ String appKey = map.get("appKey").toString();
+ String favicon = map.get("favicon").toString();
+
+ File manifestFile = new File(mWebappsFolder, appKey + "/manifest.json");
+
+ // Parse the contents into a string
+ String manifestJson = new String();
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(manifestFile));
+ String line = new String();
+
+ while ((line = in.readLine()) != null) {
+ manifestJson += line;
+ }
+ } catch (IOException e) { }
+
+ try {
+ JSONObject manifest = (JSONObject) new JSONTokener(manifestJson).nextValue();
+ uri += manifest.getString("launch_path");
+ } catch (JSONException e) { }
+
Intent shortcutintent = new Intent("org.mozilla.gecko.WEBAPP");
shortcutintent.setClass(this, App.class);
- shortcutintent.putExtra("args", "--webapp=" + mCursor.getString(2));
+ shortcutintent.putExtra("args", "--webapp=" + uri);
Intent intent = new Intent();
- intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, mCursor.getString(1));
+ intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutintent);
- String favicon = mCursor.getString(3);
- byte[] raw = Base64.decode(favicon.substring(22), Base64.DEFAULT);
-
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int size;
switch (dm.densityDpi) {
case DisplayMetrics.DENSITY_MEDIUM:
size = 48;
break;
case DisplayMetrics.DENSITY_HIGH:
size = 72;
break;
default:
size = 72;
}
- Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(raw, 0, raw.length), size, size, true);
+ Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(favicon), size, size, true);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
// Now, return the result to the launcher
setResult(RESULT_OK, intent);
- mDb.close();
- mCursor.close();
finish();
}
+
+ private class FetchWebApps extends AsyncTask<Void, Void, Void> {
+
+ @Override
+ protected Void doInBackground(Void... unused) {
+ mWebappsList = null;
+
+ Context context = getApplicationContext();
+
+ File home = new File(context.getFilesDir(), "mozilla");
+ if (!home.exists())
+ home = new File(context.getExternalFilesDir(null).getPath(), "mozilla");
+
+ if (!home.exists())
+ return null;
+
+ File profile = null;
+ String[] files = home.list();
+ for (String file : files) {
+ if (file.endsWith(".default")) {
+ profile = new File(home, file);
+ break;
+ }
+ }
+
+ if (profile == null)
+ return null;
+
+ // Save the folder path to be used during click event
+ mWebappsFolder = new File(profile, "webapps");
+ if (!mWebappsFolder.exists())
+ return null;
+
+ File webapps = new File(mWebappsFolder, "webapps.json");
+ if (!webapps.exists())
+ return null;
+
+ // Parse the contents into a string
+ String webappsJson = new String();
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(webapps));
+ String line = new String();
+
+ while ((line = in.readLine()) != null) {
+ webappsJson += line;
+ }
+ } catch (IOException e) { }
+
+ if (webappsJson.length() == 0)
+ return null;
+
+ mWebappsList = new ArrayList<HashMap<String, String>>();
+
+ try {
+ JSONObject webApps = (JSONObject) new JSONTokener(webappsJson).nextValue();
+
+ Iterator<Object> appKeys = webApps.keys();
+ HashMap<String, String> map;
+
+ while (appKeys.hasNext()) {
+ String appKey = appKeys.next().toString();
+ JSONObject app = webApps.getJSONObject(appKey);
+
+ map = new HashMap<String, String>();
+ map.put("appKey", appKey);
+ map.put("favicon", mWebappsFolder.getPath() + "/" + appKey + "/icon.png");
+ map.put("title", app.getString("title"));
+ map.put("uri", app.getString("appURI"));
+
+ mWebappsList.add(map);
+ }
+
+ } catch (JSONException e) {}
+
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void unused) {
+ if (mWebappsList != null) {
+ TextView emptyText = (TextView)findViewById(android.R.id.empty);
+ emptyText.setText("");
+
+ setListAdapter(new SimpleAdapter(
+ LauncherShortcuts.this,
+ mWebappsList,
+ R.layout.launch_app_listitem,
+ new String[] { "favicon", "title" },
+ new int[] { R.id.favicon, R.id.title }
+ ));
+ }
+ }
+ }
}