зеркало из https://github.com/mozilla/gecko-dev.git
Bug 816547: Make sure the Bitmap is accessed in UI thread in LWTheme. [r=mfinkle]
--HG-- extra : rebase_source : 7f99818a2395fdc4f03b24927f706a4f81197038
This commit is contained in:
Родитель
a8e0a1a69c
Коммит
2560db822a
|
@ -18,13 +18,17 @@ import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.Shader;
|
import android.graphics.Shader;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Handler;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewParent;
|
import android.view.ViewParent;
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@ -34,15 +38,13 @@ public class LightweightTheme implements GeckoEventListener {
|
||||||
private static final String LOGTAG = "GeckoLightweightTheme";
|
private static final String LOGTAG = "GeckoLightweightTheme";
|
||||||
|
|
||||||
private Application mApplication;
|
private Application mApplication;
|
||||||
|
private Handler mHandler;
|
||||||
|
|
||||||
private Bitmap mBitmap;
|
private Bitmap mBitmap;
|
||||||
private int mColor;
|
private int mColor;
|
||||||
private boolean mIsLight;
|
private boolean mIsLight;
|
||||||
|
|
||||||
public static interface OnChangeListener {
|
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.
|
// The View should change its background/text color.
|
||||||
public void onLightweightThemeChanged();
|
public void onLightweightThemeChanged();
|
||||||
|
|
||||||
|
@ -54,8 +56,10 @@ public class LightweightTheme implements GeckoEventListener {
|
||||||
|
|
||||||
public LightweightTheme(Application application) {
|
public LightweightTheme(Application application) {
|
||||||
mApplication = application;
|
mApplication = application;
|
||||||
|
mHandler = new Handler(Looper.getMainLooper());
|
||||||
mListeners = new ArrayList<OnChangeListener>();
|
mListeners = new ArrayList<OnChangeListener>();
|
||||||
|
|
||||||
|
// unregister isn't needed as the lifetime is same as the application.
|
||||||
GeckoAppShell.getEventDispatcher().registerEventListener("LightweightTheme:Update", this);
|
GeckoAppShell.getEventDispatcher().registerEventListener("LightweightTheme:Update", this);
|
||||||
GeckoAppShell.getEventDispatcher().registerEventListener("LightweightTheme:Disable", this);
|
GeckoAppShell.getEventDispatcher().registerEventListener("LightweightTheme:Disable", this);
|
||||||
}
|
}
|
||||||
|
@ -70,76 +74,6 @@ public class LightweightTheme implements GeckoEventListener {
|
||||||
mListeners.remove(listener);
|
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
|
@Override
|
||||||
public void handleMessage(String event, JSONObject message) {
|
public void handleMessage(String event, JSONObject message) {
|
||||||
try {
|
try {
|
||||||
|
@ -149,15 +83,78 @@ public class LightweightTheme implements GeckoEventListener {
|
||||||
int mark = headerURL.indexOf('?');
|
int mark = headerURL.indexOf('?');
|
||||||
if (mark != -1)
|
if (mark != -1)
|
||||||
headerURL = headerURL.substring(0, mark);
|
headerURL = headerURL.substring(0, mark);
|
||||||
setLightweightTheme(headerURL);
|
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() {
|
||||||
|
public void run() {
|
||||||
|
setLightweightTheme(bitmap);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch(MalformedURLException e) {
|
||||||
|
} catch(IOException e) {
|
||||||
|
}
|
||||||
} else if (event.equals("LightweightTheme:Disable")) {
|
} else if (event.equals("LightweightTheme:Disable")) {
|
||||||
resetLightweightTheme();
|
mHandler.post(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
resetLightweightTheme();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(LOGTAG, "Exception handling message \"" + event + "\":", 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.
|
* A lightweight theme is enabled only if there is an active bitmap.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче