• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.chrome.browser;
6 
7 import android.app.ActivityManager;
8 import android.content.Context;
9 import android.content.Intent;
10 import android.graphics.Bitmap;
11 import android.graphics.Canvas;
12 import android.graphics.Color;
13 import android.graphics.Paint;
14 import android.graphics.Path;
15 import android.graphics.PorterDuff;
16 import android.graphics.PorterDuffColorFilter;
17 import android.graphics.PorterDuffXfermode;
18 import android.graphics.Rect;
19 import android.graphics.RectF;
20 import android.graphics.drawable.BitmapDrawable;
21 import android.graphics.drawable.Drawable;
22 import android.net.Uri;
23 import android.os.Build;
24 import android.util.Log;
25 import android.util.TypedValue;
26 
27 import org.chromium.chrome.R;
28 
29 /**
30  * Util class for bookmarks.
31  */
32 public class BookmarkUtils {
33 
34     // There is no public string defining this intent so if Home changes the value, we
35     // have to update this string.
36     private static final String INSTALL_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT";
37     private static final int DEFAULT_RGB_VALUE = 145;
38     private static final String TAG = "BookmarkUtils";
39     public static final String REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB =
40             "REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB";
41     private static final int INSET_DIMENSION_FOR_TOUCHICON = 1;
42     private static final int TOUCHICON_BORDER_RADII = 10;
43 
44     /**
45      * Creates an intent that will add a shortcut to the home screen.
46      * @param context Context used to create the intent.
47      * @param shortcutIntent Intent to fire when the shortcut is activated.
48      * @param title Title of the bookmark.
49      * @param favicon Bookmark favicon.
50      * @param rValue Red component of the dominant favicon color.
51      * @param gValue Green component of the dominant favicon color.
52      * @param bValue Blue component of the dominant favicon color.
53      * @return Intent for the shortcut.
54      */
createAddToHomeIntent(Context context, Intent shortcutIntent, String title, Bitmap favicon, int rValue, int gValue, int bValue)55     public static Intent createAddToHomeIntent(Context context, Intent shortcutIntent, String title,
56             Bitmap favicon, int rValue, int gValue, int bValue) {
57         Intent i = new Intent(INSTALL_SHORTCUT);
58         i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
59         i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
60         i.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon(context, favicon, rValue,
61                 gValue, bValue));
62         return i;
63     }
64 
65     /**
66      * Creates an intent that will add a shortcut to the home screen.
67      * @param context Context used to create the intent.
68      * @param url Url of the bookmark.
69      * @param title Title of the bookmark.
70      * @param favicon Bookmark favicon.
71      * @param rValue Red component of the dominant favicon color.
72      * @param gValue Green component of the dominant favicon color.
73      * @param bValue Blue component of the dominant favicon color.
74      * @return Intent for the shortcut.
75      */
createAddToHomeIntent(Context context, String url, String title, Bitmap favicon, int rValue, int gValue, int bValue)76     public static Intent createAddToHomeIntent(Context context, String url, String title,
77             Bitmap favicon, int rValue, int gValue, int bValue) {
78         Intent shortcutIntent = createShortcutIntent(context, url);
79         return createAddToHomeIntent(
80                 context, shortcutIntent, title, favicon, rValue, gValue, bValue);
81     }
82 
83     /**
84      * Shortcut intent for icon on homescreen.
85      * @param context Context used to create the intent.
86      * @param url Url of the bookmark.
87      * @return Intent for onclick action of the shortcut.
88      */
createShortcutIntent(Context context, String url)89     public static Intent createShortcutIntent(Context context, String url) {
90         Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
91         shortcutIntent.putExtra(REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true);
92         return shortcutIntent;
93     }
94 
95     /**
96      * Creates an icon to be associated with this bookmark. If available, the touch icon
97      * will be used, else we draw our own.
98      * @param context Context used to create the intent.
99      * @param favicon Bookmark favicon bitmap.
100      * @param rValue Red component of the dominant favicon color.
101      * @param gValue Green component of the dominant favicon color.
102      * @param bValue Blue component of the dominant favicon color.
103      * @return Bitmap Either the touch-icon or the newly created favicon.
104      */
createIcon(Context context, Bitmap favicon, int rValue, int gValue, int bValue)105     private static Bitmap createIcon(Context context, Bitmap favicon, int rValue,
106             int gValue, int bValue) {
107         Bitmap bitmap = null;
108         ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
109         final int iconSize = am.getLauncherLargeIconSize();
110         final int iconDensity = am.getLauncherLargeIconDensity();
111         try {
112             bitmap = Bitmap.createBitmap(iconSize, iconSize, Bitmap.Config.ARGB_8888);
113             Canvas canvas = new Canvas(bitmap);
114             if (favicon == null) {
115                 favicon = getBitmapFromResourceId(context, R.drawable.globe_favicon, iconDensity);
116                 rValue = gValue = bValue = DEFAULT_RGB_VALUE;
117             }
118             final int smallestSide = iconSize;
119             if (favicon.getWidth() >= smallestSide / 2 && favicon.getHeight() >= smallestSide / 2) {
120                 drawTouchIconToCanvas(context, favicon, canvas);
121             } else {
122                 drawWidgetBackgroundToCanvas(context, canvas, iconDensity,
123                         Color.rgb(rValue, gValue, bValue));
124                 drawFaviconToCanvas(context, favicon, canvas);
125             }
126             canvas.setBitmap(null);
127         } catch (OutOfMemoryError e) {
128             Log.w(TAG, "OutOfMemoryError while trying to draw bitmap on canvas.");
129         }
130         return bitmap;
131     }
132 
getBitmapFromResourceId(Context context, int id, int density)133     private static Bitmap getBitmapFromResourceId(Context context, int id, int density) {
134         Drawable drawable = null;
135         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
136             drawable = context.getResources().getDrawableForDensity(id, density);
137         } else {
138             drawable = context.getResources().getDrawable(id);
139         }
140 
141         if (drawable instanceof BitmapDrawable) {
142             BitmapDrawable bd = (BitmapDrawable) drawable;
143             return bd.getBitmap();
144         }
145         assert false : "The drawable was not a bitmap drawable as expected";
146         return null;
147     }
148 
149     /**
150      * Use touch-icon or higher-resolution favicon and round the corners.
151      * @param context    Context used to get resources.
152      * @param touchIcon  Touch icon bitmap.
153      * @param canvas     Canvas that holds the touch icon.
154      */
drawTouchIconToCanvas( Context context, Bitmap touchIcon, Canvas canvas)155     private static void drawTouchIconToCanvas(
156             Context context, Bitmap touchIcon, Canvas canvas) {
157         Rect iconBounds = new Rect(0, 0, canvas.getWidth(), canvas.getHeight());
158         Rect src = new Rect(0, 0, touchIcon.getWidth(), touchIcon.getHeight());
159         Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
160         paint.setFilterBitmap(true);
161         canvas.drawBitmap(touchIcon, src, iconBounds, paint);
162         // Convert dp to px.
163         int borderRadii = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
164                 TOUCHICON_BORDER_RADII, context.getResources().getDisplayMetrics());
165         Path path = new Path();
166         path.setFillType(Path.FillType.INVERSE_WINDING);
167         RectF rect = new RectF(iconBounds);
168         rect.inset(INSET_DIMENSION_FOR_TOUCHICON, INSET_DIMENSION_FOR_TOUCHICON);
169         path.addRoundRect(rect, borderRadii, borderRadii, Path.Direction.CW);
170         paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
171         canvas.drawPath(path, paint);
172     }
173 
174     /**
175      * Draw the favicon with dominant color.
176      * @param context Context used to create the intent.
177      * @param favicon favicon bitmap.
178      * @param canvas Canvas that holds the favicon.
179      */
drawFaviconToCanvas(Context context, Bitmap favicon, Canvas canvas)180     private static void drawFaviconToCanvas(Context context, Bitmap favicon, Canvas canvas) {
181         Rect iconBounds = new Rect(0, 0, canvas.getWidth(), canvas.getHeight());
182         int faviconSize = iconBounds.width() / 3;
183         Bitmap scaledFavicon = Bitmap.createScaledBitmap(favicon, faviconSize, faviconSize, true);
184         canvas.drawBitmap(scaledFavicon,
185                 iconBounds.exactCenterX() - scaledFavicon.getWidth() / 2.0f,
186                 iconBounds.exactCenterY() - scaledFavicon.getHeight() / 2.0f, null);
187     }
188 
189     /**
190      * Draw document icon to canvas.
191      * @param context     Context used to get bitmap resources.
192      * @param canvas      Canvas that holds the document icon.
193      * @param iconDensity Density information to get bitmap resources.
194      * @param color       Color for the document icon's folding and the bottom strip.
195      */
drawWidgetBackgroundToCanvas( Context context, Canvas canvas, int iconDensity, int color)196     private static void drawWidgetBackgroundToCanvas(
197             Context context, Canvas canvas, int iconDensity, int color) {
198         Rect iconBounds = new Rect(0, 0, canvas.getWidth(), canvas.getHeight());
199         Bitmap bookmarkWidgetBg =
200                 getBitmapFromResourceId(context, R.mipmap.bookmark_widget_bg, iconDensity);
201         Bitmap bookmarkWidgetBgHighlights = getBitmapFromResourceId(context,
202                 R.mipmap.bookmark_widget_bg_highlights, iconDensity);
203         if (bookmarkWidgetBg == null || bookmarkWidgetBgHighlights == null) {
204             Log.w(TAG, "Can't load R.mipmap.bookmark_widget_bg or " +
205                     "R.mipmap.bookmark_widget_bg_highlights.");
206             return;
207         }
208         Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
209         canvas.drawBitmap(bookmarkWidgetBg, null, iconBounds, paint);
210 
211         // The following color filter will convert bookmark_widget_bg_highlights' white color to
212         // the 'color' variable when it is painted to 'canvas'.
213         paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
214         canvas.drawBitmap(bookmarkWidgetBgHighlights, null, iconBounds, paint);
215     }
216 }
217