Bug 932335 - Part 1: differentiate between unprivileged (http(s) URLs) and privileged URLs r=nalexander
Privileged URLs can include chrome://, jar://, ..., etc.
MozReview-Commit-ID: 3lFR7djRGAH
--- a/mobile/android/base/java/org/mozilla/gecko/Tab.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tab.java
@@ -456,18 +456,26 @@ public class Tab {
Favicons.cancelFaviconLoad(mFaviconLoadId);
mFaviconUrl = newFavicon.faviconUrl;
} else {
// Otherwise, fallback to the default Favicon.
mFaviconUrl = null;
}
+ final Favicons.LoadType loadType;
+ if (mSiteIdentity.getSecurityMode() == SiteIdentity.SecurityMode.CHROMEUI) {
+ loadType = Favicons.LoadType.PRIVILEGED;
+ } else {
+ loadType = Favicons.LoadType.UNPRIVILEGED;
+ }
+
int flags = (isPrivate() || mErrorType != ErrorType.NONE) ? 0 : LoadFaviconTask.FLAG_PERSIST;
- mFaviconLoadId = Favicons.getSizedFavicon(mAppContext, mUrl, mFaviconUrl, Favicons.browserToolbarFaviconSize, flags,
+ mFaviconLoadId = Favicons.getSizedFavicon(mAppContext, mUrl, mFaviconUrl,
+ loadType, Favicons.browserToolbarFaviconSize, flags,
new OnFaviconLoadedListener() {
@Override
public void onFaviconLoaded(String pageUrl, String faviconURL, Bitmap favicon) {
// The tab might be pointing to another URL by the time the
// favicon is finally loaded, in which case we simply ignore it.
if (!pageUrl.equals(mUrl)) {
return;
}
--- a/mobile/android/base/java/org/mozilla/gecko/favicons/Favicons.java
+++ b/mobile/android/base/java/org/mozilla/gecko/favicons/Favicons.java
@@ -38,16 +38,21 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
public class Favicons {
private static final String LOGTAG = "GeckoFavicons";
+ public enum LoadType {
+ PRIVILEGED,
+ UNPRIVILEGED
+ }
+
// A magic URL representing the app's own favicon, used for about: pages.
private static final String BUILT_IN_FAVICON_URL = "about:favicon";
// A magic URL representing the app's search favicon, used for about:home.
private static final String BUILT_IN_SEARCH_URL = "about:search";
// Size of the favicon bitmap cache, in bytes (Counting payload only).
public static final int FAVICON_CACHE_SIZE_BYTES = 512 * 1024;
@@ -209,31 +214,39 @@ public class Favicons {
* @param faviconURL URL of the Favicon to be downloaded, if known. If none provided, an educated
* guess is made by the system.
* @param targetSize Target size of the returned Favicon
* @param listener Listener to call with the result of the load operation, if the result is not
* immediately available.
* @return The id of the asynchronous task created, NOT_LOADING if none is created, or
* LOADED if the value could be dispatched on the current thread.
*/
- public static int getSizedFavicon(Context context, String pageURL, String faviconURL, int targetSize, int flags, OnFaviconLoadedListener listener) {
+ public static int getSizedFavicon(Context context, String pageURL, String faviconURL,
+ LoadType loadType, int targetSize, int flags, OnFaviconLoadedListener listener) {
// Do we know the favicon URL for this page already?
String cacheURL = faviconURL;
if (cacheURL == null) {
cacheURL = pageURLMappings.get(pageURL);
}
// If there's no favicon URL given, try and hit the cache with the default one.
if (cacheURL == null) {
cacheURL = guessDefaultFaviconURL(pageURL);
}
- // If it's something we can't even figure out a default URL for, just give up.
if (cacheURL == null) {
+ // If it's something we can't even figure out a default URL for, just give up.
return dispatchResult(pageURL, null, defaultFavicon, listener);
+ } else if (loadType != LoadType.PRIVILEGED &&
+ !(cacheURL.startsWith("http://") || cacheURL.startsWith("https://"))) {
+ // Don't load internal / other favicons for non-privileged pages. This is only relevant
+ // for getSizedFavicon since this is the only method that allows using a specific favicon
+ // URL. All other methods operate via the cache, icons will only end up in the cache
+ // if we load them via getSizedFavicon in the first place.
+ return NOT_LOADING;
}
Bitmap cachedIcon = getSizedFaviconFromCache(cacheURL, targetSize);
if (cachedIcon != null) {
return dispatchResult(pageURL, cacheURL, cachedIcon, listener);
}
// Check if favicon has failed.
@@ -623,16 +636,23 @@ public class Favicons {
final Map<String, Object> row = metadata.get(url);
String touchIconURL = null;
if (row != null) {
touchIconURL = (String) row.get(URLMetadataTable.TOUCH_ICON_COLUMN);
}
+ if (touchIconURL != null &&
+ !(touchIconURL.startsWith("http://") || touchIconURL.startsWith("https://"))) {
+ // We definitely don't want to load internal icons for homescreen shortcuts. See
+ // our use of LoadType.PRIVILEGED above for where allow non http(s) icons
+ touchIconURL = null;
+ }
+
// Retrieve the icon while bypassing the cache. Homescreen icon creation is a one-off event, hence it isn't
// useful to cache these icons. (Android takes care of storing homescreen icons after a shortcut
// has been created.)
// The cache is also (currently) limited to 32dp, hence we explicitly need to avoid accessing those icons.
// If touchIconURL is null, then Favicons falls back to finding the best possible favicon for
// the site URI, hence we can use this call even when there is no touchIcon defined.
getPreferredSizeFaviconForPage(context, url, touchIconURL, onFaviconLoadedListener);
}
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/SearchEnginePreference.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/SearchEnginePreference.java
@@ -167,17 +167,19 @@ public class SearchEnginePreference exte
// ever happen (leaving it at 0), so we fall back.
if (Favicons.largestFaviconSize == 0) {
desiredWidth = 128;
} else {
desiredWidth = Favicons.largestFaviconSize;
}
}
- Favicons.getSizedFavicon(getContext(), mIdentifier, iconURI, desiredWidth, 0,
+ Favicons.getSizedFavicon(getContext(), mIdentifier, iconURI,
+ Favicons.LoadType.PRIVILEGED, // We have an internal store of search engine icons, hence we're always loading PRIVILEGED icons here
+ desiredWidth, 0,
new OnFaviconLoadedListener() {
@Override
public void onFaviconLoaded(String url, String faviconURL, Bitmap favicon) {
synchronized (bitmapLock) {
mIconBitmap = favicon;
if (mFaviconView != null) {
mFaviconView.updateAndScaleImage(mIconBitmap, getTitle().toString());