diff --git a/mobile/android/base/LightweightTheme.java b/mobile/android/base/LightweightTheme.java index 9bb1208a992..5625182f0ff 100644 --- a/mobile/android/base/LightweightTheme.java +++ b/mobile/android/base/LightweightTheme.java @@ -18,17 +18,13 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.Rect; import android.graphics.Shader; import android.os.Build; -import android.os.Looper; -import android.os.Handler; import android.util.DisplayMetrics; import android.view.Gravity; import android.view.View; import android.view.ViewParent; -import java.io.InputStream; -import java.io.IOException; -import java.net.MalformedURLException; import java.net.URL; +import java.io.InputStream; import java.util.List; import java.util.ArrayList; @@ -38,13 +34,15 @@ public class LightweightTheme implements GeckoEventListener { private static final String LOGTAG = "GeckoLightweightTheme"; private Application mApplication; - private Handler mHandler; - private Bitmap mBitmap; private int mColor; private boolean mIsLight; public static interface OnChangeListener { + // This is the View's default post. + // This is required to post the change/rest on UI thread. + public boolean post(Runnable action); + // The View should change its background/text color. public void onLightweightThemeChanged(); @@ -56,10 +54,8 @@ public class LightweightTheme implements GeckoEventListener { public LightweightTheme(Application application) { mApplication = application; - mHandler = new Handler(Looper.getMainLooper()); mListeners = new ArrayList(); - // unregister isn't needed as the lifetime is same as the application. GeckoAppShell.getEventDispatcher().registerEventListener("LightweightTheme:Update", this); GeckoAppShell.getEventDispatcher().registerEventListener("LightweightTheme:Disable", this); } @@ -74,6 +70,76 @@ public class LightweightTheme implements GeckoEventListener { mListeners.remove(listener); } + public void setLightweightTheme(String headerURL) { + try { + // Get the image and convert it to a bitmap. + URL url = new URL(headerURL); + InputStream stream = url.openStream(); + mBitmap = BitmapFactory.decodeStream(stream); + stream.close(); + + // The download could be HTTP for previews, so let's be sure we have a bitmap + if (mBitmap == null || mBitmap.getWidth() == 0 || mBitmap.getHeight() == 0) { + mBitmap = null; + return; + } + + // To find the dominant color only once, take the bottom 25% of pixels. + DisplayMetrics dm = mApplication.getResources().getDisplayMetrics(); + int maxWidth = Math.max(dm.widthPixels, dm.heightPixels); + int height = (int) (mBitmap.getHeight() * 0.25); + Bitmap cropped = Bitmap.createBitmap(mBitmap, mBitmap.getWidth() - maxWidth, + mBitmap.getHeight() - height, + maxWidth, height); + mColor = BitmapUtils.getDominantColor(cropped, false); + + double luminance = (0.2125 * ((mColor & 0x00FF0000) >> 16)) + + (0.7154 * ((mColor & 0x0000FF00) >> 8)) + + (0.0721 * (mColor &0x000000FF)); + mIsLight = (luminance > 110) ? true : false; + + notifyListeners(); + } catch(java.net.MalformedURLException e) { + mBitmap = null; + } catch(java.io.IOException e) { + mBitmap = null; + } + } + + public void resetLightweightTheme() { + if (mBitmap != null) { + // Reset the bitmap. + mBitmap = null; + + // Post the reset on the UI thread. + for (OnChangeListener listener : mListeners) { + final OnChangeListener oneListener = listener; + oneListener.post(new Runnable() { + @Override + public void run() { + oneListener.onLightweightThemeReset(); + } + }); + } + } + } + + public void notifyListeners() { + if (mBitmap == null) + return; + + // Post the change on the UI thread. + for (OnChangeListener listener : mListeners) { + final OnChangeListener oneListener = listener; + oneListener.post(new Runnable() { + @Override + public void run() { + oneListener.onLightweightThemeChanged(); + } + }); + } + } + @Override public void handleMessage(String event, JSONObject message) { try { @@ -83,80 +149,15 @@ public class LightweightTheme implements GeckoEventListener { int mark = headerURL.indexOf('?'); if (mark != -1) headerURL = headerURL.substring(0, mark); - try { - // Get the image and convert it to a bitmap. - URL url = new URL(headerURL); - InputStream stream = url.openStream(); - final Bitmap bitmap = BitmapFactory.decodeStream(stream); - stream.close(); - mHandler.post(new Runnable() { - @Override - public void run() { - setLightweightTheme(bitmap); - } - }); - } catch(MalformedURLException e) { - } catch(IOException e) { - } + setLightweightTheme(headerURL); } else if (event.equals("LightweightTheme:Disable")) { - mHandler.post(new Runnable() { - @Override - public void run() { - resetLightweightTheme(); - } - }); + resetLightweightTheme(); } } catch (Exception e) { Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e); } } - /** - * Set a new lightweight theme with the given bitmap. - * Note: This should be called on the UI thread to restrict accessing the - * bitmap to a single thread. - * - * @param bitmap The bitmap used for the lightweight theme. - */ - private void setLightweightTheme(Bitmap bitmap) { - mBitmap = bitmap; - if (mBitmap == null || mBitmap.getWidth() == 0 || mBitmap.getHeight() == 0) { - mBitmap = null; - return; - } - - // To find the dominant color only once, take the bottom 25% of pixels. - DisplayMetrics dm = mApplication.getResources().getDisplayMetrics(); - int maxWidth = Math.max(dm.widthPixels, dm.heightPixels); - int height = (int) (mBitmap.getHeight() * 0.25); - Bitmap cropped = Bitmap.createBitmap(mBitmap, mBitmap.getWidth() - maxWidth, - mBitmap.getHeight() - height, - maxWidth, height); - mColor = BitmapUtils.getDominantColor(cropped, false); - - double luminance = (0.2125 * ((mColor & 0x00FF0000) >> 16)) + - (0.7154 * ((mColor & 0x0000FF00) >> 8)) + - (0.0721 * (mColor &0x000000FF)); - mIsLight = (luminance > 110) ? true : false; - - for (OnChangeListener listener : mListeners) - listener.onLightweightThemeChanged(); - } - - /** - * Reset the lightweight theme. - * Note: This should be called on the UI thread to restrict accessing the - * bitmap to a single thread. - */ - private void resetLightweightTheme() { - if (mBitmap != null) { - // Reset the bitmap. - mBitmap = null; - - for (OnChangeListener listener : mListeners) - listener.onLightweightThemeReset(); - } - } /** * A lightweight theme is enabled only if there is an active bitmap.