mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 1290014 - Move code from the FaviconGenerator class to the IconGenerator in the icons package. r=ahunt,Grisha
The FaviconGenerator is the last class in the old favicons package. As this class is only used by the IconGenerator let's move the code inside the new class and remove FaviconGenerator. MozReview-Commit-ID: 7NsJRGdoUWv --HG-- extra : rebase_source : 703b80560f47220d094de0049cd9b92f8cd524eb
This commit is contained in:
parent
2a9ce08987
commit
fb80b68a08
@ -1,168 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.favicons;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Generate favicons based on the page URL.
|
||||
*/
|
||||
public class FaviconGenerator {
|
||||
// Mozilla's Visual Design Colour Palette
|
||||
// http://firefoxux.github.io/StyleGuide/#/visualDesign/colours
|
||||
private static final int[] COLORS = {
|
||||
0xFFc33c32,
|
||||
0xFFf25820,
|
||||
0xFFff9216,
|
||||
0xFFffcb00,
|
||||
0xFF57bd35,
|
||||
0xFF01bdad,
|
||||
0xFF0996f8,
|
||||
0xFF02538b,
|
||||
0xFF1f386e,
|
||||
0xFF7a2f7a,
|
||||
0xFFea385e,
|
||||
};
|
||||
|
||||
// List of common prefixes of host names. Those prefixes will be striped before a prepresentative
|
||||
// character for an URL is determined.
|
||||
private static final String[] COMMON_PREFIXES = {
|
||||
"www.",
|
||||
"m.",
|
||||
"mobile.",
|
||||
};
|
||||
|
||||
private static final int TEXT_SIZE_DP = 12;
|
||||
|
||||
public static class IconWithColor {
|
||||
public final Bitmap bitmap;
|
||||
public final int color;
|
||||
|
||||
private IconWithColor(Bitmap bitmap, int color) {
|
||||
this.bitmap = bitmap;
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate default favicon for the given page URL.
|
||||
*/
|
||||
public static IconWithColor generate(Context context, String pageURL) {
|
||||
final Resources resources = context.getResources();
|
||||
final int widthAndHeight = resources.getDimensionPixelSize(R.dimen.favicon_bg);
|
||||
final int roundedCorners = resources.getDimensionPixelOffset(R.dimen.favicon_corner_radius);
|
||||
|
||||
final Bitmap favicon = Bitmap.createBitmap(widthAndHeight, widthAndHeight, Bitmap.Config.ARGB_8888);
|
||||
final Canvas canvas = new Canvas(favicon);
|
||||
|
||||
final int color = pickColor(pageURL);
|
||||
|
||||
final Paint paint = new Paint();
|
||||
paint.setColor(color);
|
||||
|
||||
canvas.drawRoundRect(new RectF(0, 0, widthAndHeight, widthAndHeight), roundedCorners, roundedCorners, paint);
|
||||
|
||||
paint.setColor(Color.WHITE);
|
||||
|
||||
final String character = getRepresentativeCharacter(pageURL);
|
||||
|
||||
final float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DP, context.getResources().getDisplayMetrics());
|
||||
|
||||
paint.setTextAlign(Paint.Align.CENTER);
|
||||
paint.setTextSize(textSize);
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
canvas.drawText(character,
|
||||
canvas.getWidth() / 2,
|
||||
(int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)),
|
||||
paint);
|
||||
|
||||
return new IconWithColor(favicon, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a representative character for the given URL.
|
||||
*
|
||||
* For example this method will return "f" for "http://m.facebook.com/foobar".
|
||||
*/
|
||||
protected static String getRepresentativeCharacter(String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return "?";
|
||||
}
|
||||
|
||||
final String snippet = getRepresentativeSnippet(url);
|
||||
for (int i = 0; i < snippet.length(); i++) {
|
||||
char c = snippet.charAt(i);
|
||||
|
||||
if (Character.isLetterOrDigit(c)) {
|
||||
return String.valueOf(Character.toUpperCase(c));
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing found..
|
||||
return "?";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a color for this URL. Colors will be based on the host. URLs with the same host will
|
||||
* return the same color.
|
||||
*/
|
||||
protected static int pickColor(String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return COLORS[0];
|
||||
}
|
||||
|
||||
final String snippet = getRepresentativeSnippet(url);
|
||||
final int color = Math.abs(snippet.hashCode() % COLORS.length);
|
||||
|
||||
return COLORS[color];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the representative part of the URL. Usually this is the host (without common prefixes).
|
||||
*/
|
||||
private static String getRepresentativeSnippet(@NonNull String url) {
|
||||
Uri uri = Uri.parse(url);
|
||||
|
||||
// Use the host if available
|
||||
String snippet = uri.getHost();
|
||||
|
||||
if (TextUtils.isEmpty(snippet)) {
|
||||
// If the uri does not have a host (e.g. file:// uris) then use the path
|
||||
snippet = uri.getPath();
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(snippet)) {
|
||||
// If we still have no snippet then just return the question mark
|
||||
return "?";
|
||||
}
|
||||
|
||||
// Strip common prefixes that we do not want to use to determine the representative character
|
||||
for (String prefix : COMMON_PREFIXES) {
|
||||
if (snippet.startsWith(prefix)) {
|
||||
snippet = snippet.substring(prefix.length());
|
||||
}
|
||||
}
|
||||
|
||||
return snippet;
|
||||
}
|
||||
}
|
@ -5,7 +5,20 @@
|
||||
|
||||
package org.mozilla.gecko.icons.loader;
|
||||
|
||||
import org.mozilla.gecko.favicons.FaviconGenerator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.icons.IconRequest;
|
||||
import org.mozilla.gecko.icons.IconResponse;
|
||||
|
||||
@ -14,6 +27,31 @@ import org.mozilla.gecko.icons.IconResponse;
|
||||
* to be the last loader that will be tried.
|
||||
*/
|
||||
public class IconGenerator implements IconLoader {
|
||||
// Mozilla's Visual Design Colour Palette
|
||||
// http://firefoxux.github.io/StyleGuide/#/visualDesign/colours
|
||||
private static final int[] COLORS = {
|
||||
0xFFc33c32,
|
||||
0xFFf25820,
|
||||
0xFFff9216,
|
||||
0xFFffcb00,
|
||||
0xFF57bd35,
|
||||
0xFF01bdad,
|
||||
0xFF0996f8,
|
||||
0xFF02538b,
|
||||
0xFF1f386e,
|
||||
0xFF7a2f7a,
|
||||
0xFFea385e,
|
||||
};
|
||||
|
||||
// List of common prefixes of host names. Those prefixes will be striped before a prepresentative
|
||||
// character for an URL is determined.
|
||||
private static final String[] COMMON_PREFIXES = {
|
||||
"www.",
|
||||
"m.",
|
||||
"mobile.",
|
||||
};
|
||||
|
||||
private static final int TEXT_SIZE_DP = 12;
|
||||
@Override
|
||||
public IconResponse load(IconRequest request) {
|
||||
if (request.getIconCount() > 1) {
|
||||
@ -22,9 +60,109 @@ public class IconGenerator implements IconLoader {
|
||||
return null;
|
||||
}
|
||||
|
||||
final FaviconGenerator.IconWithColor iconWithColor = FaviconGenerator.generate(
|
||||
request.getContext(), request.getPageUrl());
|
||||
return generate(request.getContext(), request.getPageUrl());
|
||||
}
|
||||
|
||||
return IconResponse.createGenerated(iconWithColor.bitmap, iconWithColor.color);
|
||||
/**
|
||||
* Generate default favicon for the given page URL.
|
||||
*/
|
||||
@VisibleForTesting static IconResponse generate(Context context, String pageURL) {
|
||||
final Resources resources = context.getResources();
|
||||
final int widthAndHeight = resources.getDimensionPixelSize(R.dimen.favicon_bg);
|
||||
final int roundedCorners = resources.getDimensionPixelOffset(R.dimen.favicon_corner_radius);
|
||||
|
||||
final Bitmap favicon = Bitmap.createBitmap(widthAndHeight, widthAndHeight, Bitmap.Config.ARGB_8888);
|
||||
final Canvas canvas = new Canvas(favicon);
|
||||
|
||||
final int color = pickColor(pageURL);
|
||||
|
||||
final Paint paint = new Paint();
|
||||
paint.setColor(color);
|
||||
|
||||
canvas.drawRoundRect(new RectF(0, 0, widthAndHeight, widthAndHeight), roundedCorners, roundedCorners, paint);
|
||||
|
||||
paint.setColor(Color.WHITE);
|
||||
|
||||
final String character = getRepresentativeCharacter(pageURL);
|
||||
|
||||
final float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DP, context.getResources().getDisplayMetrics());
|
||||
|
||||
paint.setTextAlign(Paint.Align.CENTER);
|
||||
paint.setTextSize(textSize);
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
canvas.drawText(character,
|
||||
canvas.getWidth() / 2,
|
||||
(int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)),
|
||||
paint);
|
||||
|
||||
return IconResponse.createGenerated(favicon, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a representative character for the given URL.
|
||||
*
|
||||
* For example this method will return "f" for "http://m.facebook.com/foobar".
|
||||
*/
|
||||
@VisibleForTesting static String getRepresentativeCharacter(String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return "?";
|
||||
}
|
||||
|
||||
final String snippet = getRepresentativeSnippet(url);
|
||||
for (int i = 0; i < snippet.length(); i++) {
|
||||
char c = snippet.charAt(i);
|
||||
|
||||
if (Character.isLetterOrDigit(c)) {
|
||||
return String.valueOf(Character.toUpperCase(c));
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing found..
|
||||
return "?";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a color for this URL. Colors will be based on the host. URLs with the same host will
|
||||
* return the same color.
|
||||
*/
|
||||
@VisibleForTesting static int pickColor(String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return COLORS[0];
|
||||
}
|
||||
|
||||
final String snippet = getRepresentativeSnippet(url);
|
||||
final int color = Math.abs(snippet.hashCode() % COLORS.length);
|
||||
|
||||
return COLORS[color];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the representative part of the URL. Usually this is the host (without common prefixes).
|
||||
*/
|
||||
private static String getRepresentativeSnippet(@NonNull String url) {
|
||||
Uri uri = Uri.parse(url);
|
||||
|
||||
// Use the host if available
|
||||
String snippet = uri.getHost();
|
||||
|
||||
if (TextUtils.isEmpty(snippet)) {
|
||||
// If the uri does not have a host (e.g. file:// uris) then use the path
|
||||
snippet = uri.getPath();
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(snippet)) {
|
||||
// If we still have no snippet then just return the question mark
|
||||
return "?";
|
||||
}
|
||||
|
||||
// Strip common prefixes that we do not want to use to determine the representative character
|
||||
for (String prefix : COMMON_PREFIXES) {
|
||||
if (snippet.startsWith(prefix)) {
|
||||
snippet = snippet.substring(prefix.length());
|
||||
}
|
||||
}
|
||||
|
||||
return snippet;
|
||||
}
|
||||
}
|
||||
|
@ -6,23 +6,18 @@
|
||||
package org.mozilla.gecko.widget;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.favicons.FaviconGenerator;
|
||||
import org.mozilla.gecko.icons.IconCallback;
|
||||
import org.mozilla.gecko.icons.IconResponse;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
@ -375,11 +375,6 @@ gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
|
||||
'DynamicToolbar.java',
|
||||
'EditBookmarkDialog.java',
|
||||
'Experiments.java',
|
||||
'favicons/decoders/FaviconDecoder.java',
|
||||
'favicons/decoders/ICODecoder.java',
|
||||
'favicons/decoders/IconDirectoryEntry.java',
|
||||
'favicons/decoders/LoadFaviconResult.java',
|
||||
'favicons/FaviconGenerator.java',
|
||||
'feeds/action/CheckForUpdatesAction.java',
|
||||
'feeds/action/EnrollSubscriptionsAction.java',
|
||||
'feeds/action/FeedAction.java',
|
||||
@ -492,6 +487,10 @@ gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
|
||||
'home/TopSitesThumbnailView.java',
|
||||
'home/TwoLinePageRow.java',
|
||||
'home/UpdateViewFaviconLoadedListener.java',
|
||||
'icons/decoders/FaviconDecoder.java',
|
||||
'icons/decoders/ICODecoder.java',
|
||||
'icons/decoders/IconDirectoryEntry.java',
|
||||
'icons/decoders/LoadFaviconResult.java',
|
||||
'icons/IconCallback.java',
|
||||
'icons/IconDescriptor.java',
|
||||
'icons/IconDescriptorComparator.java',
|
||||
|
@ -1,93 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.favicons;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(TestRunner.class)
|
||||
public class TestFaviconGenerator {
|
||||
@Test
|
||||
public void testRepresentativeCharacter() {
|
||||
Assert.assertEquals("M", FaviconGenerator.getRepresentativeCharacter("https://mozilla.org"));
|
||||
Assert.assertEquals("W", FaviconGenerator.getRepresentativeCharacter("http://wikipedia.org"));
|
||||
Assert.assertEquals("P", FaviconGenerator.getRepresentativeCharacter("http://plus.google.com"));
|
||||
Assert.assertEquals("E", FaviconGenerator.getRepresentativeCharacter("https://en.m.wikipedia.org/wiki/Main_Page"));
|
||||
|
||||
// Stripping common prefixes
|
||||
Assert.assertEquals("T", FaviconGenerator.getRepresentativeCharacter("http://www.theverge.com"));
|
||||
Assert.assertEquals("F", FaviconGenerator.getRepresentativeCharacter("https://m.facebook.com"));
|
||||
Assert.assertEquals("T", FaviconGenerator.getRepresentativeCharacter("https://mobile.twitter.com"));
|
||||
|
||||
// Special urls
|
||||
Assert.assertEquals("?", FaviconGenerator.getRepresentativeCharacter("file:///"));
|
||||
Assert.assertEquals("S", FaviconGenerator.getRepresentativeCharacter("file:///system/"));
|
||||
Assert.assertEquals("P", FaviconGenerator.getRepresentativeCharacter("ftp://people.mozilla.org/test"));
|
||||
|
||||
// No values
|
||||
Assert.assertEquals("?", FaviconGenerator.getRepresentativeCharacter(""));
|
||||
Assert.assertEquals("?", FaviconGenerator.getRepresentativeCharacter(null));
|
||||
|
||||
// Rubbish
|
||||
Assert.assertEquals("Z", FaviconGenerator.getRepresentativeCharacter("zZz"));
|
||||
Assert.assertEquals("Ö", FaviconGenerator.getRepresentativeCharacter("ölkfdpou3rkjaslfdköasdfo8"));
|
||||
Assert.assertEquals("?", FaviconGenerator.getRepresentativeCharacter("_*+*'##"));
|
||||
Assert.assertEquals("ツ", FaviconGenerator.getRepresentativeCharacter("¯\\_(ツ)_/¯"));
|
||||
Assert.assertEquals("ಠ", FaviconGenerator.getRepresentativeCharacter("ಠ_ಠ Look of Disapproval"));
|
||||
|
||||
// Non-ASCII
|
||||
Assert.assertEquals("Ä", FaviconGenerator.getRepresentativeCharacter("http://www.ätzend.de"));
|
||||
Assert.assertEquals("名", FaviconGenerator.getRepresentativeCharacter("http://名がドメイン.com"));
|
||||
Assert.assertEquals("C", FaviconGenerator.getRepresentativeCharacter("http://√.com"));
|
||||
Assert.assertEquals("ß", FaviconGenerator.getRepresentativeCharacter("http://ß.de"));
|
||||
Assert.assertEquals("Ԛ", FaviconGenerator.getRepresentativeCharacter("http://ԛәлп.com/")); // cyrillic
|
||||
|
||||
// Punycode
|
||||
Assert.assertEquals("X", FaviconGenerator.getRepresentativeCharacter("http://xn--tzend-fra.de")); // ätzend.de
|
||||
Assert.assertEquals("X", FaviconGenerator.getRepresentativeCharacter("http://xn--V8jxj3d1dzdz08w.com")); // 名がドメイン.com
|
||||
|
||||
// Numbers
|
||||
Assert.assertEquals("1", FaviconGenerator.getRepresentativeCharacter("https://www.1and1.com/"));
|
||||
|
||||
// IP
|
||||
Assert.assertEquals("1", FaviconGenerator.getRepresentativeCharacter("https://192.168.0.1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPickColor() {
|
||||
final int color = FaviconGenerator.pickColor("http://m.facebook.com");
|
||||
|
||||
// Color does not change
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Assert.assertEquals(color, FaviconGenerator.pickColor("http://m.facebook.com"));
|
||||
}
|
||||
|
||||
// Color is stable for "similar" hosts.
|
||||
Assert.assertEquals(color, FaviconGenerator.pickColor("https://m.facebook.com"));
|
||||
Assert.assertEquals(color, FaviconGenerator.pickColor("http://facebook.com"));
|
||||
Assert.assertEquals(color, FaviconGenerator.pickColor("http://www.facebook.com"));
|
||||
Assert.assertEquals(color, FaviconGenerator.pickColor("http://www.facebook.com/foo/bar/foobar?mobile=1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratingFavicon() {
|
||||
final FaviconGenerator.IconWithColor iconWithColor = FaviconGenerator.generate(RuntimeEnvironment.application, "http://m.facebook.com");
|
||||
final Bitmap bitmap = iconWithColor.bitmap;
|
||||
|
||||
Assert.assertNotNull(bitmap);
|
||||
|
||||
final int size = RuntimeEnvironment.application.getResources().getDimensionPixelSize(R.dimen.favicon_bg);
|
||||
Assert.assertEquals(size, bitmap.getWidth());
|
||||
Assert.assertEquals(size, bitmap.getHeight());
|
||||
|
||||
Assert.assertEquals(Bitmap.Config.ARGB_8888, bitmap.getConfig());
|
||||
}
|
||||
}
|
@ -3,10 +3,13 @@
|
||||
|
||||
package org.mozilla.gecko.icons.loader;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.icons.IconDescriptor;
|
||||
import org.mozilla.gecko.icons.IconRequest;
|
||||
@ -46,4 +49,80 @@ public class TestIconGenerator {
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertNotNull(response.getBitmap());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepresentativeCharacter() {
|
||||
Assert.assertEquals("M", IconGenerator.getRepresentativeCharacter("https://mozilla.org"));
|
||||
Assert.assertEquals("W", IconGenerator.getRepresentativeCharacter("http://wikipedia.org"));
|
||||
Assert.assertEquals("P", IconGenerator.getRepresentativeCharacter("http://plus.google.com"));
|
||||
Assert.assertEquals("E", IconGenerator.getRepresentativeCharacter("https://en.m.wikipedia.org/wiki/Main_Page"));
|
||||
|
||||
// Stripping common prefixes
|
||||
Assert.assertEquals("T", IconGenerator.getRepresentativeCharacter("http://www.theverge.com"));
|
||||
Assert.assertEquals("F", IconGenerator.getRepresentativeCharacter("https://m.facebook.com"));
|
||||
Assert.assertEquals("T", IconGenerator.getRepresentativeCharacter("https://mobile.twitter.com"));
|
||||
|
||||
// Special urls
|
||||
Assert.assertEquals("?", IconGenerator.getRepresentativeCharacter("file:///"));
|
||||
Assert.assertEquals("S", IconGenerator.getRepresentativeCharacter("file:///system/"));
|
||||
Assert.assertEquals("P", IconGenerator.getRepresentativeCharacter("ftp://people.mozilla.org/test"));
|
||||
|
||||
// No values
|
||||
Assert.assertEquals("?", IconGenerator.getRepresentativeCharacter(""));
|
||||
Assert.assertEquals("?", IconGenerator.getRepresentativeCharacter(null));
|
||||
|
||||
// Rubbish
|
||||
Assert.assertEquals("Z", IconGenerator.getRepresentativeCharacter("zZz"));
|
||||
Assert.assertEquals("Ö", IconGenerator.getRepresentativeCharacter("ölkfdpou3rkjaslfdköasdfo8"));
|
||||
Assert.assertEquals("?", IconGenerator.getRepresentativeCharacter("_*+*'##"));
|
||||
Assert.assertEquals("ツ", IconGenerator.getRepresentativeCharacter("¯\\_(ツ)_/¯"));
|
||||
Assert.assertEquals("ಠ", IconGenerator.getRepresentativeCharacter("ಠ_ಠ Look of Disapproval"));
|
||||
|
||||
// Non-ASCII
|
||||
Assert.assertEquals("Ä", IconGenerator.getRepresentativeCharacter("http://www.ätzend.de"));
|
||||
Assert.assertEquals("名", IconGenerator.getRepresentativeCharacter("http://名がドメイン.com"));
|
||||
Assert.assertEquals("C", IconGenerator.getRepresentativeCharacter("http://√.com"));
|
||||
Assert.assertEquals("ß", IconGenerator.getRepresentativeCharacter("http://ß.de"));
|
||||
Assert.assertEquals("Ԛ", IconGenerator.getRepresentativeCharacter("http://ԛәлп.com/")); // cyrillic
|
||||
|
||||
// Punycode
|
||||
Assert.assertEquals("X", IconGenerator.getRepresentativeCharacter("http://xn--tzend-fra.de")); // ätzend.de
|
||||
Assert.assertEquals("X", IconGenerator.getRepresentativeCharacter("http://xn--V8jxj3d1dzdz08w.com")); // 名がドメイン.com
|
||||
|
||||
// Numbers
|
||||
Assert.assertEquals("1", IconGenerator.getRepresentativeCharacter("https://www.1and1.com/"));
|
||||
|
||||
// IP
|
||||
Assert.assertEquals("1", IconGenerator.getRepresentativeCharacter("https://192.168.0.1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPickColor() {
|
||||
final int color = IconGenerator.pickColor("http://m.facebook.com");
|
||||
|
||||
// Color does not change
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Assert.assertEquals(color, IconGenerator.pickColor("http://m.facebook.com"));
|
||||
}
|
||||
|
||||
// Color is stable for "similar" hosts.
|
||||
Assert.assertEquals(color, IconGenerator.pickColor("https://m.facebook.com"));
|
||||
Assert.assertEquals(color, IconGenerator.pickColor("http://facebook.com"));
|
||||
Assert.assertEquals(color, IconGenerator.pickColor("http://www.facebook.com"));
|
||||
Assert.assertEquals(color, IconGenerator.pickColor("http://www.facebook.com/foo/bar/foobar?mobile=1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratingFavicon() {
|
||||
final IconResponse response = IconGenerator.generate(RuntimeEnvironment.application, "http://m.facebook.com");
|
||||
final Bitmap bitmap = response.getBitmap();
|
||||
|
||||
Assert.assertNotNull(bitmap);
|
||||
|
||||
final int size = RuntimeEnvironment.application.getResources().getDimensionPixelSize(R.dimen.favicon_bg);
|
||||
Assert.assertEquals(size, bitmap.getWidth());
|
||||
Assert.assertEquals(size, bitmap.getHeight());
|
||||
|
||||
Assert.assertEquals(Bitmap.Config.ARGB_8888, bitmap.getConfig());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user