summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Hamilton <jham@android.com>2010-08-17 11:13:53 -0500
committerJeff Hamilton <jham@android.com>2010-08-18 14:06:12 -0500
commit8ce956c6076a89aae85856f35b94bad7fc8fa1f1 (patch)
treeca6d690359a55fc4a7489f20c67a5168389c8dc9
parent8e4fbf1b26c2cc05a56ba2d4e7d1eda7d1574e91 (diff)
downloadandroid_packages_apps_Gello-8ce956c6076a89aae85856f35b94bad7fc8fa1f1.tar.gz
android_packages_apps_Gello-8ce956c6076a89aae85856f35b94bad7fc8fa1f1.tar.bz2
android_packages_apps_Gello-8ce956c6076a89aae85856f35b94bad7fc8fa1f1.zip
Switch the history management over to the new provider.
Also fix up a bunch of bugs causing things like thumbnails to not be stored properly. Change-Id: I5758ee108734d9b50e741822dcbe86b7cc834e8e
-rw-r--r--src/com/android/browser/Bookmarks.java69
-rw-r--r--src/com/android/browser/BrowserActivity.java7
-rw-r--r--src/com/android/browser/BrowserBookmarksPage.java9
-rw-r--r--src/com/android/browser/BrowserDownloadAdapter.java7
-rw-r--r--src/com/android/browser/BrowserDownloadPage.java13
-rw-r--r--src/com/android/browser/BrowserHistoryPage.java210
-rw-r--r--src/com/android/browser/DateSortedExpandableListAdapter.java117
-rw-r--r--src/com/android/browser/DownloadTouchIcon.java24
-rw-r--r--src/com/android/browser/Tab.java38
-rw-r--r--src/com/android/browser/provider/BrowserProvider2.java46
10 files changed, 278 insertions, 262 deletions
diff --git a/src/com/android/browser/Bookmarks.java b/src/com/android/browser/Bookmarks.java
index 62ed7e36..3ead2034 100644
--- a/src/com/android/browser/Bookmarks.java
+++ b/src/com/android/browser/Bookmarks.java
@@ -24,8 +24,6 @@ import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
-import android.provider.Browser;
-import android.provider.Browser.BookmarkColumns;
import android.provider.BrowserContract;
import android.util.Log;
import android.webkit.WebIconDatabase;
@@ -103,40 +101,26 @@ import java.io.ByteArrayOutputStream;
ContentResolver cr, String url, String title) {
Cursor cursor = null;
try {
- cursor = cr.query(
- Browser.BOOKMARKS_URI,
- Browser.HISTORY_PROJECTION,
- "url = ? AND title = ?",
+ cursor = cr.query(BrowserContract.Bookmarks.CONTENT_URI,
+ new String[] { BrowserContract.Bookmarks._ID },
+ BrowserContract.Bookmarks.URL + " = ? AND " +
+ BrowserContract.Bookmarks.TITLE + " = ?",
new String[] { url, title },
null);
- boolean first = cursor.moveToFirst();
+
// Should be in the database no matter what
- if (!first) {
+ if (!cursor.moveToFirst()) {
throw new AssertionError("URL is not in the database! " + url
+ " " + title);
}
+
// Remove from bookmarks
WebIconDatabase.getInstance().releaseIconForPageUrl(url);
- Uri uri = ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
- cursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX));
- int numVisits = cursor.getInt(
- Browser.HISTORY_PROJECTION_VISITS_INDEX);
- if (0 == numVisits) {
- cr.delete(uri, null, null);
- } else {
- // It is no longer a bookmark, but it is still a visited
- // site.
- ContentValues values = new ContentValues();
- values.put(Browser.BookmarkColumns.BOOKMARK, 0);
- try {
- cr.update(uri, values, null, null);
- } catch (IllegalStateException e) {
- Log.e("removeFromBookmarks", "no database!");
- }
- }
+ Uri uri = ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI,
+ cursor.getLong(0));
+ cr.delete(uri, null, null);
if (context != null) {
- Toast.makeText(context, R.string.removed_from_bookmarks,
- Toast.LENGTH_LONG).show();
+ Toast.makeText(context, R.string.removed_from_bookmarks, Toast.LENGTH_LONG).show();
}
} catch (IllegalStateException e) {
Log.e(LOGTAG, "removeFromBookmarks", e);
@@ -168,8 +152,15 @@ import java.io.ByteArrayOutputStream;
return false;
}
+ static final String QUERY_BOOKMARKS_WHERE =
+ BrowserContract.Bookmarks.IS_FOLDER + " == 0 AND (" +
+ BrowserContract.Bookmarks.URL + " == ? OR " +
+ BrowserContract.Bookmarks.URL + " == ? OR " +
+ BrowserContract.Bookmarks.URL + " LIKE ? || '%' OR " +
+ BrowserContract.Bookmarks.URL + " LIKE ? || '%')";
+
/* package */ static Cursor queryBookmarksForUrl(ContentResolver cr,
- String originalUrl, String url, boolean onlyBookmarks) {
+ String originalUrl, String url) {
if (cr == null || url == null) {
return null;
}
@@ -192,18 +183,10 @@ import java.io.ByteArrayOutputStream;
// http://www.google.com/m, search for
// http://www.google.com/m?some_query)
final String[] selArgs = new String[] {
- originalUrlNoQuery, urlNoQuery, originalUrl, url };
- String where = BookmarkColumns.URL + " == ? OR "
- + BookmarkColumns.URL + " == ? OR "
- + BookmarkColumns.URL + " LIKE ? || '%' OR "
- + BookmarkColumns.URL + " LIKE ? || '%'";
- if (onlyBookmarks) {
- where = "(" + where + ") AND " + BookmarkColumns.BOOKMARK + " == 1";
- }
- final String[] projection =
- new String[] { Browser.BookmarkColumns._ID };
- return cr.query(Browser.BOOKMARKS_URI, projection, where, selArgs,
- null);
+ originalUrlNoQuery, urlNoQuery, originalUrl, url };
+ final String[] projection = new String[] { BrowserContract.Bookmarks._ID };
+ return cr.query(BrowserContract.Bookmarks.CONTENT_URI, projection, QUERY_BOOKMARKS_WHERE,
+ selArgs, null);
}
// Strip the query from the given url.
@@ -233,7 +216,7 @@ import java.io.ByteArrayOutputStream;
@Override
protected Void doInBackground(Void... unused) {
final Cursor c =
- Bookmarks.queryBookmarksForUrl(cr, originalUrl, url, true);
+ Bookmarks.queryBookmarksForUrl(cr, originalUrl, url);
if (c == null) {
return null;
}
@@ -242,11 +225,11 @@ import java.io.ByteArrayOutputStream;
final ByteArrayOutputStream os =
new ByteArrayOutputStream();
favicon.compress(Bitmap.CompressFormat.PNG, 100, os);
- values.put(Browser.BookmarkColumns.FAVICON,
+ values.put(BrowserContract.Bookmarks.FAVICON,
os.toByteArray());
do {
cr.update(ContentUris.withAppendedId(
- Browser.BOOKMARKS_URI, c.getInt(0)),
+ BrowserContract.Bookmarks.CONTENT_URI, c.getLong(0)),
values, null, null);
} while (c.moveToNext());
}
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 36be5e4b..99bf0174 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -62,6 +62,7 @@ import android.os.PowerManager;
import android.os.Process;
import android.os.SystemClock;
import android.provider.Browser;
+import android.provider.BrowserContract;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Intents.Insert;
import android.provider.Downloads;
@@ -2506,18 +2507,18 @@ public class BrowserActivity extends Activity
Cursor c = null;
try {
c = Bookmarks.queryBookmarksForUrl(
- cr, originalUrl, url, true);
+ cr, originalUrl, url);
if (c != null) {
if (c.moveToFirst()) {
ContentValues values = new ContentValues();
final ByteArrayOutputStream os
= new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, os);
- values.put(Browser.BookmarkColumns.THUMBNAIL,
+ values.put(BrowserContract.Bookmarks.THUMBNAIL,
os.toByteArray());
do {
cr.update(ContentUris.withAppendedId(
- Browser.BOOKMARKS_URI, c.getInt(0)),
+ BrowserContract.Bookmarks.CONTENT_URI, c.getLong(0)),
values, null, null);
} while (c.moveToNext());
}
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index 6a51b987..a01f6fa9 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -386,7 +386,7 @@ public class BrowserBookmarksPage extends Activity implements View.OnCreateConte
public void updateRow(Bundle map) {
// Find the record
- int id = map.getInt("id");
+ long id = map.getLong("id");
int position = -1;
Cursor cursor = mAdapter.getCursor();
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
@@ -411,12 +411,13 @@ public class BrowserBookmarksPage extends Activity implements View.OnCreateConte
}
if (map.getBoolean("invalidateThumbnail") == true) {
- values.put(Browser.BookmarkColumns.THUMBNAIL, new byte[0]);
+ values.putNull(Browser.BookmarkColumns.THUMBNAIL);
}
if (values.size() > 0) {
- getContentResolver().update(Browser.BOOKMARKS_URI, values,
- "_id = ?", new String[] { Integer.toString(id) });
+ getContentResolver().update(
+ ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id),
+ values, null, null);
}
}
diff --git a/src/com/android/browser/BrowserDownloadAdapter.java b/src/com/android/browser/BrowserDownloadAdapter.java
index f22c9fe6..6f498b69 100644
--- a/src/com/android/browser/BrowserDownloadAdapter.java
+++ b/src/com/android/browser/BrowserDownloadAdapter.java
@@ -26,7 +26,6 @@ import android.database.Cursor;
import android.drm.mobile1.DrmRawContent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
-import android.os.Handler;
import android.provider.Downloads;
import android.text.format.Formatter;
import android.view.LayoutInflater;
@@ -56,9 +55,9 @@ public class BrowserDownloadAdapter extends DateSortedExpandableListAdapter {
private int mMimetypeColumnId;
private int mDateColumnId;
- public BrowserDownloadAdapter(Context context, Cursor c, int index,
- Handler handler) {
- super(context, c, index, handler);
+ public BrowserDownloadAdapter(Context context, Cursor c, int index) {
+ super(context, index);
+ changeCursor(c);
mTitleColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_TITLE);
mDescColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_DESCRIPTION);
mStatusColumnId = c.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS);
diff --git a/src/com/android/browser/BrowserDownloadPage.java b/src/com/android/browser/BrowserDownloadPage.java
index bbf1191b..a897f993 100644
--- a/src/com/android/browser/BrowserDownloadPage.java
+++ b/src/com/android/browser/BrowserDownloadPage.java
@@ -18,13 +18,10 @@ package com.android.browser;
import android.app.AlertDialog;
import android.app.ExpandableListActivity;
-import android.content.ActivityNotFoundException;
+import android.content.ContentUris;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.ContentUris;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
@@ -34,17 +31,13 @@ import android.provider.Downloads;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
import android.view.Menu;
-import android.view.MenuItem;
import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.AdapterView;
import android.widget.ExpandableListView;
import java.io.File;
-import java.util.List;
/**
* View showing the user's current browser downloads
@@ -100,7 +93,7 @@ public class BrowserDownloadPage extends ExpandableListActivity {
// Create a list "controller" for the data
mDownloadAdapter = new BrowserDownloadAdapter(this,
mDownloadCursor, mDownloadCursor.getColumnIndexOrThrow(
- Downloads.Impl.COLUMN_LAST_MODIFICATION), mHandler);
+ Downloads.Impl.COLUMN_LAST_MODIFICATION));
setListAdapter(mDownloadAdapter);
mListView.setOnCreateContextMenuListener(this);
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 5298b9a9..8116b97d 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -18,33 +18,30 @@ package com.android.browser;
import android.app.Activity;
import android.app.ExpandableListActivity;
+import android.app.LoaderManager.LoaderCallbacks;
import android.content.ClipboardManager;
import android.content.Context;
+import android.content.CursorLoader;
import android.content.Intent;
+import android.content.Loader;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.os.AsyncTask;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.ServiceManager;
import android.provider.Browser;
import android.provider.BrowserContract.History;
-import android.util.Log;
import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
-import android.view.ContextMenu.ContextMenuInfo;
import android.view.ViewStub;
import android.webkit.WebIconDatabase.IconListener;
-import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.Toast;
@@ -53,21 +50,41 @@ import android.widget.Toast;
* Activity for displaying the browser's history, divided into
* days of viewing.
*/
-public class BrowserHistoryPage extends ExpandableListActivity {
- private HistoryAdapter mAdapter;
- private boolean mDisableNewWindow;
- private HistoryItem mContextHeader;
+public class BrowserHistoryPage extends ExpandableListActivity
+ implements LoaderCallbacks<Cursor> {
+
+ static final int LOADER_HISTORY = 1;
- private final static String LOGTAG = "browser";
+ HistoryAdapter mAdapter;
+ boolean mDisableNewWindow;
+ HistoryItem mContextHeader;
// Implementation of WebIconDatabase.IconListener
- private class IconReceiver implements IconListener {
+ class IconReceiver implements IconListener {
+ @Override
public void onReceivedIcon(String url, Bitmap icon) {
- setListAdapter(mAdapter);
+ mAdapter.notifyDataSetChanged();
}
}
+
// Instance of IconReceiver
- private final IconReceiver mIconReceiver = new IconReceiver();
+ final IconReceiver mIconReceiver = new IconReceiver();
+
+ static interface HistoryQuery {
+ static final String[] PROJECTION = new String[] {
+ History._ID, // 0
+ History.DATE_LAST_VISITED, // 1
+ History.TITLE, // 2
+ History.URL, // 3
+ History.FAVICON, // 4
+ };
+
+ static final int INDEX_ID = 0;
+ static final int INDEX_DATE_LAST_VISITED = 1;
+ static final int INDEX_TITE = 2;
+ static final int INDEX_URL = 3;
+ static final int INDEX_FAVICON = 4;
+ }
/**
* Report back to the calling activity to load a site.
@@ -90,81 +107,73 @@ public class BrowserHistoryPage extends ExpandableListActivity {
cm.setText(text);
}
- private static final int ADAPTER_CREATED = 1000;
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case ADAPTER_CREATED:
- mAdapter = (HistoryAdapter) msg.obj;
- setListAdapter(mAdapter);
- final ExpandableListView list = getExpandableListView();
- // Add an empty view late, so it does not claim an empty
- // history before the adapter is present
- View v = new ViewStub(BrowserHistoryPage.this,
- R.layout.empty_history);
- addContentView(v, new LayoutParams(
- LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
- list.setEmptyView(v);
- list.setOnCreateContextMenuListener(
- BrowserHistoryPage.this);
- // Do not post the runnable if there is nothing in the list.
- if (list.getExpandableListAdapter().getGroupCount() > 0) {
- list.post(new Runnable() {
- public void run() {
- // In case the history gets cleared before this
- // event happens
- if (list.getExpandableListAdapter()
- .getGroupCount() > 0) {
- list.expandGroup(0);
- }
- }
- });
- }
- break;
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ switch (id) {
+ case LOADER_HISTORY: {
+ CursorLoader loader = new CursorLoader(this, History.CONTENT_URI,
+ HistoryQuery.PROJECTION, null, null, null);
+ return loader;
+ }
+
+ default: {
+ throw new IllegalArgumentException();
}
}
- };
+ }
@Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ switch (loader.getId()) {
+ case LOADER_HISTORY: {
+ mAdapter.changeCursor(data);
+
+ // Add an empty view late, so it does not claim an empty
+ // history before the adapter is present
+ final ExpandableListView list = getExpandableListView();
+ View v = new ViewStub(this, R.layout.empty_history);
+ addContentView(v, new LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT));
+ list.setEmptyView(v);
+
+ // Do not post the runnable if there is nothing in the list.
+ if (list.getExpandableListAdapter().getGroupCount() > 0) {
+ list.post(new Runnable() {
+ @Override
+ public void run() {
+ // In case the history gets cleared before this
+ // event happens
+ if (list.getExpandableListAdapter()
+ .getGroupCount() > 0) {
+ list.expandGroup(0);
+ }
+ }
+ });
+ }
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ @Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setTitle(R.string.browser_history);
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... unused) {
- final String whereClause = Browser.BookmarkColumns.VISITS
- + " > 0"
- // In AddBookmarkPage, where we save new bookmarks, we
- // add three visits to newly created bookmarks, so that
- // bookmarks that have not been visited will show up in
- // the most visited, and higher in the goto search box.
- // However, this puts the site in the history, unless
- // we ignore sites with a DATE of 0, which the next
- // line does.
- + " AND " + Browser.BookmarkColumns.DATE + " > 0";
- final String orderBy = Browser.BookmarkColumns.DATE + " DESC";
-
- Cursor cursor = managedQuery(
- Browser.BOOKMARKS_URI,
- Browser.HISTORY_PROJECTION,
- whereClause, null, orderBy);
-
- HistoryAdapter adapter = new HistoryAdapter(
- BrowserHistoryPage.this, cursor,
- Browser.HISTORY_PROJECTION_DATE_INDEX, mHandler);
- mHandler.obtainMessage(ADAPTER_CREATED, adapter).sendToTarget();
- return null;
- }
- }.execute();
- mDisableNewWindow = getIntent().getBooleanExtra("disable_new_window",
- false);
+ getExpandableListView().setOnCreateContextMenuListener(this);
+
+ mAdapter = new HistoryAdapter(this);
+ setListAdapter(mAdapter);
+
+ mDisableNewWindow = getIntent().getBooleanExtra("disable_new_window", false);
// Register to receive icons in case they haven't all been loaded.
- CombinedBookmarkHistoryActivity.getIconListenerSet()
- .addListener(mIconReceiver);
+ CombinedBookmarkHistoryActivity.getIconListenerSet().addListener(mIconReceiver);
Activity parent = getParent();
if (null == parent
@@ -172,14 +181,17 @@ public class BrowserHistoryPage extends ExpandableListActivity {
throw new AssertionError("history page can only be viewed as a tab"
+ "in CombinedBookmarkHistoryActivity");
}
+
// initialize the result to canceled, so that if the user just presses
// back then it will have the correct result
setResultToParent(RESULT_CANCELED, null);
+
+ // Start the loader
+ getLoaderManager().initLoader(LOADER_HISTORY, null, this);
}
@Override
protected void onDestroy() {
- mHandler.removeCallbacksAndMessages(null);
super.onDestroy();
CombinedBookmarkHistoryActivity.getIconListenerSet()
.removeListener(mIconReceiver);
@@ -195,7 +207,8 @@ public class BrowserHistoryPage extends ExpandableListActivity {
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
- menu.findItem(R.id.clear_history_menu_id).setVisible(Browser.canClearHistory(this.getContentResolver()));
+ menu.findItem(R.id.clear_history_menu_id).setVisible(
+ Browser.canClearHistory(this.getContentResolver()));
return true;
}
@@ -208,7 +221,6 @@ public class BrowserHistoryPage extends ExpandableListActivity {
// CombinedBookmarkHistoryActivity
((CombinedBookmarkHistoryActivity) getParent())
.removeParentChildRelationShips();
- if (mAdapter != null) mAdapter.refreshData();
return true;
default:
@@ -292,7 +304,6 @@ public class BrowserHistoryPage extends ExpandableListActivity {
return true;
case R.id.delete_context_menu_id:
Browser.deleteFromHistory(getContentResolver(), url);
- if (mAdapter != null) mAdapter.refreshData();
return true;
case R.id.homepage_context_menu_id:
BrowserSettings.getInstance().setHomePage(this, url);
@@ -304,12 +315,12 @@ public class BrowserHistoryPage extends ExpandableListActivity {
}
return super.onContextItemSelected(item);
}
-
+
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
- if (v instanceof HistoryItem) {
- loadUrl(((HistoryItem) v).getUrl(), false);
+ if (v instanceof BookmarkItem) {
+ loadUrl(((BookmarkItem) v).getUrl(), false);
return true;
}
return false;
@@ -324,17 +335,16 @@ public class BrowserHistoryPage extends ExpandableListActivity {
}
private class HistoryAdapter extends DateSortedExpandableListAdapter {
- HistoryAdapter(Context context, Cursor cursor, int index,
- Handler handler) {
- super(context, cursor, index, handler);
-
+ HistoryAdapter(Context context) {
+ super(context, HistoryQuery.INDEX_DATE_LAST_VISITED);
}
+ @Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
- HistoryItem item;
- if (null == convertView || !(convertView instanceof HistoryItem)) {
- item = new HistoryItem(BrowserHistoryPage.this);
+ BookmarkItem item;
+ if (null == convertView || !(convertView instanceof BookmarkItem)) {
+ item = new BookmarkItem(BrowserHistoryPage.this);
// Add padding on the left so it will be indented from the
// arrows on the group views.
item.setPadding(item.getPaddingLeft() + 10,
@@ -342,16 +352,18 @@ public class BrowserHistoryPage extends ExpandableListActivity {
item.getPaddingRight(),
item.getPaddingBottom());
} else {
- item = (HistoryItem) convertView;
+ item = (BookmarkItem) convertView;
}
+
// Bail early if the Cursor is closed.
if (!moveCursorToChildPosition(groupPosition, childPosition)) {
return item;
}
- item.setName(getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
- String url = getString(Browser.HISTORY_PROJECTION_URL_INDEX);
+
+ item.setName(getString(HistoryQuery.INDEX_TITE));
+ String url = getString(HistoryQuery.INDEX_URL);
item.setUrl(url);
- byte[] data = getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX);
+ byte[] data = getBlob(HistoryQuery.INDEX_FAVICON);
if (data != null) {
item.setFavicon(BitmapFactory.decodeByteArray(data, 0,
data.length));
@@ -359,8 +371,6 @@ public class BrowserHistoryPage extends ExpandableListActivity {
item.setFavicon(CombinedBookmarkHistoryActivity
.getIconListenerSet().getFavicon(url));
}
- item.setIsBookmark(1 ==
- getInt(Browser.HISTORY_PROJECTION_BOOKMARK_INDEX));
return item;
}
}
diff --git a/src/com/android/browser/DateSortedExpandableListAdapter.java b/src/com/android/browser/DateSortedExpandableListAdapter.java
index f8261d83..a48efe67 100644
--- a/src/com/android/browser/DateSortedExpandableListAdapter.java
+++ b/src/com/android/browser/DateSortedExpandableListAdapter.java
@@ -17,65 +17,55 @@
package com.android.browser;
import android.content.Context;
-import android.database.ContentObserver;
import android.database.Cursor;
import android.database.DataSetObserver;
-import android.os.Handler;
-import android.provider.BaseColumns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.DateSorter;
-import android.widget.ExpandableListAdapter;
+import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.TextView;
-import java.util.Vector;
-
/**
* ExpandableListAdapter which separates data into categories based on date.
* Used for History and Downloads.
*/
-public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
+public class DateSortedExpandableListAdapter extends BaseExpandableListAdapter {
// Array for each of our bins. Each entry represents how many items are
// in that bin.
private int mItemMap[];
// This is our GroupCount. We will have at most DateSorter.DAY_COUNT
// bins, less if the user has no items in one or more bins.
private int mNumberOfBins;
- private Vector<DataSetObserver> mObservers;
private Cursor mCursor;
private DateSorter mDateSorter;
private int mDateIndex;
private int mIdIndex;
private Context mContext;
- private class ChangeObserver extends ContentObserver {
- public ChangeObserver(Handler handler) {
- super(handler);
- }
+ boolean mDataValid;
+ DataSetObserver mDataSetObserver = new DataSetObserver() {
@Override
- public boolean deliverSelfNotifications() {
- return true;
+ public void onChanged() {
+ mDataValid = true;
+ notifyDataSetChanged();
}
@Override
- public void onChange(boolean selfChange) {
- refreshData();
+ public void onInvalidated() {
+ mDataValid = false;
+ notifyDataSetInvalidated();
}
- }
-
- public DateSortedExpandableListAdapter(Context context, Cursor cursor,
- int dateIndex, Handler handler) {
+ };
+
+ public DateSortedExpandableListAdapter(Context context, int dateIndex) {
mContext = context;
mDateSorter = new DateSorter(context);
- mObservers = new Vector<DataSetObserver>();
- mCursor = cursor;
- mIdIndex = cursor.getColumnIndexOrThrow(BaseColumns._ID);
- cursor.registerContentObserver(new ChangeObserver(handler));
mDateIndex = dateIndex;
- buildMap();
+ mDataValid = false;
+ mIdIndex = -1;
}
/**
@@ -122,6 +112,7 @@ public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
* @return corresponding byte array from the Cursor.
*/
/* package */ byte[] getBlob(int cursorIndex) {
+ if (!mDataValid) return null;
return mCursor.getBlob(cursorIndex);
}
@@ -138,6 +129,7 @@ public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
* @return corresponding integer from the Cursor.
*/
/* package */ int getInt(int cursorIndex) {
+ if (!mDataValid) return 0;
return mCursor.getInt(cursorIndex);
}
@@ -146,6 +138,7 @@ public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
* already been moved to the correct position.
*/
/* package */ long getLong(int cursorIndex) {
+ if (!mDataValid) return 0;
return mCursor.getLong(cursorIndex);
}
@@ -158,6 +151,7 @@ public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
* @return corresponding String from the Cursor.
*/
/* package */ String getString(int cursorIndex) {
+ if (!mDataValid) return null;
return mCursor.getString(cursorIndex);
}
@@ -166,6 +160,7 @@ public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
* @param childId ID of the child view in question.
* @return int Group position of the containing group.
/* package */ int groupFromChildId(long childId) {
+ if (!mDataValid) return -1;
int group = -1;
for (mCursor.moveToFirst(); !mCursor.isAfterLast();
mCursor.moveToNext()) {
@@ -173,11 +168,15 @@ public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
int bin = mDateSorter.getIndex(getLong(mDateIndex));
// bin is the same as the group if the number of bins is the
// same as DateSorter
- if (mDateSorter.DAY_COUNT == mNumberOfBins) return bin;
+ if (DateSorter.DAY_COUNT == mNumberOfBins) {
+ return bin;
+ }
// There are some empty bins. Find the corresponding group.
group = 0;
for (int i = 0; i < bin; i++) {
- if (mItemMap[i] != 0) group++;
+ if (mItemMap[i] != 0) {
+ group++;
+ }
}
break;
}
@@ -193,6 +192,7 @@ public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
* @return The corresponding bin that holds that group.
*/
private int groupPositionToBin(int groupPosition) {
+ if (!mDataValid) return -1;
if (groupPosition < 0 || groupPosition >= DateSorter.DAY_COUNT) {
throw new AssertionError("group position out of range");
}
@@ -241,7 +241,9 @@ public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
*/
/* package */ boolean moveCursorToChildPosition(int groupPosition,
int childPosition) {
- if (mCursor.isClosed()) return false;
+ if (!mDataValid || mCursor.isClosed()) {
+ return false;
+ }
groupPosition = groupPositionToBin(groupPosition);
int index = childPosition;
for (int i = 0; i < groupPosition; i++) {
@@ -250,19 +252,34 @@ public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
return mCursor.moveToPosition(index);
}
- /* package */ void refreshData() {
- if (mCursor.isClosed()) {
+ public void changeCursor(Cursor cursor) {
+ if (cursor == mCursor) {
return;
}
- mCursor.requery();
- buildMap();
- for (DataSetObserver o : mObservers) {
- o.onChanged();
+ if (mCursor != null) {
+ mCursor.unregisterDataSetObserver(mDataSetObserver);
+ mCursor.close();
+ }
+ mCursor = cursor;
+ if (cursor != null) {
+ cursor.registerDataSetObserver(mDataSetObserver);
+ mIdIndex = cursor.getColumnIndexOrThrow("_id");
+ mDataValid = true;
+ buildMap();
+ // notify the observers about the new cursor
+ notifyDataSetChanged();
+ } else {
+ mIdIndex = -1;
+ mDataValid = false;
+ // notify the observers about the lack of a data set
+ notifyDataSetInvalidated();
}
}
+ @Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
+ if (!mDataValid) throw new IllegalStateException("Data is not valid");
TextView item;
if (null == convertView || !(convertView instanceof TextView)) {
LayoutInflater factory = LayoutInflater.from(mContext);
@@ -275,73 +292,87 @@ public class DateSortedExpandableListAdapter implements ExpandableListAdapter {
return item;
}
+ @Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
+ if (!mDataValid) throw new IllegalStateException("Data is not valid");
return null;
}
+ @Override
public boolean areAllItemsEnabled() {
return true;
}
+ @Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
+ @Override
public int getGroupCount() {
+ if (!mDataValid) return 0;
return mNumberOfBins;
}
+ @Override
public int getChildrenCount(int groupPosition) {
+ if (!mDataValid) return 0;
return mItemMap[groupPositionToBin(groupPosition)];
}
+ @Override
public Object getGroup(int groupPosition) {
return null;
}
+ @Override
public Object getChild(int groupPosition, int childPosition) {
return null;
}
+ @Override
public long getGroupId(int groupPosition) {
+ if (!mDataValid) return 0;
return groupPosition;
}
+ @Override
public long getChildId(int groupPosition, int childPosition) {
+ if (!mDataValid) return 0;
if (moveCursorToChildPosition(groupPosition, childPosition)) {
return getLong(mIdIndex);
}
return 0;
}
+ @Override
public boolean hasStableIds() {
return true;
}
- public void registerDataSetObserver(DataSetObserver observer) {
- mObservers.add(observer);
- }
-
- public void unregisterDataSetObserver(DataSetObserver observer) {
- mObservers.remove(observer);
- }
-
+ @Override
public void onGroupExpanded(int groupPosition) {
}
+ @Override
public void onGroupCollapsed(int groupPosition) {
}
+ @Override
public long getCombinedChildId(long groupId, long childId) {
+ if (!mDataValid) return 0;
return childId;
}
+ @Override
public long getCombinedGroupId(long groupId) {
+ if (!mDataValid) return 0;
return groupId;
}
+ @Override
public boolean isEmpty() {
- return mCursor.isClosed() || mCursor.getCount() == 0;
+ return !mDataValid || mCursor == null || mCursor.isClosed() || mCursor.getCount() == 0;
}
}
diff --git a/src/com/android/browser/DownloadTouchIcon.java b/src/com/android/browser/DownloadTouchIcon.java
index 2816f58c..14426837 100644
--- a/src/com/android/browser/DownloadTouchIcon.java
+++ b/src/com/android/browser/DownloadTouchIcon.java
@@ -16,6 +16,13 @@
package com.android.browser;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.params.HttpClientParams;
+import org.apache.http.conn.params.ConnRouteParams;
+
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
@@ -23,21 +30,14 @@ import android.content.ContentValues;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.net.http.AndroidHttpClient;
import android.net.Proxy;
+import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Message;
-import android.provider.Browser;
+import android.provider.BrowserContract;
import android.webkit.WebView;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.params.HttpClientParams;
-import org.apache.http.conn.params.ConnRouteParams;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -102,7 +102,7 @@ class DownloadTouchIcon extends AsyncTask<String, Void, Void> {
public Void doInBackground(String... values) {
if (mContentResolver != null) {
mCursor = Bookmarks.queryBookmarksForUrl(mContentResolver,
- mOriginalUrl, mUrl, true);
+ mOriginalUrl, mUrl);
}
boolean inBookmarksDatabase = mCursor != null && mCursor.getCount() > 0;
@@ -180,13 +180,13 @@ class DownloadTouchIcon extends AsyncTask<String, Void, Void> {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
icon.compress(Bitmap.CompressFormat.PNG, 100, os);
ContentValues values = new ContentValues();
- values.put(Browser.BookmarkColumns.TOUCH_ICON,
+ values.put(BrowserContract.Bookmarks.TOUCH_ICON,
os.toByteArray());
if (mCursor.moveToFirst()) {
do {
mContentResolver.update(ContentUris.withAppendedId(
- Browser.BOOKMARKS_URI, mCursor.getInt(0)),
+ BrowserContract.Bookmarks.CONTENT_URI, mCursor.getLong(0)),
values, null, null);
} while (mCursor.moveToNext());
}
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 9abf32f6..e7309a64 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -16,13 +16,16 @@
package com.android.browser;
+import com.android.browser.TabControl.TabChangeListener;
+import com.android.common.speech.LoggingEvents;
+
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.DialogInterface;
-import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
+import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
@@ -34,14 +37,15 @@ import android.os.Bundle;
import android.os.Message;
import android.os.SystemClock;
import android.provider.Browser;
+import android.provider.BrowserContract.History;
import android.speech.RecognizerResultsIntent;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewStub;
-import android.view.View.OnClickListener;
import android.webkit.ConsoleMessage;
import android.webkit.CookieSyncManager;
import android.webkit.DownloadListener;
@@ -63,10 +67,6 @@ import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
-import com.android.browser.TabControl.TabChangeListener;
-import com.android.common.speech.LoggingEvents;
-
-import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -992,26 +992,12 @@ class Tab {
.replace("_", "\\_");
Cursor c = null;
try {
- final ContentResolver cr
- = mActivity.getContentResolver();
- url = "%" + url;
- String [] selArgs = new String[] { url };
- String where = Browser.BookmarkColumns.URL
- + " LIKE ? ESCAPE '\\' AND "
- + Browser.BookmarkColumns.BOOKMARK + " = 0";
- c = cr.query(Browser.BOOKMARKS_URI, new String[]
- { Browser.BookmarkColumns._ID }, where, selArgs,
- null);
- if (c.moveToFirst()) {
- // Current implementation of database only has one
- // entry per url.
- ContentValues map = new ContentValues();
- map.put(Browser.BookmarkColumns.TITLE, title);
- String[] projection = new String[]
- { Integer.valueOf(c.getInt(0)).toString() };
- cr.update(Browser.BOOKMARKS_URI, map, "_id = ?",
- projection);
- }
+ final ContentResolver cr = mActivity.getContentResolver();
+ String selection = History.URL + " LIKE ? ESCAPE '\\'";
+ String [] selectionArgs = new String[] { "%" + url };
+ ContentValues values = new ContentValues();
+ values.put(History.TITLE, title);
+ cr.update(History.CONTENT_URI, values, selection, selectionArgs);
} catch (IllegalStateException e) {
Log.e(LOGTAG, "Tab onReceived title", e);
} catch (SQLiteException ex) {
diff --git a/src/com/android/browser/provider/BrowserProvider2.java b/src/com/android/browser/provider/BrowserProvider2.java
index 0aae9118..ab24c030 100644
--- a/src/com/android/browser/provider/BrowserProvider2.java
+++ b/src/com/android/browser/provider/BrowserProvider2.java
@@ -51,9 +51,8 @@ public class BrowserProvider2 extends SQLiteContentProvider {
static final String TABLE_SEARCHES = "searches";
static final String TABLE_SYNC_STATE = "syncstate";
- static final String HISTORY_JOIN_BOOKMARKS =
- "history LEFT OUTER JOIN bookmarks ON (history.url = bookmarks.url)";
-
+ static final String DEFAULT_HISTORY_SORT = History.DATE_LAST_VISITED + " DESC";
+
static final int BOOKMARKS = 1000;
static final int BOOKMARKS_ID = 1001;
static final int BOOKMARKS_FOLDER = 1002;
@@ -96,17 +95,13 @@ public class BrowserProvider2 extends SQLiteContentProvider {
matcher.addURI(BrowserContract.AUTHORITY, "syncstate", SYNCSTATE);
matcher.addURI(BrowserContract.AUTHORITY, "syncstate/#", SYNCSTATE_ID);
- // Common BookmarkColumns
- HashMap<String, String> bookmarksColumns = new HashMap();
- bookmarksColumns.put(Bookmarks.TITLE, Bookmarks.TITLE);
- bookmarksColumns.put(Bookmarks.URL, Bookmarks.URL);
- bookmarksColumns.put(Bookmarks.FAVICON, Bookmarks.FAVICON);
- bookmarksColumns.put(Bookmarks.THUMBNAIL, Bookmarks.THUMBNAIL);
- bookmarksColumns.put(Bookmarks.TOUCH_ICON, Bookmarks.TOUCH_ICON);
-
// Bookmarks
HashMap<String, String> map = BOOKMARKS_PROJECTION_MAP;
- map.putAll(bookmarksColumns);
+ map.put(Bookmarks.TITLE, Bookmarks.TITLE);
+ map.put(Bookmarks.URL, Bookmarks.URL);
+ map.put(Bookmarks.FAVICON, Bookmarks.FAVICON);
+ map.put(Bookmarks.THUMBNAIL, Bookmarks.THUMBNAIL);
+ map.put(Bookmarks.TOUCH_ICON, Bookmarks.TOUCH_ICON);
map.put(Bookmarks._ID, TABLE_BOOKMARKS + "._id AS _id");
map.put(Bookmarks.IS_FOLDER, Bookmarks.IS_FOLDER);
map.put(Bookmarks.PARENT, Bookmarks.PARENT);
@@ -130,11 +125,16 @@ public class BrowserProvider2 extends SQLiteContentProvider {
// History
map = HISTORY_PROJECTION_MAP;
- map.putAll(bookmarksColumns);
- map.put(History._ID, TABLE_HISTORY + "._id AS _id");
+ map.put(History._ID, qualifyColumn(TABLE_HISTORY, History._ID));
+ map.put(History.TITLE, Bookmarks.TITLE);
+ map.put(History.URL, Bookmarks.URL);
+ map.put(History.FAVICON, Bookmarks.FAVICON);
+ map.put(History.THUMBNAIL, Bookmarks.THUMBNAIL);
+ map.put(History.TOUCH_ICON, Bookmarks.TOUCH_ICON);
map.put(History.DATE_CREATED, History.DATE_CREATED);
map.put(History.DATE_LAST_VISITED, History.DATE_LAST_VISITED);
map.put(History.VISITS, History.VISITS);
+ map.put(History.USER_ENTERED, History.USER_ENTERED);
// Sync state
map = SYNC_STATE_PROJECTION_MAP;
@@ -144,12 +144,16 @@ public class BrowserProvider2 extends SQLiteContentProvider {
map.put(SyncState.DATA, SyncState.DATA);
}
+ static final String qualifyColumn(String table, String column) {
+ return table + "." + column + " AS " + column;
+ }
+
DatabaseHelper mOpenHelper;
SyncStateContentProviderHelper mSyncHelper = new SyncStateContentProviderHelper();
final class DatabaseHelper extends SQLiteOpenHelper {
static final String DATABASE_NAME = "browser2.db";
- static final int DATABASE_VERSION = 11;
+ static final int DATABASE_VERSION = 15;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@@ -186,10 +190,15 @@ public class BrowserProvider2 extends SQLiteContentProvider {
db.execSQL("CREATE TABLE " + TABLE_HISTORY + "(" +
History._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+ History.TITLE + " TEXT," +
History.URL + " TEXT NOT NULL," +
+ History.FAVICON + " BLOB," +
+ History.THUMBNAIL + " BLOB," +
+ History.TOUCH_ICON + " BLOB," +
History.DATE_CREATED + " INTEGER," +
History.DATE_LAST_VISITED + " INTEGER," +
- History.VISITS + " INTEGER NOT NULL DEFAULT 0" +
+ History.VISITS + " INTEGER NOT NULL DEFAULT 0," +
+ History.USER_ENTERED + " INTEGER" +
");");
db.execSQL("CREATE TABLE " + TABLE_SEARCHES + " (" +
@@ -482,8 +491,11 @@ public class BrowserProvider2 extends SQLiteContentProvider {
// fall through
}
case HISTORY: {
+ if (sortOrder == null) {
+ sortOrder = DEFAULT_HISTORY_SORT;
+ }
qb.setProjectionMap(HISTORY_PROJECTION_MAP);
- qb.setTables(HISTORY_JOIN_BOOKMARKS);
+ qb.setTables(TABLE_HISTORY);
break;
}