| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser; | 5 package org.chromium.chrome.browser; |
| 6 | 6 |
| 7 import android.app.ActivityManager; | 7 import android.app.ActivityManager; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.content.Intent; | 9 import android.content.Intent; |
| 10 import android.graphics.Bitmap; | 10 import android.graphics.Bitmap; |
| 11 import android.graphics.Canvas; | 11 import android.graphics.Canvas; |
| 12 import android.graphics.Color; | 12 import android.graphics.Color; |
| 13 import android.graphics.LinearGradient; | |
| 14 import android.graphics.Paint; | 13 import android.graphics.Paint; |
| 15 import android.graphics.Path; | 14 import android.graphics.Path; |
| 16 import android.graphics.PorterDuff; | 15 import android.graphics.PorterDuff; |
| 16 import android.graphics.PorterDuffColorFilter; |
| 17 import android.graphics.PorterDuffXfermode; | 17 import android.graphics.PorterDuffXfermode; |
| 18 import android.graphics.Rect; | 18 import android.graphics.Rect; |
| 19 import android.graphics.RectF; | 19 import android.graphics.RectF; |
| 20 import android.graphics.drawable.BitmapDrawable; | 20 import android.graphics.drawable.BitmapDrawable; |
| 21 import android.graphics.drawable.Drawable; | 21 import android.graphics.drawable.Drawable; |
| 22 import android.net.Uri; | 22 import android.net.Uri; |
| 23 import android.os.Build; | 23 import android.os.Build; |
| 24 import android.util.Log; | 24 import android.util.Log; |
| 25 import android.util.TypedValue; |
| 25 | 26 |
| 26 import org.chromium.chrome.R; | 27 import org.chromium.chrome.R; |
| 27 | 28 |
| 28 /** | 29 /** |
| 29 * Util class for bookmarks. | 30 * Util class for bookmarks. |
| 30 */ | 31 */ |
| 31 public class BookmarkUtils { | 32 public class BookmarkUtils { |
| 32 | 33 |
| 33 // There is no public string defining this intent so if Home changes the val
ue, we | 34 // There is no public string defining this intent so if Home changes the val
ue, we |
| 34 // have to update this string. | 35 // have to update this string. |
| 35 private static final String INSTALL_SHORTCUT = "com.android.launcher.action.
INSTALL_SHORTCUT"; | 36 private static final String INSTALL_SHORTCUT = "com.android.launcher.action.
INSTALL_SHORTCUT"; |
| 36 private static final int DEFAULT_RGB_VALUE = 145; | 37 private static final int DEFAULT_RGB_VALUE = 145; |
| 37 private static final String TAG = "BookmarkUtils"; | 38 private static final String TAG = "BookmarkUtils"; |
| 38 public static final String REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB = | 39 public static final String REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB = |
| 39 "REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB"; | 40 "REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB"; |
| 40 private static final int INSET_DIMENSION_FOR_TOUCHICON = 1; | 41 private static final int INSET_DIMENSION_FOR_TOUCHICON = 1; |
| 41 private static final int SDK_VERSION_FOR_ACCESS_TO_METHODS = 15; | 42 private static final int TOUCHICON_BORDER_RADII = 10; |
| 42 | 43 |
| 43 /** | 44 /** |
| 44 * Creates an intent that will add a shortcut to the home screen. | 45 * Creates an intent that will add a shortcut to the home screen. |
| 45 * @param context Context used to create the intent. | 46 * @param context Context used to create the intent. |
| 46 * @param url Url of the bookmark. | 47 * @param url Url of the bookmark. |
| 47 * @param title Title of the bookmark. | 48 * @param title Title of the bookmark. |
| 48 * @param favicon Bookmark favicon. | 49 * @param favicon Bookmark favicon. |
| 49 * @param rValue Red component of the dominant favicon color. | 50 * @param rValue Red component of the dominant favicon color. |
| 50 * @param gValue Green component of the dominant favicon color. | 51 * @param gValue Green component of the dominant favicon color. |
| 51 * @param bValue Blue component of the dominant favicon color. | 52 * @param bValue Blue component of the dominant favicon color. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 81 * @param favicon Bookmark favicon bitmap. | 82 * @param favicon Bookmark favicon bitmap. |
| 82 * @param rValue Red component of the dominant favicon color. | 83 * @param rValue Red component of the dominant favicon color. |
| 83 * @param gValue Green component of the dominant favicon color. | 84 * @param gValue Green component of the dominant favicon color. |
| 84 * @param bValue Blue component of the dominant favicon color. | 85 * @param bValue Blue component of the dominant favicon color. |
| 85 * @return Bitmap Either the touch-icon or the newly created favicon. | 86 * @return Bitmap Either the touch-icon or the newly created favicon. |
| 86 */ | 87 */ |
| 87 private static Bitmap createIcon(Context context, Bitmap favicon, int rValue
, | 88 private static Bitmap createIcon(Context context, Bitmap favicon, int rValue
, |
| 88 int gValue, int bValue) { | 89 int gValue, int bValue) { |
| 89 Bitmap bitmap = null; | 90 Bitmap bitmap = null; |
| 90 ActivityManager am = (ActivityManager) context.getSystemService(Context.
ACTIVITY_SERVICE); | 91 ActivityManager am = (ActivityManager) context.getSystemService(Context.
ACTIVITY_SERVICE); |
| 91 final int iconDimension = am.getLauncherLargeIconSize(); | 92 final int iconSize = am.getLauncherLargeIconSize(); |
| 92 final int iconDensity = am.getLauncherLargeIconDensity(); | 93 final int iconDensity = am.getLauncherLargeIconDensity(); |
| 93 try { | 94 try { |
| 94 bitmap = Bitmap.createBitmap(iconDimension, iconDimension, Bitmap.Co
nfig.ARGB_8888); | 95 bitmap = Bitmap.createBitmap(iconSize, iconSize, Bitmap.Config.ARGB_
8888); |
| 95 Canvas canvas = new Canvas(bitmap); | 96 Canvas canvas = new Canvas(bitmap); |
| 96 Rect iconBounds = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight
()); | |
| 97 if (favicon == null) { | 97 if (favicon == null) { |
| 98 favicon = getBitmapFromResourceId(context, R.drawable.globe_favi
con, iconDensity); | 98 favicon = getBitmapFromResourceId(context, R.drawable.globe_favi
con, iconDensity); |
| 99 rValue = gValue = bValue = DEFAULT_RGB_VALUE; | 99 rValue = gValue = bValue = DEFAULT_RGB_VALUE; |
| 100 } | 100 } |
| 101 final int smallestSide = iconDimension; | 101 final int smallestSide = iconSize; |
| 102 if (favicon.getWidth() >= smallestSide / 2 && favicon.getHeight() >=
smallestSide / 2) { | 102 if (favicon.getWidth() >= smallestSide / 2 && favicon.getHeight() >=
smallestSide / 2) { |
| 103 drawTouchIconToCanvas(context, favicon, canvas, iconBounds); | 103 drawTouchIconToCanvas(context, favicon, canvas); |
| 104 } else { | 104 } else { |
| 105 Bitmap icon = getIconBackground(context, iconDensity); | 105 drawWidgetBackgroundToCanvas(context, canvas, iconDensity, |
| 106 if (icon != null) { | 106 Color.rgb(rValue, gValue, bValue)); |
| 107 canvas.drawBitmap(icon, null, iconBounds, new Paint(Paint.AN
TI_ALIAS_FLAG)); | 107 drawFaviconToCanvas(context, favicon, canvas); |
| 108 } | |
| 109 drawFaviconToCanvas(context, favicon, canvas, iconBounds, rValue
, gValue, bValue); | |
| 110 } | 108 } |
| 111 canvas.setBitmap(null); | 109 canvas.setBitmap(null); |
| 112 } catch (OutOfMemoryError e) { | 110 } catch (OutOfMemoryError e) { |
| 113 Log.w(TAG, "OutOfMemoryError while trying to draw bitmap on canvas."
); | 111 Log.w(TAG, "OutOfMemoryError while trying to draw bitmap on canvas."
); |
| 114 } | 112 } |
| 115 return bitmap; | 113 return bitmap; |
| 116 } | 114 } |
| 117 | 115 |
| 118 /** | |
| 119 * Get the icon background asset. | |
| 120 * @param context Context used to create the intent. | |
| 121 * @return Bitmap favicon background asset. | |
| 122 */ | |
| 123 private static Bitmap getIconBackground(Context context, int density) { | |
| 124 return getBitmapFromResourceId(context, R.mipmap.homescreen_bg, density)
; | |
| 125 } | |
| 126 | |
| 127 private static Bitmap getBitmapFromResourceId(Context context, int id, int d
ensity) { | 116 private static Bitmap getBitmapFromResourceId(Context context, int id, int d
ensity) { |
| 128 Drawable drawable = null; | 117 Drawable drawable = null; |
| 129 if (Build.VERSION.SDK_INT >= SDK_VERSION_FOR_ACCESS_TO_METHODS) { | 118 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
{ |
| 130 drawable = context.getResources().getDrawableForDensity(id, density)
; | 119 drawable = context.getResources().getDrawableForDensity(id, density)
; |
| 131 } else { | 120 } else { |
| 132 drawable = context.getResources().getDrawable(id); | 121 drawable = context.getResources().getDrawable(id); |
| 133 } | 122 } |
| 123 |
| 134 if (drawable instanceof BitmapDrawable) { | 124 if (drawable instanceof BitmapDrawable) { |
| 135 BitmapDrawable bd = (BitmapDrawable) drawable; | 125 BitmapDrawable bd = (BitmapDrawable) drawable; |
| 136 return bd.getBitmap(); | 126 return bd.getBitmap(); |
| 137 } | 127 } |
| 138 assert false : "The drawable was not a bitmap drawable as expected"; | 128 assert false : "The drawable was not a bitmap drawable as expected"; |
| 139 return null; | 129 return null; |
| 140 } | 130 } |
| 141 | 131 |
| 142 /** | 132 /** |
| 143 * Use touch-icon or higher-resolution favicon and round the corners. | 133 * Use touch-icon or higher-resolution favicon and round the corners. |
| 144 * @param context Context used to get resources. | 134 * @param context Context used to get resources. |
| 145 * @param touchIcon Touch icon bitmap. | 135 * @param touchIcon Touch icon bitmap. |
| 146 * @param canvas Canvas that holds the touch icon. | 136 * @param canvas Canvas that holds the touch icon. |
| 147 * @param iconBounds Rectangle bounds needed for adding rounded corners of t
he touch icon. | |
| 148 */ | 137 */ |
| 149 private static void drawTouchIconToCanvas( | 138 private static void drawTouchIconToCanvas( |
| 150 Context context, Bitmap touchIcon, Canvas canvas, Rect iconBounds) { | 139 Context context, Bitmap touchIcon, Canvas canvas) { |
| 140 Rect iconBounds = new Rect(0, 0, canvas.getWidth(), canvas.getHeight()); |
| 151 Rect src = new Rect(0, 0, touchIcon.getWidth(), touchIcon.getHeight()); | 141 Rect src = new Rect(0, 0, touchIcon.getWidth(), touchIcon.getHeight()); |
| 152 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); | 142 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); |
| 153 paint.setFilterBitmap(true); | 143 paint.setFilterBitmap(true); |
| 154 canvas.drawBitmap(touchIcon, src, iconBounds, paint); | 144 canvas.drawBitmap(touchIcon, src, iconBounds, paint); |
| 155 int borderRadii = | 145 // Convert dp to px. |
| 156 context.getResources().getDimensionPixelSize(R.dimen.touchicon_b
order_radii); | 146 int borderRadii = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNI
T_DIP, |
| 147 TOUCHICON_BORDER_RADII, context.getResources().getDisplayMetrics
()); |
| 157 Path path = new Path(); | 148 Path path = new Path(); |
| 158 path.setFillType(Path.FillType.INVERSE_WINDING); | 149 path.setFillType(Path.FillType.INVERSE_WINDING); |
| 159 RectF rect = new RectF(iconBounds); | 150 RectF rect = new RectF(iconBounds); |
| 160 rect.inset(INSET_DIMENSION_FOR_TOUCHICON, INSET_DIMENSION_FOR_TOUCHICON)
; | 151 rect.inset(INSET_DIMENSION_FOR_TOUCHICON, INSET_DIMENSION_FOR_TOUCHICON)
; |
| 161 path.addRoundRect(rect, borderRadii, borderRadii, Path.Direction.CW); | 152 path.addRoundRect(rect, borderRadii, borderRadii, Path.Direction.CW); |
| 162 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); | 153 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); |
| 163 canvas.drawPath(path, paint); | 154 canvas.drawPath(path, paint); |
| 164 } | 155 } |
| 165 | 156 |
| 166 /** | 157 /** |
| 167 * Draw the favicon with dominant color. | 158 * Draw the favicon with dominant color. |
| 168 * @param context Context used to create the intent. | 159 * @param context Context used to create the intent. |
| 169 * @param favicon favicon bitmap. | 160 * @param favicon favicon bitmap. |
| 170 * @param canvas Canvas that holds the favicon. | 161 * @param canvas Canvas that holds the favicon. |
| 171 * @param iconBounds Rectangle bounds needed to create the homescreen favico
n. | |
| 172 * @param rValue Red component of the dominant favicon color. | |
| 173 * @param gValue Green component of the dominant favicon color. | |
| 174 * @param bValue Blue component of the dominant favicon color. | |
| 175 */ | 162 */ |
| 176 private static void drawFaviconToCanvas(Context context, Bitmap favicon, | 163 private static void drawFaviconToCanvas(Context context, Bitmap favicon, Can
vas canvas) { |
| 177 Canvas canvas, Rect iconBounds, int rValue, int gValue, int bValue)
{ | 164 Rect iconBounds = new Rect(0, 0, canvas.getWidth(), canvas.getHeight()); |
| 178 int colorStripWidth = context.getResources().getDimensionPixelSize( | 165 int faviconSize = iconBounds.width() / 3; |
| 179 R.dimen.favicon_colorstrip_width); | 166 Bitmap scaledFavicon = Bitmap.createScaledBitmap(favicon, faviconSize, f
aviconSize, true); |
| 180 int colorStripHeight = context.getResources().getDimensionPixelSize( | 167 canvas.drawBitmap(scaledFavicon, |
| 181 R.dimen.favicon_colorstrip_height); | 168 iconBounds.exactCenterX() - scaledFavicon.getWidth() / 2.0f, |
| 182 int colorStripPadding = context.getResources().getDimensionPixelSize( | 169 iconBounds.exactCenterY() - scaledFavicon.getHeight() / 2.0f, nu
ll); |
| 183 R.dimen.favicon_colorstrip_padding); | 170 } |
| 184 int colorStripCornerRadii = context.getResources().getDimensionPixelSize
( | |
| 185 R.dimen.favicon_colorstrip_corner_radii); | |
| 186 int foldSize = context.getResources().getDimensionPixelSize(R.dimen.favi
con_fold_size); | |
| 187 int foldCornerRadii = context.getResources().getDimensionPixelSize( | |
| 188 R.dimen.favicon_fold_corner_radii); | |
| 189 int foldBorder = context.getResources().getDimensionPixelSize(R.dimen.fa
vicon_fold_border); | |
| 190 int foldShadow = context.getResources().getDimensionPixelSize(R.dimen.fa
vicon_fold_shadow); | |
| 191 int faviconSize = context.getResources().getDimensionPixelSize(R.dimen.f
avicon_size); | |
| 192 | 171 |
| 193 float x1 = iconBounds.exactCenterX() - (colorStripWidth / 2.0f); | 172 /** |
| 194 float x2 = x1 + colorStripWidth; | 173 * Draw document icon to canvas. |
| 195 float y1 = iconBounds.height() - colorStripPadding; | 174 * @param context Context used to get bitmap resources. |
| 196 float y2 = y1 - colorStripHeight; | 175 * @param canvas Canvas that holds the document icon. |
| 197 int faviconColorAlpha100 = Color.argb(255, rValue, gValue, bValue); | 176 * @param iconDensity Density information to get bitmap resources. |
| 198 Paint stripPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | 177 * @param color Color for the document icon's folding and the bottom s
trip. |
| 199 stripPaint.setColor(faviconColorAlpha100); | 178 */ |
| 200 stripPaint.setStyle(Paint.Style.FILL); | 179 private static void drawWidgetBackgroundToCanvas( |
| 201 Path stripPath = new Path(); | 180 Context context, Canvas canvas, int iconDensity, int color) { |
| 202 stripPath.moveTo(x1, y2); | 181 Rect iconBounds = new Rect(0, 0, canvas.getWidth(), canvas.getHeight()); |
| 203 stripPath.lineTo(x2, y2); | 182 Bitmap bookmark_widget_bg = |
| 204 stripPath.lineTo(x2, y1 - colorStripCornerRadii); | 183 getBitmapFromResourceId(context, R.mipmap.bookmark_widget_bg, ic
onDensity); |
| 205 stripPath.arcTo(new RectF(x2 - colorStripCornerRadii, y1 - colorStripCor
nerRadii, x2, y1), | 184 Bitmap bookmark_widget_bg_highlights = getBitmapFromResourceId(context, |
| 206 0, 90); | 185 R.mipmap.bookmark_widget_bg_highlights, iconDensity); |
| 207 stripPath.lineTo(x1 + colorStripCornerRadii, y1); | 186 if (bookmark_widget_bg == null || bookmark_widget_bg_highlights == null)
{ |
| 208 stripPath.arcTo(new RectF(x1, y1 - colorStripCornerRadii, x1 + colorStri
pCornerRadii, y1), | 187 Log.w(TAG, "Can't load R.mipmap.bookmark_widget_bg or " + |
| 209 90, 90); | 188 "R.mipmap.bookmark_widget_bg_highlights."); |
| 210 stripPath.lineTo(x1, y2); | 189 return; |
| 211 canvas.drawPath(stripPath, stripPaint); | 190 } |
| 191 Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG); |
| 192 canvas.drawBitmap(bookmark_widget_bg, null, iconBounds, paint); |
| 212 | 193 |
| 213 float ax, ay, bx, by, cx, cy; | 194 // The following color filter will convert bookmark_widget_bg_highlights
' white color to |
| 214 bx = ax = x2 - foldSize; | 195 // the 'color' variable when it is painted to 'canvas'. |
| 215 cx = x2; | 196 paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SR
C_IN)); |
| 216 ay = colorStripPadding; | 197 canvas.drawBitmap(bookmark_widget_bg_highlights, null, iconBounds, paint
); |
| 217 by = cy = colorStripPadding + foldSize; | |
| 218 int blackAlpha10 = Color.argb((int) (255 * 0.10f), 0, 0, 0); | |
| 219 | |
| 220 Paint foldShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
| 221 foldShadowPaint.setColor(Color.WHITE); | |
| 222 foldShadowPaint.setShadowLayer(1, 0, foldShadow, blackAlpha10); | |
| 223 int faviconColorAlpha60 = Color.argb((int) (255 * 0.60f), rValue, gValue
, bValue); | |
| 224 Paint foldGradientPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
| 225 foldGradientPaint.setShader(new LinearGradient(x2 - foldSize / 2.0f, | |
| 226 colorStripPadding + foldSize / 2.0f, x2 - foldSize, colorStripPa
dding + foldSize, | |
| 227 faviconColorAlpha60, faviconColorAlpha100, | |
| 228 android.graphics.Shader.TileMode.CLAMP)); | |
| 229 Path foldPath = new Path(); | |
| 230 foldPath.moveTo(ax, ay); | |
| 231 foldPath.lineTo(cx, cy); | |
| 232 foldPath.lineTo(bx + foldCornerRadii, by); | |
| 233 foldPath.arcTo(new RectF(bx, by - foldCornerRadii, bx + foldCornerRadii,
by), 90, 90); | |
| 234 foldPath.lineTo(ax, ay); | |
| 235 canvas.drawPath(foldPath, foldShadowPaint); | |
| 236 canvas.drawPath(foldPath, foldGradientPaint); | |
| 237 int faviconColorAlpha80 = Color.argb((int) (255 * 0.80f), rValue, gValue
, bValue); | |
| 238 Paint foldBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
| 239 foldBorderPaint.setColor(faviconColorAlpha80); | |
| 240 foldBorderPaint.setStyle(Paint.Style.STROKE); | |
| 241 foldBorderPaint.setStrokeWidth(foldBorder); | |
| 242 canvas.drawPath(foldPath, foldBorderPaint); | |
| 243 try { | |
| 244 Bitmap scaledFavicon = Bitmap.createScaledBitmap(favicon, faviconSiz
e, faviconSize, | |
| 245 true); | |
| 246 canvas.drawBitmap(scaledFavicon, | |
| 247 iconBounds.exactCenterX() - scaledFavicon.getWidth() / 2.0f, | |
| 248 iconBounds.exactCenterY() - scaledFavicon.getHeight() / 2.0f
, null); | |
| 249 } catch (OutOfMemoryError e) { | |
| 250 Log.w(TAG, "OutOfMemoryError while trying to draw bitmap on canvas."
); | |
| 251 } | |
| 252 } | 198 } |
| 253 } | 199 } |
| OLD | NEW |