BookmarkUtils.java revision 90b40269a55eb34a2942c6a493819b60a03eb7f1
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.browser; 18 19import android.content.Context; 20import android.content.Intent; 21import android.graphics.Bitmap; 22import android.graphics.BitmapFactory; 23import android.graphics.Canvas; 24import android.graphics.Color; 25import android.graphics.Paint; 26import android.graphics.Path; 27import android.graphics.PorterDuff; 28import android.graphics.PorterDuffXfermode; 29import android.graphics.Rect; 30import android.graphics.RectF; 31import android.net.Uri; 32import android.provider.Browser; 33import android.util.Log; 34 35class BookmarkUtils { 36 private final static String LOGTAG = "BookmarkUtils"; 37 38 // XXX: There is no public string defining this intent so if Home changes the value, we 39 // have to update this string. 40 private static final String INSTALL_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT"; 41 42 enum BookmarkIconType { 43 ICON_INSTALLABLE_WEB_APP, // Icon for an installable web app (launches WebAppRuntime). 44 ICON_HOME_SHORTCUT // Icon for a shortcut on the home screen (launches Browser). 45 }; 46 47 /** 48 * Creates an icon to be associated with this bookmark. If available, the apple touch icon 49 * will be used, else we draw our own depending on the type of "bookmark" being created. 50 */ 51 static Bitmap createIcon(Context context, Bitmap touchIcon, Bitmap favicon, 52 BookmarkIconType type) { 53 int iconDimension = context.getResources().getDimensionPixelSize( 54 android.R.dimen.app_icon_size); 55 56 Bitmap bm = Bitmap.createBitmap(iconDimension, iconDimension, Bitmap.Config.ARGB_8888); 57 Canvas canvas = new Canvas(bm); 58 Rect iconBounds = new Rect(0, 0, bm.getWidth(), bm.getHeight()); 59 60 // Use the apple-touch-icon if available 61 if (touchIcon != null) { 62 drawTouchIconToCanvas(touchIcon, canvas, iconBounds); 63 } else { 64 // No touch icon so create our own. 65 // Set the background based on the type of shortcut (either webapp or home shortcut). 66 Bitmap icon = getIconBackground(context, type); 67 68 if (icon != null) { 69 // Now draw the correct icon background into our new bitmap. 70 canvas.drawBitmap(icon, null, iconBounds, null); 71 } 72 73 // If we have a favicon, overlay it in a nice rounded white box on top of the 74 // background. 75 if (favicon != null) { 76 drawFaviconToCanvas(favicon, canvas, iconBounds, 77 context.getResources().getDisplayMetrics().density); 78 } 79 } 80 return bm; 81 } 82 83 /** 84 * Convenience method for creating an intent that will add a shortcut to the home screen. 85 */ 86 static Intent createAddToHomeIntent(Context context, String url, String title, 87 Bitmap touchIcon, Bitmap favicon) { 88 Intent i = new Intent(INSTALL_SHORTCUT); 89 Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); 90 long urlHash = url.hashCode(); 91 long uniqueId = (urlHash << 32) | shortcutIntent.hashCode(); 92 shortcutIntent.putExtra(Browser.EXTRA_APPLICATION_ID, Long.toString(uniqueId)); 93 i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); 94 i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title); 95 i.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon(context, touchIcon, favicon, 96 BookmarkIconType.ICON_HOME_SHORTCUT)); 97 98 // Do not allow duplicate items 99 i.putExtra("duplicate", false); 100 return i; 101 } 102 103 private static Bitmap getIconBackground(Context context, BookmarkIconType type) { 104 if (type == BookmarkIconType.ICON_HOME_SHORTCUT) { 105 // Want to create a shortcut icon on the homescreen, so the icon 106 // background is the red bookmark. 107 return BitmapFactory.decodeResource(context.getResources(), 108 R.drawable.ic_launcher_shortcut_browser_bookmark); 109 } else if (type == BookmarkIconType.ICON_INSTALLABLE_WEB_APP) { 110 // Use the web browser icon as the background for the icon for an installable 111 // web app. 112 return BitmapFactory.decodeResource(context.getResources(), 113 R.drawable.ic_launcher_browser); 114 } 115 return null; 116 } 117 118 private static void drawTouchIconToCanvas(Bitmap touchIcon, Canvas canvas, Rect iconBounds) { 119 Rect src = new Rect(0, 0, touchIcon.getWidth(), touchIcon.getHeight()); 120 121 // Paint used for scaling the bitmap and drawing the rounded rect. 122 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 123 paint.setFilterBitmap(true); 124 canvas.drawBitmap(touchIcon, src, iconBounds, paint); 125 126 // Construct a path from a round rect. This will allow drawing with 127 // an inverse fill so we can punch a hole using the round rect. 128 Path path = new Path(); 129 path.setFillType(Path.FillType.INVERSE_WINDING); 130 RectF rect = new RectF(iconBounds); 131 rect.inset(1, 1); 132 path.addRoundRect(rect, 8f, 8f, Path.Direction.CW); 133 134 // Reuse the paint and clear the outside of the rectangle. 135 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 136 canvas.drawPath(path, paint); 137 } 138 139 private static void drawFaviconToCanvas(Bitmap favicon, Canvas canvas, Rect iconBounds, 140 float density) { 141 // Make a Paint for the white background rectangle and for 142 // filtering the favicon. 143 Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); 144 p.setStyle(Paint.Style.FILL_AND_STROKE); 145 p.setColor(Color.WHITE); 146 147 // Create a rectangle that is slightly wider than the favicon 148 final float iconSize = 16 * density; // 16x16 favicon 149 final float padding = 2 * density; // white padding around icon 150 final float rectSize = iconSize + 2 * padding; 151 final float x = iconBounds.exactCenterX() - (rectSize / 2); 152 // Note: Subtract 2 dip from the y position since the box is 153 // slightly higher than center. Use padding since it is already 154 // 2 * density. 155 final float y = iconBounds.exactCenterY() - (rectSize / 2) - padding; 156 RectF r = new RectF(x, y, x + rectSize, y + rectSize); 157 158 // Draw a white rounded rectangle behind the favicon 159 canvas.drawRoundRect(r, 2, 2, p); 160 161 // Draw the favicon in the same rectangle as the rounded 162 // rectangle but inset by the padding 163 // (results in a 16x16 favicon). 164 r.inset(padding, padding); 165 canvas.drawBitmap(favicon, null, r, p); 166 } 167 168}; 169