// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.favicon;
import android.graphics.Bitmap;
import android.util.LruCache;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.browser.profiles.Profile;
/**
* A Java API for using the C++ LargeIconService.
*
* An instance of this class must be created, used, and destroyed on the same thread.
*/
public class LargeIconBridge {
private static final int CACHE_ENTRY_MIN_SIZE_BYTES = 1024;
private long mNativeLargeIconBridge;
private Profile mProfile;
private LruCache<String, CachedFavicon> mFaviconCache;
private static class CachedFavicon {
public Bitmap icon;
public int fallbackColor;
public boolean isFallbackColorDefault;
CachedFavicon(Bitmap newIcon, int newFallbackColor, boolean newIsFallbackColorDefault) {
icon = newIcon;
fallbackColor = newFallbackColor;
isFallbackColorDefault = newIsFallbackColorDefault;
}
}
/**
* Callback for use with GetLargeIconForUrl().
*/
public interface LargeIconCallback {
/**
* Called when the icon or fallback color is available.
*
* @param icon The icon, or null if none is available.
* @param fallbackColor The fallback color to use if icon is null.
*/
@CalledByNative("LargeIconCallback")
void onLargeIconAvailable(Bitmap icon, int fallbackColor, boolean isFallbackColorDefault);
}
/**
* Initializes the C++ side of this class.
* @param profile Profile to use when fetching icons.
*/
public LargeIconBridge(Profile profile) {
mNativeLargeIconBridge = nativeInit();
mProfile = profile;
}
/**
* Create an internal cache.
* @param cacheSizeBytes The maximum size of the cache in bytes. Must be greater than 0. Note
* that this will be an approximate as there is no easy way to measure
* the precise size in Java.
*/
public void createCache(int cacheSizeBytes) {
assert cacheSizeBytes > 0;
mFaviconCache = new LruCache<String, CachedFavicon>(cacheSizeBytes) {
@Override
protected int sizeOf(String key, CachedFavicon favicon) {
int iconBitmapSize = favicon.icon == null ? 0 : favicon.icon.getByteCount();
return Math.max(CACHE_ENTRY_MIN_SIZE_BYTES, iconBitmapSize);
}
};
}
/**
* Deletes the C++ side of this class. This must be called when this object is no longer needed.
*/
public void destroy() {
assert mNativeLargeIconBridge != 0;
nativeDestroy(mNativeLargeIconBridge);
mNativeLargeIconBridge = 0;
}
/**
* Given a URL, returns a large icon for that URL if one is available (e.g. a favicon or
* touch icon). If none is available, a fallback color is returned, based on the dominant color
* of any small icons for the URL, or a default gray if no small icons are available. The icon
* and fallback color are returned synchronously(when it's from cache) or asynchronously to the
* given callback.
*
* @param pageUrl The URL of the page whose icon will be fetched.
* @param desiredSizePx The desired size of the icon in pixels.
* @param callback The method to call asynchronously when the result is available. This callback
* will not be called if this method returns false.
* @return True if a callback should be expected.
*/
public boolean getLargeIconForUrl(final String pageUrl, int desiredSizePx,
final LargeIconCallback callback) {
assert mNativeLargeIconBridge != 0;
assert callback != null;
if (mFaviconCache == null) {
return nativeGetLargeIconForURL(mNativeLargeIconBridge, mProfile, pageUrl,
desiredSizePx, callback);
} else {
CachedFavicon cached = mFaviconCache.get(pageUrl);
if (cached != null) {
callback.onLargeIconAvailable(
cached.icon, cached.fallbackColor, cached.isFallbackColorDefault);
return true;
}
LargeIconCallback callbackWrapper = new LargeIconCallback() {
@Override
public void onLargeIconAvailable(
Bitmap icon, int fallbackColor, boolean isFallbackColorDefault) {
mFaviconCache.put(pageUrl,
new CachedFavicon(icon, fallbackColor, isFallbackColorDefault));
callback.onLargeIconAvailable(icon, fallbackColor, isFallbackColorDefault);
}
};
return nativeGetLargeIconForURL(mNativeLargeIconBridge, mProfile, pageUrl,
desiredSizePx, callbackWrapper);
}
}
private static native long nativeInit();
private static native void nativeDestroy(long nativeLargeIconBridge);
private static native boolean nativeGetLargeIconForURL(long nativeLargeIconBridge,
Profile profile, String pageUrl, int desiredSizePx, LargeIconCallback callback);
}