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 |