mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 941868 - Part 2: load and cache certain preloaded favicons on launch, and remove favicon from about:home's HTML content. r=mcomella
This commit is contained in:
parent
fb5468e532
commit
3007c545eb
@ -39,5 +39,38 @@ public class AboutPages {
|
||||
}
|
||||
return url.startsWith(READER);
|
||||
}
|
||||
|
||||
private static final String[] DEFAULT_ICON_PAGES = new String[] {
|
||||
HOME,
|
||||
|
||||
ADDONS,
|
||||
CONFIG,
|
||||
DOWNLOADS,
|
||||
FIREFOX,
|
||||
HEALTHREPORT,
|
||||
UPDATER
|
||||
};
|
||||
|
||||
/**
|
||||
* Callers must not modify the returned array.
|
||||
*/
|
||||
public static String[] getDefaultIconPages() {
|
||||
return DEFAULT_ICON_PAGES;
|
||||
}
|
||||
|
||||
public static boolean isDefaultIconPage(final String url) {
|
||||
if (url == null ||
|
||||
!url.startsWith("about:")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: it'd be quicker to not compare the "about:" part every time.
|
||||
for (int i = 0; i < DEFAULT_ICON_PAGES.length; ++i) {
|
||||
if (DEFAULT_ICON_PAGES[i].equals(url)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1229,7 +1229,7 @@ abstract public class BrowserApp extends GeckoApp
|
||||
|
||||
@Override
|
||||
public void addTab() {
|
||||
Tabs.getInstance().loadUrl(AboutPages.HOME, Tabs.LOADURL_NEW_TAB);
|
||||
super.loadHomePage(Tabs.LOADURL_NEW_TAB);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1401,7 +1401,7 @@ abstract public class BrowserApp extends GeckoApp
|
||||
}
|
||||
|
||||
private void openReadingList() {
|
||||
Tabs.getInstance().loadUrl(AboutPages.HOME, Tabs.LOADURL_READING_LIST);
|
||||
super.loadHomePage(Tabs.LOADURL_READING_LIST);
|
||||
}
|
||||
|
||||
/* Favicon stuff. */
|
||||
|
@ -1354,8 +1354,8 @@ abstract public class GeckoApp
|
||||
if (url == null) {
|
||||
if (!mShouldRestore) {
|
||||
// Show about:home if we aren't restoring previous session and
|
||||
// there's no external URL
|
||||
Tab tab = Tabs.getInstance().loadUrl(AboutPages.HOME, Tabs.LOADURL_NEW_TAB);
|
||||
// there's no external URL.
|
||||
loadHomePage(Tabs.LOADURL_NEW_TAB);
|
||||
}
|
||||
} else {
|
||||
// If given an external URL, load it
|
||||
@ -1364,6 +1364,14 @@ abstract public class GeckoApp
|
||||
}
|
||||
}
|
||||
|
||||
protected Tab loadHomePage() {
|
||||
return loadHomePage(Tabs.LOADURL_NONE);
|
||||
}
|
||||
|
||||
protected Tab loadHomePage(int flags) {
|
||||
return Tabs.getInstance().loadUrl(AboutPages.HOME, flags);
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
mInitialized = true;
|
||||
|
||||
|
@ -660,8 +660,8 @@ public class Tabs implements GeckoEventListener {
|
||||
*
|
||||
* @param url URL of page to load, or search term used if searchEngine is given
|
||||
*/
|
||||
public void loadUrl(String url) {
|
||||
loadUrl(url, LOADURL_NONE);
|
||||
public Tab loadUrl(String url) {
|
||||
return loadUrl(url, LOADURL_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -731,13 +731,34 @@ public class Tabs implements GeckoEventListener {
|
||||
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Load", args.toString()));
|
||||
|
||||
if ((added != null) && !delayLoad && !background) {
|
||||
if (added == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!delayLoad && !background) {
|
||||
selectTab(added.getId());
|
||||
}
|
||||
|
||||
// TODO: surely we could just fetch *any* cached icon?
|
||||
if (AboutPages.isDefaultIconPage(url)) {
|
||||
Log.d(LOGTAG, "Setting about: tab favicon inline.");
|
||||
added.updateFavicon(getAboutPageFavicon(url));
|
||||
}
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
/**
|
||||
* These favicons are only used for the URL bar, so
|
||||
* we fetch with that size.
|
||||
*
|
||||
* This method completes on the calling thread.
|
||||
*/
|
||||
private Bitmap getAboutPageFavicon(final String url) {
|
||||
int faviconSize = Math.round(mAppContext.getResources().getDimension(R.dimen.browser_toolbar_favicon_size));
|
||||
return Favicons.getCachedFaviconForSize(url, faviconSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the url as a new tab, and mark the selected tab as its "parent".
|
||||
*
|
||||
|
@ -6,23 +6,28 @@
|
||||
package org.mozilla.gecko.favicons;
|
||||
|
||||
import org.mozilla.gecko.AboutPages;
|
||||
import org.mozilla.gecko.AppConstants;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.Tab;
|
||||
import org.mozilla.gecko.Tabs;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.favicons.cache.FaviconCache;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.GeckoJarReader;
|
||||
import org.mozilla.gecko.util.NonEvictingLruCache;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@ -32,6 +37,9 @@ import java.util.Set;
|
||||
public class Favicons {
|
||||
private static final String LOGTAG = "GeckoFavicons";
|
||||
|
||||
// A magic URL representing the app's own favicon, used for about: pages.
|
||||
private static final String BUILT_IN_FAVICON_URL = "about:favicon";
|
||||
|
||||
// Size of the favicon bitmap cache, in bytes (Counting payload only).
|
||||
public static final int FAVICON_CACHE_SIZE_BYTES = 512 * 1024;
|
||||
|
||||
@ -97,6 +105,20 @@ public class Favicons {
|
||||
return NOT_LOADING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only returns a non-null Bitmap if the entire path is cached -- the
|
||||
* page URL to favicon URL, and the favicon URL to in-memory bitmaps.
|
||||
*
|
||||
* Returns null otherwise.
|
||||
*/
|
||||
public static Bitmap getCachedFaviconForSize(final String pageURL, int targetSize) {
|
||||
final String faviconURL = sPageURLMappings.get(pageURL);
|
||||
if (faviconURL == null) {
|
||||
return null;
|
||||
}
|
||||
return getSizedFaviconFromCache(faviconURL, targetSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Favicon as close as possible to the target dimensions for the URL provided.
|
||||
* If a result is instantly available from the cache, it is returned and the listener is invoked.
|
||||
@ -113,8 +135,13 @@ public class Favicons {
|
||||
* LOADED if the value could be dispatched on the current thread.
|
||||
*/
|
||||
public static int getFaviconForSize(String pageURL, String faviconURL, int targetSize, int flags, OnFaviconLoadedListener listener) {
|
||||
// If there's no favicon URL given, try and hit the cache with the default one.
|
||||
// Do we know the favicon URL for this page already?
|
||||
String cacheURL = faviconURL;
|
||||
if (cacheURL == null) {
|
||||
cacheURL = sPageURLMappings.get(pageURL);
|
||||
}
|
||||
|
||||
// If there's no favicon URL given, try and hit the cache with the default one.
|
||||
if (cacheURL == null) {
|
||||
cacheURL = guessDefaultFaviconURL(pageURL);
|
||||
}
|
||||
@ -328,16 +355,49 @@ public class Favicons {
|
||||
* @param context A reference to the GeckoApp instance.
|
||||
*/
|
||||
public static void attachToContext(Context context) throws Exception {
|
||||
final Resources res = context.getResources();
|
||||
sContext = context;
|
||||
|
||||
// Decode the default Favicon ready for use.
|
||||
sDefaultFavicon = BitmapFactory.decodeResource(context.getResources(), R.drawable.favicon);
|
||||
sDefaultFavicon = BitmapFactory.decodeResource(res, R.drawable.favicon);
|
||||
if (sDefaultFavicon == null) {
|
||||
throw new Exception("Null default favicon was returned from the resources system!");
|
||||
}
|
||||
|
||||
sDefaultFaviconSize = context.getResources().getDimensionPixelSize(R.dimen.favicon_bg);
|
||||
sFaviconsCache = new FaviconCache(FAVICON_CACHE_SIZE_BYTES, context.getResources().getDimensionPixelSize(R.dimen.favicon_largest_interesting_size));
|
||||
sDefaultFaviconSize = res.getDimensionPixelSize(R.dimen.favicon_bg);
|
||||
sFaviconsCache = new FaviconCache(FAVICON_CACHE_SIZE_BYTES, res.getDimensionPixelSize(R.dimen.favicon_largest_interesting_size));
|
||||
|
||||
// Initialize page mappings for each of our special pages.
|
||||
for (String url : AboutPages.getDefaultIconPages()) {
|
||||
sPageURLMappings.putWithoutEviction(url, BUILT_IN_FAVICON_URL);
|
||||
}
|
||||
|
||||
// Load and cache the built-in favicon in each of its sizes.
|
||||
// TODO: don't open the zip twice!
|
||||
ArrayList<Bitmap> toInsert = new ArrayList<Bitmap>(2);
|
||||
toInsert.add(loadBrandingBitmap(context, "favicon64.png"));
|
||||
toInsert.add(loadBrandingBitmap(context, "favicon32.png"));
|
||||
putFaviconsInMemCache(BUILT_IN_FAVICON_URL, toInsert.iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a string like:
|
||||
* "jar:jar:file:///data/app/org.mozilla.firefox-1.apk!/assets/omni.ja!/chrome/chrome/content/branding/favicon64.png"
|
||||
*/
|
||||
private static String getBrandingBitmapPath(Context context, String name) {
|
||||
final String apkPath = context.getPackageResourcePath();
|
||||
return "jar:jar:" + new File(apkPath).toURI() + "!/" +
|
||||
AppConstants.OMNIJAR_NAME + "!/" +
|
||||
"chrome/chrome/content/branding/" + name;
|
||||
}
|
||||
|
||||
private static Bitmap loadBrandingBitmap(Context context, String name) {
|
||||
Bitmap b = GeckoJarReader.getBitmap(context.getResources(),
|
||||
getBrandingBitmapPath(context, name));
|
||||
if (b == null) {
|
||||
throw new IllegalStateException("Bitmap " + name + " missing from JAR!");
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,8 +115,12 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
private ShapedButton mTabs;
|
||||
private ImageButton mBack;
|
||||
private ImageButton mForward;
|
||||
private ImageButton mFavicon;
|
||||
private ImageButton mStop;
|
||||
|
||||
// To de-bounce sets.
|
||||
private Bitmap mLastFavicon;
|
||||
private ImageButton mFavicon;
|
||||
|
||||
private ImageButton mSiteSecurity;
|
||||
private PageActionLayout mPageActionLayout;
|
||||
private Animation mProgressSpinner;
|
||||
@ -428,7 +432,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
|
||||
mFavicon.setOnClickListener(faviconListener);
|
||||
mSiteSecurity.setOnClickListener(faviconListener);
|
||||
|
||||
|
||||
mStop.setOnClickListener(new Button.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@ -741,12 +745,15 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
}
|
||||
|
||||
public void setProgressVisibility(boolean visible) {
|
||||
Log.d(LOGTAG, "setProgressVisibility: " + visible);
|
||||
// The "Throbber start" and "Throbber stop" log messages in this method
|
||||
// are needed by S1/S2 tests (http://mrcote.info/phonedash/#).
|
||||
// See discussion in Bug 804457. Bug 805124 tracks paring these down.
|
||||
if (visible) {
|
||||
mFavicon.setImageResource(R.drawable.progress_spinner);
|
||||
//To stop the glitch caused by mutiple start() calls.
|
||||
mLastFavicon = null;
|
||||
|
||||
// To stop the glitch caused by multiple start() calls.
|
||||
if (!mSpinnerVisible) {
|
||||
setPageActionVisibility(true);
|
||||
mFavicon.setAnimation(mProgressSpinner);
|
||||
@ -868,15 +875,15 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
setContentDescription(title != null ? title : mTitle.getHint());
|
||||
}
|
||||
|
||||
// Sets the toolbar title according to the selected tab, obeying the mShowUrl prference.
|
||||
// Sets the toolbar title according to the selected tab, obeying the mShowUrl preference.
|
||||
private void updateTitle() {
|
||||
Tab tab = Tabs.getInstance().getSelectedTab();
|
||||
final Tab tab = Tabs.getInstance().getSelectedTab();
|
||||
// Keep the title unchanged if there's no selected tab, or if the tab is entering reader mode.
|
||||
if (tab == null || tab.isEnteringReaderMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String url = tab.getURL();
|
||||
final String url = tab.getURL();
|
||||
|
||||
if (!isEditing()) {
|
||||
mUrlEditLayout.setText(url);
|
||||
@ -923,8 +930,17 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
}
|
||||
|
||||
private void setFavicon(Bitmap image) {
|
||||
if (Tabs.getInstance().getSelectedTab().getState() == Tab.STATE_LOADING)
|
||||
Log.d(LOGTAG, "setFavicon(" + image + ")");
|
||||
if (Tabs.getInstance().getSelectedTab().getState() == Tab.STATE_LOADING) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (image == mLastFavicon) {
|
||||
Log.d(LOGTAG, "Ignoring favicon set: new favicon is identical to previous favicon.");
|
||||
return;
|
||||
}
|
||||
|
||||
mLastFavicon = image; // Cache the original so we can debounce without scaling.
|
||||
|
||||
if (image != null) {
|
||||
image = Bitmap.createScaledBitmap(image, mFaviconSize, mFaviconSize, false);
|
||||
@ -933,7 +949,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
mFavicon.setImageDrawable(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setSecurityMode(String mode) {
|
||||
int imageLevel = SiteIdentityPopup.getSecurityImageLevel(mode);
|
||||
mSiteSecurity.setImageLevel(imageLevel);
|
||||
|
@ -16,7 +16,6 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>&abouthome.title;</title>
|
||||
<link rel="icon" type="image/png" sizes="64x64" href="chrome://branding/content/favicon64.png" />
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
|
Loading…
Reference in New Issue
Block a user