From 90b40269a55eb34a2942c6a493819b60a03eb7f1 Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Wed, 30 Jun 2010 13:33:28 +0100 Subject: Create BookmarkUtils class. This factors out some bookmarks functionality that we would like to reuse when impementing installable webapps. Change-Id: Ia34d70b732c45220637767ddd0f05b280f0fc6bc --- src/com/android/browser/BookmarkUtils.java | 168 ++++++++++++++++++++++ src/com/android/browser/BrowserBookmarksPage.java | 106 +------------- 2 files changed, 172 insertions(+), 102 deletions(-) create mode 100644 src/com/android/browser/BookmarkUtils.java (limited to 'src/com') diff --git a/src/com/android/browser/BookmarkUtils.java b/src/com/android/browser/BookmarkUtils.java new file mode 100644 index 000000000..0fdad153f --- /dev/null +++ b/src/com/android/browser/BookmarkUtils.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.browser; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.graphics.RectF; +import android.net.Uri; +import android.provider.Browser; +import android.util.Log; + +class BookmarkUtils { + private final static String LOGTAG = "BookmarkUtils"; + + // XXX: There is no public string defining this intent so if Home changes the value, we + // have to update this string. + private static final String INSTALL_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT"; + + enum BookmarkIconType { + ICON_INSTALLABLE_WEB_APP, // Icon for an installable web app (launches WebAppRuntime). + ICON_HOME_SHORTCUT // Icon for a shortcut on the home screen (launches Browser). + }; + + /** + * Creates an icon to be associated with this bookmark. If available, the apple touch icon + * will be used, else we draw our own depending on the type of "bookmark" being created. + */ + static Bitmap createIcon(Context context, Bitmap touchIcon, Bitmap favicon, + BookmarkIconType type) { + int iconDimension = context.getResources().getDimensionPixelSize( + android.R.dimen.app_icon_size); + + Bitmap bm = Bitmap.createBitmap(iconDimension, iconDimension, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bm); + Rect iconBounds = new Rect(0, 0, bm.getWidth(), bm.getHeight()); + + // Use the apple-touch-icon if available + if (touchIcon != null) { + drawTouchIconToCanvas(touchIcon, canvas, iconBounds); + } else { + // No touch icon so create our own. + // Set the background based on the type of shortcut (either webapp or home shortcut). + Bitmap icon = getIconBackground(context, type); + + if (icon != null) { + // Now draw the correct icon background into our new bitmap. + canvas.drawBitmap(icon, null, iconBounds, null); + } + + // If we have a favicon, overlay it in a nice rounded white box on top of the + // background. + if (favicon != null) { + drawFaviconToCanvas(favicon, canvas, iconBounds, + context.getResources().getDisplayMetrics().density); + } + } + return bm; + } + + /** + * Convenience method for creating an intent that will add a shortcut to the home screen. + */ + static Intent createAddToHomeIntent(Context context, String url, String title, + Bitmap touchIcon, Bitmap favicon) { + Intent i = new Intent(INSTALL_SHORTCUT); + Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + long urlHash = url.hashCode(); + long uniqueId = (urlHash << 32) | shortcutIntent.hashCode(); + shortcutIntent.putExtra(Browser.EXTRA_APPLICATION_ID, Long.toString(uniqueId)); + i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); + i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title); + i.putExtra(Intent.EXTRA_SHORTCUT_ICON, createIcon(context, touchIcon, favicon, + BookmarkIconType.ICON_HOME_SHORTCUT)); + + // Do not allow duplicate items + i.putExtra("duplicate", false); + return i; + } + + private static Bitmap getIconBackground(Context context, BookmarkIconType type) { + if (type == BookmarkIconType.ICON_HOME_SHORTCUT) { + // Want to create a shortcut icon on the homescreen, so the icon + // background is the red bookmark. + return BitmapFactory.decodeResource(context.getResources(), + R.drawable.ic_launcher_shortcut_browser_bookmark); + } else if (type == BookmarkIconType.ICON_INSTALLABLE_WEB_APP) { + // Use the web browser icon as the background for the icon for an installable + // web app. + return BitmapFactory.decodeResource(context.getResources(), + R.drawable.ic_launcher_browser); + } + return null; + } + + private static void drawTouchIconToCanvas(Bitmap touchIcon, Canvas canvas, Rect iconBounds) { + Rect src = new Rect(0, 0, touchIcon.getWidth(), touchIcon.getHeight()); + + // Paint used for scaling the bitmap and drawing the rounded rect. + Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + paint.setFilterBitmap(true); + canvas.drawBitmap(touchIcon, src, iconBounds, paint); + + // Construct a path from a round rect. This will allow drawing with + // an inverse fill so we can punch a hole using the round rect. + Path path = new Path(); + path.setFillType(Path.FillType.INVERSE_WINDING); + RectF rect = new RectF(iconBounds); + rect.inset(1, 1); + path.addRoundRect(rect, 8f, 8f, Path.Direction.CW); + + // Reuse the paint and clear the outside of the rectangle. + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); + canvas.drawPath(path, paint); + } + + private static void drawFaviconToCanvas(Bitmap favicon, Canvas canvas, Rect iconBounds, + float density) { + // Make a Paint for the white background rectangle and for + // filtering the favicon. + Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); + p.setStyle(Paint.Style.FILL_AND_STROKE); + p.setColor(Color.WHITE); + + // Create a rectangle that is slightly wider than the favicon + final float iconSize = 16 * density; // 16x16 favicon + final float padding = 2 * density; // white padding around icon + final float rectSize = iconSize + 2 * padding; + final float x = iconBounds.exactCenterX() - (rectSize / 2); + // Note: Subtract 2 dip from the y position since the box is + // slightly higher than center. Use padding since it is already + // 2 * density. + final float y = iconBounds.exactCenterY() - (rectSize / 2) - padding; + RectF r = new RectF(x, y, x + rectSize, y + rectSize); + + // Draw a white rounded rectangle behind the favicon + canvas.drawRoundRect(r, 2, 2, p); + + // Draw the favicon in the same rectangle as the rounded + // rectangle but inset by the padding + // (results in a 16x16 favicon). + r.inset(padding, padding); + canvas.drawBitmap(favicon, null, r, p); + } + +}; diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java index 7560c78af..320c43825 100644 --- a/src/com/android/browser/BrowserBookmarksPage.java +++ b/src/com/android/browser/BrowserBookmarksPage.java @@ -74,10 +74,6 @@ public class BrowserBookmarksPage extends Activity implements private boolean mMostVisited; private View mEmptyView; private int mIconSize; - // XXX: There is no public string defining this intent so if Home changes - // the value, we have to update this string. - private static final String INSTALL_SHORTCUT = - "com.android.launcher.action.INSTALL_SHORTCUT"; private final static String LOGTAG = "browser"; private final static String PREF_BOOKMARK_VIEW_MODE = "pref_bookmark_view_mode"; @@ -108,9 +104,7 @@ public class BrowserBookmarksPage extends Activity implements editBookmark(i.position); break; case R.id.shortcut_context_menu_id: - final Intent send = createShortcutIntent(i.position); - send.setAction(INSTALL_SHORTCUT); - sendBroadcast(send); + sendBroadcast(createShortcutIntent(i.position)); break; case R.id.delete_context_menu_id: if (mMostVisited) { @@ -438,8 +432,7 @@ public class BrowserBookmarksPage extends Activity implements loadUrl(position); } } else { - final Intent intent = createShortcutIntent(position); - setResultToParent(RESULT_OK, intent); + setResultToParent(RESULT_OK, createShortcutIntent(position)); finish(); } } @@ -449,99 +442,8 @@ public class BrowserBookmarksPage extends Activity implements String url = getUrl(position); String title = getBookmarkTitle(position); Bitmap touchIcon = getTouchIcon(position); - - final Intent i = new Intent(); - final Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, - Uri.parse(url)); - long urlHash = url.hashCode(); - long uniqueId = (urlHash << 32) | shortcutIntent.hashCode(); - shortcutIntent.putExtra(Browser.EXTRA_APPLICATION_ID, - Long.toString(uniqueId)); - i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); - i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title); - // Use the apple-touch-icon if available - if (touchIcon != null) { - // Make a copy so we can modify the pixels. We can't use - // createScaledBitmap or copy since they will preserve the config - // and lose the ability to add alpha. - Bitmap bm = Bitmap.createBitmap(mIconSize, mIconSize, - Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bm); - Rect src = new Rect(0, 0, touchIcon.getWidth(), - touchIcon.getHeight()); - Rect dest = new Rect(0, 0, bm.getWidth(), bm.getHeight()); - - // Paint used for scaling the bitmap and drawing the rounded rect. - Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); - paint.setFilterBitmap(true); - canvas.drawBitmap(touchIcon, src, dest, paint); - - // Construct a path from a round rect. This will allow drawing with - // an inverse fill so we can punch a hole using the round rect. - Path path = new Path(); - path.setFillType(Path.FillType.INVERSE_WINDING); - RectF rect = new RectF(0, 0, bm.getWidth(), bm.getHeight()); - rect.inset(1, 1); - path.addRoundRect(rect, 8f, 8f, Path.Direction.CW); - - // Reuse the paint and clear the outside of the rectangle. - paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); - canvas.drawPath(path, paint); - - i.putExtra(Intent.EXTRA_SHORTCUT_ICON, bm); - } else { - Bitmap favicon = getFavicon(position); - if (favicon == null) { - i.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, - Intent.ShortcutIconResource.fromContext( - BrowserBookmarksPage.this, - R.drawable.ic_launcher_shortcut_browser_bookmark)); - } else { - Bitmap icon = BitmapFactory.decodeResource(getResources(), - R.drawable.ic_launcher_shortcut_browser_bookmark_icon); - - // Make a copy of the regular icon so we can modify the pixels. - Bitmap copy = icon.copy(Bitmap.Config.ARGB_8888, true); - Canvas canvas = new Canvas(copy); - - // Make a Paint for the white background rectangle and for - // filtering the favicon. - Paint p = new Paint(Paint.ANTI_ALIAS_FLAG - | Paint.FILTER_BITMAP_FLAG); - p.setStyle(Paint.Style.FILL_AND_STROKE); - p.setColor(Color.WHITE); - - final float density = - getResources().getDisplayMetrics().density; - // Create a rectangle that is slightly wider than the favicon - final float iconSize = 16 * density; // 16x16 favicon - final float padding = 2 * density; // white padding around icon - final float rectSize = iconSize + 2 * padding; - - final Rect iconBounds = - new Rect(0, 0, icon.getWidth(), icon.getHeight()); - final float x = iconBounds.exactCenterX() - (rectSize / 2); - // Note: Subtract 2 dip from the y position since the box is - // slightly higher than center. Use padding since it is already - // 2 * density. - final float y = iconBounds.exactCenterY() - (rectSize / 2) - - padding; - RectF r = new RectF(x, y, x + rectSize, y + rectSize); - - // Draw a white rounded rectangle behind the favicon - canvas.drawRoundRect(r, 2, 2, p); - - // Draw the favicon in the same rectangle as the rounded - // rectangle but inset by the padding - // (results in a 16x16 favicon). - r.inset(padding, padding); - canvas.drawBitmap(favicon, null, r, p); - i.putExtra(Intent.EXTRA_SHORTCUT_ICON, copy); - } - } - // Do not allow duplicate items - i.putExtra("duplicate", false); - return i; + Bitmap favicon = getFavicon(position); + return BookmarkUtils.createAddToHomeIntent(this, url, title, touchIcon, favicon); } private void saveCurrentPage() { -- cgit v1.2.3