summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorLeon Scroggins <scroggo@google.com>2009-06-18 12:05:28 -0400
committerLeon Scroggins <scroggo@google.com>2009-06-18 17:01:59 -0400
commitb6b7f9ef3b4ed220063f555d8b7c205210a61a04 (patch)
treefeaa09ad4d5310921189e15cf1307091aa8e34b7 /src/com
parent7874657df1a62c8e3b2b9fcc47570333664d6988 (diff)
downloadpackages_apps_browser-b6b7f9ef3b4ed220063f555d8b7c205210a61a04.zip
packages_apps_browser-b6b7f9ef3b4ed220063f555d8b7c205210a61a04.tar.gz
packages_apps_browser-b6b7f9ef3b4ed220063f555d8b7c205210a61a04.tar.bz2
Use a grid view for bookmarks page.
The BrowserProvider now stores another blob for a screenshot of the page. If the current page is a bookmark, store a screenshot. When viewing bookmarks, show a gridview of screenshots of the bookmarks. Requires a change to framework to add THUMBNAIL to Browser.BookmarkColumns and to the HISTORY_PROJECTION
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/browser/BookmarkGridPage.java243
-rw-r--r--src/com/android/browser/BrowserActivity.java43
-rw-r--r--src/com/android/browser/BrowserProvider.java11
-rw-r--r--src/com/android/browser/CombinedBookmarkHistoryActivity.java2
4 files changed, 295 insertions, 4 deletions
diff --git a/src/com/android/browser/BookmarkGridPage.java b/src/com/android/browser/BookmarkGridPage.java
new file mode 100644
index 0000000..a9db7ac
--- /dev/null
+++ b/src/com/android/browser/BookmarkGridPage.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2009 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.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.ContentObserver;
+import android.database.DataSetObserver;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.Browser;
+import android.provider.Browser.BookmarkColumns;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.GridView;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+public class BookmarkGridPage extends Activity {
+ private final static int SPACING = 10;
+ private BookmarkGrid mGridView;
+ private BookmarkGridAdapter mAdapter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mGridView = new BookmarkGrid(this);
+ mGridView.setNumColumns(3);
+ mAdapter = new BookmarkGridAdapter(this);
+ mGridView.setAdapter(mAdapter);
+ mGridView.setFocusable(true);
+ mGridView.setFocusableInTouchMode(true);
+ mGridView.setSelector(android.R.drawable.gallery_thumb);
+ mGridView.setVerticalSpacing(SPACING);
+ mGridView.setHorizontalSpacing(SPACING);
+ setContentView(mGridView);
+ mGridView.requestFocus();
+ }
+
+ private class BookmarkGrid extends GridView {
+ public BookmarkGrid(Context context) {
+ super(context);
+ }
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ int thumbHeight = (h - 2 * (SPACING + getListPaddingTop()
+ + getListPaddingBottom())) / 3;
+ mAdapter.heightChanged(thumbHeight);
+ super.onSizeChanged(w, h, oldw, oldh);
+ }
+ }
+
+ private class BookmarkGridAdapter implements ListAdapter {
+ private ArrayList<DataSetObserver> mDataObservers;
+ private Context mContext; // Context to use to inflate views
+ private Cursor mCursor;
+ private int mThumbHeight;
+
+ public BookmarkGridAdapter(Context context) {
+ mContext = context;
+ mDataObservers = new ArrayList<DataSetObserver>();
+ String whereClause = Browser.BookmarkColumns.BOOKMARK + " != 0";
+ String orderBy = Browser.BookmarkColumns.VISITS + " DESC";
+ mCursor = managedQuery(Browser.BOOKMARKS_URI,
+ Browser.HISTORY_PROJECTION, whereClause, null, orderBy);
+ mCursor.registerContentObserver(new ChangeObserver());
+ mGridView.setOnItemClickListener(
+ new AdapterView.OnItemClickListener() {
+ public void onItemClick(AdapterView parent, View v,
+ int position, long id) {
+ mCursor.moveToPosition(position);
+ String url = mCursor.getString(
+ Browser.HISTORY_PROJECTION_URL_INDEX);
+ Intent intent = (new Intent()).setAction(url);
+ getParent().setResult(RESULT_OK, intent);
+ finish();
+ }});
+ }
+
+ void heightChanged(int newHeight) {
+ mThumbHeight = newHeight;
+ }
+
+ private class ChangeObserver extends ContentObserver {
+ public ChangeObserver() {
+ super(new Handler());
+ }
+
+ @Override
+ public boolean deliverSelfNotifications() {
+ return true;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ BookmarkGridAdapter.this.refreshData();
+ }
+ }
+
+ void refreshData() {
+ mCursor.requery();
+ for (DataSetObserver o : mDataObservers) {
+ o.onChanged();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see android.widget.ListAdapter#areAllItemsSelectable()
+ */
+ public boolean areAllItemsEnabled() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see android.widget.ListAdapter#isSelectable(int)
+ */
+ public boolean isEnabled(int position) {
+ if (position >= 0 && position < mCursor.getCount()) {
+ return true;
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see android.widget.Adapter#getCount()
+ */
+ public int getCount() {
+ return mCursor.getCount();
+ }
+
+ /* (non-Javadoc)
+ * @see android.widget.Adapter#getItem(int)
+ */
+ public Object getItem(int position) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see android.widget.Adapter#getItemId(int)
+ */
+ public long getItemId(int position) {
+ return position;
+ }
+
+ /* (non-Javadoc)
+ * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
+ */
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = null;
+ if (convertView != null) {
+ v = convertView;
+ } else {
+ LayoutInflater factory = LayoutInflater.from(mContext);
+ v = factory.inflate(R.layout.bookmark_thumbnail, null);
+ }
+ ImageView thumb = (ImageView) v.findViewById(R.id.thumb);
+ TextView tv = (TextView) v.findViewById(R.id.label);
+
+ mCursor.moveToPosition(position);
+ tv.setText(mCursor.getString(
+ Browser.HISTORY_PROJECTION_TITLE_INDEX));
+ byte[] data = mCursor.getBlob(
+ Browser.HISTORY_PROJECTION_THUMBNAIL_INDEX);
+ if (data == null) {
+ // Backup is to show the favicon
+ data = mCursor.getBlob(
+ Browser.HISTORY_PROJECTION_FAVICON_INDEX);
+ thumb.setScaleType(ImageView.ScaleType.CENTER);
+ } else {
+ thumb.setScaleType(ImageView.ScaleType.FIT_XY);
+ }
+ if (data != null) {
+ thumb.setImageBitmap(
+ BitmapFactory.decodeByteArray(data, 0, data.length));
+ } else {
+ thumb.setImageResource(R.drawable.app_web_browser_sm);
+ thumb.setScaleType(ImageView.ScaleType.CENTER);
+ }
+ ViewGroup.LayoutParams lp = thumb.getLayoutParams();
+ if (lp.height != mThumbHeight) {
+ lp.height = mThumbHeight;
+ thumb.requestLayout();
+ }
+ return v;
+ }
+
+ /* (non-Javadoc)
+ * @see android.widget.Adapter#registerDataSetObserver(android.database.DataSetObserver)
+ */
+ public void registerDataSetObserver(DataSetObserver observer) {
+ mDataObservers.add(observer);
+ }
+
+ /* (non-Javadoc)
+ * @see android.widget.Adapter#hasStableIds()
+ */
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see android.widget.Adapter#unregisterDataSetObserver(android.database.DataSetObserver)
+ */
+ public void unregisterDataSetObserver(DataSetObserver observer) {
+ mDataObservers.remove(observer);
+ }
+
+ public int getItemViewType(int position) {
+ return 0;
+ }
+
+ public int getViewTypeCount() {
+ return 1;
+ }
+
+ public boolean isEmpty() {
+ return getCount() == 0;
+ }
+ }
+}
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 363c6d7..d1d8d15 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -29,6 +29,7 @@ import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
@@ -130,6 +131,7 @@ import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -2989,6 +2991,47 @@ public class BrowserActivity extends Activity
// Update the lock icon image only once we are done loading
updateLockIconImage(mLockIconType);
+ // If this is a bookmarked site, add a screenshot to the database.
+ // FIXME: When should we update? Every time?
+ if (url != null) {
+ // copied from BrowserBookmarksAdapter
+ int query = url.indexOf('?');
+ String noQuery = url;
+ if (query != -1) {
+ noQuery = url.substring(0, query);
+ }
+ String URL = noQuery + '?';
+ String[] selArgs = new String[] { noQuery, URL };
+ final String where = "(url == ? OR url GLOB ? || '*') AND bookmark == 1";
+ final String[] projection = new String[] { Browser.BookmarkColumns._ID };
+ ContentResolver cr = getContentResolver();
+ final Cursor c = cr.query(Browser.BOOKMARKS_URI, projection, where, selArgs, null);
+ boolean succeed = c.moveToFirst();
+ ContentValues values = null;
+ while (succeed) {
+ if (values == null) {
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ Picture thumbnail = view.capturePicture();
+ // Height was arbitrarily chosen
+ Bitmap bm = Bitmap.createBitmap(100, 100,
+ Bitmap.Config.ARGB_4444);
+ Canvas canvas = new Canvas(bm);
+ // Scale chosen to be about one third, since we want
+ // roughly three rows/columns for bookmark page
+ canvas.scale(.3f, .3f);
+ thumbnail.draw(canvas);
+ bm.compress(Bitmap.CompressFormat.PNG, 100, os);
+ values = new ContentValues();
+ values.put(Browser.BookmarkColumns.THUMBNAIL,
+ os.toByteArray());
+ }
+ cr.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
+ c.getInt(0)), values, null, null);
+ succeed = c.moveToNext();
+ }
+ c.close();
+ }
+
// Performance probe
if (false) {
long[] sysCpu = new long[7];
diff --git a/src/com/android/browser/BrowserProvider.java b/src/com/android/browser/BrowserProvider.java
index 8743254..a3f249b 100644
--- a/src/com/android/browser/BrowserProvider.java
+++ b/src/com/android/browser/BrowserProvider.java
@@ -145,7 +145,8 @@ public class BrowserProvider extends ContentProvider {
// 15 -> 17 Set it up for the SearchManager
// 17 -> 18 Added favicon in bookmarks table for Home shortcuts
// 18 -> 19 Remove labels table
- private static final int DATABASE_VERSION = 19;
+ // 19 -> 20 Added thumbnail
+ private static final int DATABASE_VERSION = 20;
// Regular expression which matches http://, followed by some stuff, followed by
// optionally a trailing slash, all matched as separate groups.
@@ -214,7 +215,8 @@ public class BrowserProvider extends ContentProvider {
"created LONG," +
"description TEXT," +
"bookmark INTEGER," +
- "favicon BLOB DEFAULT NULL" +
+ "favicon BLOB DEFAULT NULL," +
+ "thumbnail BLOB DEFAULT NULL" +
");");
final CharSequence[] bookmarks = mContext.getResources()
@@ -241,9 +243,12 @@ public class BrowserProvider extends ContentProvider {
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
- + newVersion + ", which will destroy all old data");
+ + newVersion);
if (oldVersion == 18) {
db.execSQL("DROP TABLE IF EXISTS labels");
+ }
+ if (oldVersion <= 19) {
+ db.execSQL("ALTER TABLE bookmarks ADD COLUMN thumbnail BLOB DEFAULT NULL;");
} else {
db.execSQL("DROP TABLE IF EXISTS bookmarks");
db.execSQL("DROP TABLE IF EXISTS searches");
diff --git a/src/com/android/browser/CombinedBookmarkHistoryActivity.java b/src/com/android/browser/CombinedBookmarkHistoryActivity.java
index 963f179..6926c8f 100644
--- a/src/com/android/browser/CombinedBookmarkHistoryActivity.java
+++ b/src/com/android/browser/CombinedBookmarkHistoryActivity.java
@@ -84,7 +84,7 @@ public class CombinedBookmarkHistoryActivity extends TabActivity
Resources resources = getResources();
getIconListenerSet(getContentResolver());
- Intent bookmarksIntent = new Intent(this, BrowserBookmarksPage.class);
+ Intent bookmarksIntent = new Intent(this, BookmarkGridPage.class);
bookmarksIntent.putExtras(extras);
tabHost.addTab(tabHost.newTabSpec(BOOKMARKS_TAB)
.setIndicator(resources.getString(R.string.tab_bookmarks),