Bug 826400 - Part 3: Simplify homescreen shortcut creation, and use apple-touch-icon if available r=nalexander,jchen

This commit is contained in:
Andrzej Hunt 2015-12-29 11:49:54 -08:00
parent 048ec6274f
commit c349a42fac
7 changed files with 66 additions and 49 deletions

View File

@ -5,6 +5,7 @@
package org.mozilla.gecko;
import android.os.AsyncTask;
import org.mozilla.gecko.adjust.AdjustHelperInterface;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.AppConstants.Versions;
@ -1108,11 +1109,11 @@ public class BrowserApp extends GeckoApp
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION,
TelemetryContract.Method.DIALOG, extrasId);
String url = tab.getURL();
String title = tab.getDisplayTitle();
Bitmap favicon = tab.getFavicon();
final String url = tab.getURL();
final String title = tab.getDisplayTitle();
if (url != null && title != null) {
GeckoAppShell.createShortcut(title, url, favicon);
GeckoAppShell.createShortcut(title, url);
}
}
}
@ -1237,7 +1238,7 @@ public class BrowserApp extends GeckoApp
}
if (itemId == R.id.add_to_launcher) {
Tab tab = Tabs.getInstance().getSelectedTab();
final Tab tab = Tabs.getInstance().getSelectedTab();
if (tab == null) {
return true;
}
@ -1248,13 +1249,13 @@ public class BrowserApp extends GeckoApp
return true;
}
final OnFaviconLoadedListener listener = new GeckoAppShell.CreateShortcutFaviconLoadedListener(url, title);
Favicons.getSizedFavicon(getContext(),
url,
tab.getFaviconURL(),
Integer.MAX_VALUE,
LoadFaviconTask.FLAG_PERSIST,
listener);
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
GeckoAppShell.createShortcut(title, url);
return null;
}
}.execute();
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.CONTEXT_MENU,
getResources().getResourceEntryName(itemId));

View File

@ -23,6 +23,7 @@ import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@ -32,11 +33,14 @@ import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import android.content.ContentResolver;
import org.mozilla.gecko.annotation.JNITarget;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.db.LocalURLMetadata;
import org.mozilla.gecko.db.URLMetadataTable;
import org.mozilla.gecko.favicons.Favicons;
import org.mozilla.gecko.favicons.OnFaviconLoadedListener;
import org.mozilla.gecko.gfx.BitmapUtils;
@ -294,21 +298,6 @@ public class GeckoAppShell
public static native void onFullScreenPluginHidden(View view);
public static class CreateShortcutFaviconLoadedListener implements OnFaviconLoadedListener {
private final String title;
private final String url;
public CreateShortcutFaviconLoadedListener(final String url, final String title) {
this.url = url;
this.title = title;
}
@Override
public void onFaviconLoaded(String pageUrl, String faviconURL, Bitmap favicon) {
GeckoAppShell.createShortcut(title, url, favicon);
}
}
private static LayerView sLayerView;
public static void setLayerView(LayerView lv) {
@ -767,21 +756,41 @@ public class GeckoAppShell
// Creates a homescreen shortcut for a web page.
// This is the entry point from nsIShellService.
@WrapForJNI
static void createShortcut(final String aTitle, final String aURI, final String aIconData) {
// We have the favicon data (base64) decoded on the background thread, callback here, then
// call the other createShortcut method with the decoded favicon.
// This is slightly contrived, but makes the images available to the favicon cache.
Favicons.getSizedFavicon(getApplicationContext(), aURI, aIconData, Integer.MAX_VALUE, 0,
new OnFaviconLoadedListener() {
@Override
public void onFaviconLoaded(String url, String faviconURL, Bitmap favicon) {
createShortcut(aTitle, url, favicon);
}
}
public static void createShortcut(final String aTitle, final String aURI) {
final BrowserDB db = GeckoProfile.get(getApplicationContext()).getDB();
final ContentResolver cr = getContext().getContentResolver();
final Map<String, Map<String, Object>> metadata = db.getURLMetadata().getForURLs(cr,
Collections.singletonList(aURI),
Collections.singletonList(URLMetadataTable.TOUCH_ICON_COLUMN)
);
final Map<String, Object> row = metadata.get(aURI);
String touchIconURL = null;
if (row != null) {
touchIconURL = (String) row.get(URLMetadataTable.TOUCH_ICON_COLUMN);
}
OnFaviconLoadedListener listener = new OnFaviconLoadedListener() {
@Override
public void onFaviconLoaded(String url, String faviconURL, Bitmap favicon) {
createShortcutWithBitmap(aTitle, url, favicon);
}
};
if (touchIconURL != null) {
// We have the favicon data (base64) decoded on the background thread, callback here, then
// call the other createShortcut method with the decoded favicon.
// This is slightly contrived, but makes the images available to the favicon cache.
Favicons.getSizedFavicon(getApplicationContext(), aURI, touchIconURL, Integer.MAX_VALUE, 0, listener);
} else {
Favicons.getPreferredSizeFaviconForPage(getApplicationContext(), aURI, listener);
}
}
public static void createShortcut(final String aTitle, final String aURI, final Bitmap aBitmap) {
private static void createShortcutWithBitmap(final String aTitle, final String aURI, final Bitmap aBitmap) {
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {

View File

@ -7,6 +7,7 @@ package org.mozilla.gecko.home;
import java.util.EnumSet;
import android.os.AsyncTask;
import org.mozilla.gecko.EditBookmarkDialog;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
@ -218,7 +219,14 @@ public abstract class HomeFragment extends Fragment {
}
// Fetch an icon big enough for use as a home screen icon.
Favicons.getPreferredSizeFaviconForPage(context, info.url, new GeckoAppShell.CreateShortcutFaviconLoadedListener(info.url, info.getDisplayTitle()));
final String displayTitle = info.getDisplayTitle();
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
GeckoAppShell.createShortcut(displayTitle, info.url);
return null;
}
}.execute();
return true;
}

View File

@ -19,7 +19,7 @@ interface nsIShellService : nsISupports
*
* @param aTitle the user-friendly name of the shortcut.
* @param aURI the URI to open.
* @param aIconData a base64-encoded data: URI representation of the shortcut's icon, as accepted by the favicon decoder.
* @param aIconData obsolete and ignored, but remains for backward compatibility; pass an empty string
* @param aIntent obsolete and ignored, but remains for backward compatibility; pass an empty string
*/
void createShortcut(in AString aTitle, in AString aURI, in AString aIconData, in AString aIntent);

View File

@ -20,11 +20,11 @@ nsShellService::SwitchTask()
NS_IMETHODIMP
nsShellService::CreateShortcut(const nsAString& aTitle, const nsAString& aURI,
const nsAString& aIconData, const nsAString& aIntent)
const nsAString& aIcondata, const nsAString& aIntent)
{
if (!aTitle.Length() || !aURI.Length() || !aIconData.Length())
if (!aTitle.Length() || !aURI.Length())
return NS_ERROR_FAILURE;
widget::GeckoAppShell::CreateShortcut(aTitle, aURI, aIconData);
widget::GeckoAppShell::CreateShortcut(aTitle, aURI);
return NS_OK;
}

View File

@ -121,9 +121,9 @@ auto GeckoAppShell::CreateMessageCursorWrapper(int64_t a0, int64_t a1, mozilla::
constexpr char GeckoAppShell::CreateShortcut_t::name[];
constexpr char GeckoAppShell::CreateShortcut_t::signature[];
auto GeckoAppShell::CreateShortcut(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1, mozilla::jni::String::Param a2) -> void
auto GeckoAppShell::CreateShortcut(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> void
{
return mozilla::jni::Method<CreateShortcut_t>::Call(nullptr, nullptr, a0, a1, a2);
return mozilla::jni::Method<CreateShortcut_t>::Call(nullptr, nullptr, a0, a1);
}
constexpr char GeckoAppShell::CreateThreadCursorWrapper_t::name[];

View File

@ -359,19 +359,18 @@ public:
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
mozilla::jni::String::Param,
mozilla::jni::String::Param,
mozilla::jni::String::Param> Args;
static constexpr char name[] = "createShortcut";
static constexpr char signature[] =
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V";
"(Ljava/lang/String;Ljava/lang/String;)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
static auto CreateShortcut(mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param) -> void;
static auto CreateShortcut(mozilla::jni::String::Param, mozilla::jni::String::Param) -> void;
public:
struct CreateThreadCursorWrapper_t {