Bug 1403653 - Part 1 - Refactor getDominantColor. r=nechen

We want to use the Palette library for getting a fallback accent colour for lightweight themes, however because of bug 1318667, we might have to continue using our own implementation of getDominantColor on x86 devices.

Therefore we move this into BitmapUtils, so we can have a central location from which to switch between our own and the Palette library implementation.

MozReview-Commit-ID: 52WsfZbW12x

--HG--
extra : rebase_source : b0eb60c25355d1a13418844b5684e4356225e8c3
This commit is contained in:
Jan Henning 2017-10-14 19:23:03 +02:00
parent c17ea32a4f
commit 3fe1971e3f
7 changed files with 47 additions and 47 deletions

View File

@ -229,7 +229,6 @@ dependencies {
compile "com.android.support:recyclerview-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
compile "com.android.support:design:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
compile "com.android.support:customtabs:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
compile "com.android.support:palette-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
if (mozconfig.substs.MOZ_NATIVE_DEVICES) {
compile "com.android.support:mediarouter-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"

View File

@ -7,13 +7,10 @@ package org.mozilla.gecko.icons.processing;
import android.graphics.Bitmap;
import android.support.annotation.ColorInt;
import android.support.v7.graphics.Palette;
import android.util.Log;
import org.mozilla.gecko.gfx.BitmapUtils;
import org.mozilla.gecko.icons.IconRequest;
import org.mozilla.gecko.icons.IconResponse;
import org.mozilla.gecko.util.HardwareUtils;
/**
* Processor implementation to extract the dominant color from the icon and attach it to the icon
@ -37,36 +34,8 @@ public class ColorProcessor implements Processor {
return;
}
if (HardwareUtils.isX86System()) {
// (Bug 1318667) We are running into crashes when using the palette library with
// specific icons on x86 devices. They take down the whole VM and are not recoverable.
// Unfortunately our release icon is triggering this crash. Until we can switch to a
// newer version of the support library where this does not happen, we are using our
// own slower implementation.
extractColorUsingCustomImplementation(response);
} else {
extractColorUsingPaletteSupportLibrary(response);
}
}
private void extractColorUsingPaletteSupportLibrary(final IconResponse response) {
try {
final Palette palette = Palette.from(response.getBitmap()).generate();
response.updateColor(palette.getVibrantColor(DEFAULT_COLOR) & 0x7FFFFFFF);
} catch (ArrayIndexOutOfBoundsException e) {
// We saw the palette library fail with an ArrayIndexOutOfBoundsException intermittently
// in automation. In this case lets just swallow the exception and move on without a
// color. This is a valid condition and callers should handle this gracefully (Bug 1318560).
Log.e(LOGTAG, "Palette generation failed with ArrayIndexOutOfBoundsException", e);
response.updateColor(DEFAULT_COLOR);
}
}
private void extractColorUsingCustomImplementation(final IconResponse response) {
final int dominantColor = BitmapUtils.getDominantColor(response.getBitmap());
response.updateColor(dominantColor);
final @ColorInt int dominantColor = BitmapUtils.getDominantColor(response.getBitmap(), DEFAULT_COLOR);
response.updateColor(dominantColor & 0x7FFFFFFF);
}
/**

View File

@ -139,7 +139,7 @@ public class ShortcutUtils {
} else {
// Otherwise, use the dominant color from the icon +
// a layer of transparent white to lighten it somewhat.
final int color = BitmapUtils.getDominantColor(aSource);
final int color = BitmapUtils.getDominantColorCustomImplementation(aSource);
paint.setColor(color);
canvas.drawRoundRect(new RectF(kOffset, kOffset, size - kOffset, size - kOffset),
kRadius, kRadius, paint);

View File

@ -483,6 +483,7 @@ gvjar.extra_jars += [
CONFIG['ANDROID_SUPPORT_ANNOTATIONS_JAR_LIB'],
CONFIG['ANDROID_SUPPORT_V4_AAR_LIB'],
CONFIG['ANDROID_SUPPORT_V4_AAR_INTERNAL_LIB'],
CONFIG['ANDROID_PALETTE_V7_AAR_LIB'],
'constants.jar',
'gecko-mozglue.jar',
'gecko-util.jar',
@ -1174,7 +1175,6 @@ gbjar.extra_jars += [CONFIG['ANDROID_CARDVIEW_V7_AAR_LIB']]
gbjar.extra_jars += [CONFIG['ANDROID_DESIGN_AAR_LIB']]
gbjar.extra_jars += [CONFIG['ANDROID_RECYCLERVIEW_V7_AAR_LIB']]
gbjar.extra_jars += [CONFIG['ANDROID_CUSTOMTABS_AAR_LIB']]
gbjar.extra_jars += [CONFIG['ANDROID_PALETTE_V7_AAR_LIB']]
gbjar.javac_flags += ['-Xlint:all,-deprecation,-fallthrough', '-J-Xmx512m', '-J-Xms128m']

View File

@ -104,6 +104,7 @@ android {
dependencies {
compile "com.android.support:support-v4:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
compile "com.android.support:palette-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
}
task syncPreprocessedCode(type: Sync, dependsOn: rootProject.generateCodeAndResources) {

View File

@ -19,9 +19,13 @@ import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.ColorInt;
import android.support.v7.graphics.Palette;
import android.util.Base64;
import android.util.Log;
import org.mozilla.gecko.util.HardwareUtils;
public final class BitmapUtils {
private static final String LOGTAG = "GeckoBitmapUtils";
@ -135,13 +139,39 @@ public final class BitmapUtils {
}
}
public static int getDominantColor(Bitmap source) {
return getDominantColor(source, true);
public static @ColorInt int getDominantColor(Bitmap source, @ColorInt int defaultColor) {
if (HardwareUtils.isX86System()) {
// (Bug 1318667) We are running into crashes when using the palette library with
// specific icons on x86 devices. They take down the whole VM and are not recoverable.
// Unfortunately our release icon is triggering this crash. Until we can switch to a
// newer version of the support library where this does not happen, we are using our
// own slower implementation.
return getDominantColorCustomImplementation(source, true, defaultColor);
} else {
try {
final Palette palette = Palette.from(source).generate();
return palette.getVibrantColor(defaultColor);
} catch (ArrayIndexOutOfBoundsException e) {
// We saw the palette library fail with an ArrayIndexOutOfBoundsException intermittently
// in automation. In this case lets just swallow the exception and move on without a
// color. This is a valid condition and callers should handle this gracefully (Bug 1318560).
Log.e(LOGTAG, "Palette generation failed with ArrayIndexOutOfBoundsException", e);
return defaultColor;
}
}
}
public static int getDominantColor(Bitmap source, boolean applyThreshold) {
if (source == null)
return Color.argb(255, 255, 255, 255);
public static @ColorInt int getDominantColorCustomImplementation(Bitmap source) {
return getDominantColorCustomImplementation(source, true, Color.WHITE);
}
public static @ColorInt int getDominantColorCustomImplementation(Bitmap source,
boolean applyThreshold,
@ColorInt int defaultColor) {
if (source == null) {
return defaultColor;
}
// Keep track of how many times a hue in a given bin appears in the image.
// Hue values range [0 .. 360), so dividing by 10, we get 36 bins.
@ -193,8 +223,9 @@ public final class BitmapUtils {
}
// maxBin may never get updated if the image holds only transparent and/or black/white pixels.
if (maxBin < 0)
return Color.argb(255, 255, 255, 255);
if (maxBin < 0) {
return defaultColor;
}
// Return a color with the average hue/saturation/value of the bin with the most colors.
hsv[0] = sumHue[maxBin] / colorBins[maxBin];

View File

@ -139,11 +139,11 @@ public class SearchBar extends FrameLayout {
engineIcon.setContentDescription(engine.getName());
// Update the focused background color.
int color = BitmapUtils.getDominantColor(bitmap);
int color = BitmapUtils.getDominantColorCustomImplementation(bitmap);
// BitmapUtils#getDominantColor ignores black and white pixels, but it will
// return white if no dominant color was found. We don't want to create a
// white underline for the search bar, so we default to black instead.
// BitmapUtils#getDominantColorCustomImplementation ignores black and white pixels,
// but it will return white if no dominant color was found. We don't want to create
// a white underline for the search bar, so we default to black instead.
if (color == Color.WHITE) {
color = Color.BLACK;
}