diff options
author | Jeff Hamilton <jham@android.com> | 2010-09-15 20:52:00 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-09-15 20:52:00 -0700 |
commit | dc63589e30cfe8f27496a1be3338db95728158de (patch) | |
tree | e201edee724a935f76261b8f6e023e74e08d6593 /src | |
parent | 90500e155cb11ce0e348e8aef2c826790038a13c (diff) | |
parent | 1a805652e389d9404ee0fda7c993a6202332e92b (diff) | |
download | packages_apps_Browser-dc63589e30cfe8f27496a1be3338db95728158de.zip packages_apps_Browser-dc63589e30cfe8f27496a1be3338db95728158de.tar.gz packages_apps_Browser-dc63589e30cfe8f27496a1be3338db95728158de.tar.bz2 |
Merge "A bunch of updates to BrowserProvider2."
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/browser/Bookmarks.java | 61 | ||||
-rw-r--r-- | src/com/android/browser/BookmarksLoader.java | 28 | ||||
-rw-r--r-- | src/com/android/browser/BrowserActivity.java | 33 | ||||
-rw-r--r-- | src/com/android/browser/BrowserBookmarksPage.java | 45 | ||||
-rw-r--r-- | src/com/android/browser/DownloadTouchIcon.java | 26 | ||||
-rw-r--r-- | src/com/android/browser/Tab.java | 4 | ||||
-rw-r--r-- | src/com/android/browser/provider/BrowserProvider2.java | 435 |
7 files changed, 477 insertions, 155 deletions
diff --git a/src/com/android/browser/Bookmarks.java b/src/com/android/browser/Bookmarks.java index 3ead203..532d7c0 100644 --- a/src/com/android/browser/Bookmarks.java +++ b/src/com/android/browser/Bookmarks.java @@ -25,6 +25,8 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.AsyncTask; import android.provider.BrowserContract; +import android.provider.BrowserContract.Combined; +import android.provider.BrowserContract.Images; import android.util.Log; import android.webkit.WebIconDatabase; import android.widget.Toast; @@ -153,13 +155,12 @@ import java.io.ByteArrayOutputStream; } 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 ? || '%')"; + Combined.URL + " == ? OR " + + Combined.URL + " == ? OR " + + Combined.URL + " LIKE ? || '%' OR " + + Combined.URL + " LIKE ? || '%'"; - /* package */ static Cursor queryBookmarksForUrl(ContentResolver cr, + /* package */ static Cursor queryCombinedForUrl(ContentResolver cr, String originalUrl, String url) { if (cr == null || url == null) { return null; @@ -172,8 +173,8 @@ import java.io.ByteArrayOutputStream; // Look for both the original url and the actual url. This takes in to // account redirects. - String originalUrlNoQuery = Bookmarks.removeQuery(originalUrl); - String urlNoQuery = Bookmarks.removeQuery(url); + String originalUrlNoQuery = removeQuery(originalUrl); + String urlNoQuery = removeQuery(url); originalUrl = originalUrlNoQuery + '?'; url = urlNoQuery + '?'; @@ -182,11 +183,9 @@ import java.io.ByteArrayOutputStream; // Use url to match the base url with other queries (i.e. if the url is // http://www.google.com/m, search for // http://www.google.com/m?some_query) - final String[] selArgs = new String[] { - 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); + final String[] selArgs = new String[] { originalUrlNoQuery, urlNoQuery, originalUrl, url }; + final String[] projection = new String[] { Combined.URL }; + return cr.query(Combined.CONTENT_URI, projection, QUERY_BOOKMARKS_WHERE, selArgs, null); } // Strip the query from the given url. @@ -210,30 +209,28 @@ import java.io.ByteArrayOutputStream; * @param url The current url. * @param favicon The favicon bitmap to write to the db. */ - /* package */ static void updateBookmarkFavicon(final ContentResolver cr, + /* package */ static void updateFavicon(final ContentResolver cr, final String originalUrl, final String url, final Bitmap favicon) { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... unused) { - final Cursor c = - Bookmarks.queryBookmarksForUrl(cr, originalUrl, url); - if (c == null) { - return null; + Cursor cursor = queryCombinedForUrl(cr, originalUrl, url); + try { + if (cursor.moveToFirst()) { + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + favicon.compress(Bitmap.CompressFormat.PNG, 100, os); + + ContentValues values = new ContentValues(); + values.put(Images.FAVICON, os.toByteArray()); + values.put(Images.URL, cursor.getString(0)); + + do { + cr.update(Images.CONTENT_URI, values, null, null); + } while (cursor.moveToNext()); + } + } finally { + if (cursor != null) cursor.close(); } - if (c.moveToFirst()) { - ContentValues values = new ContentValues(); - final ByteArrayOutputStream os = - new ByteArrayOutputStream(); - favicon.compress(Bitmap.CompressFormat.PNG, 100, os); - values.put(BrowserContract.Bookmarks.FAVICON, - os.toByteArray()); - do { - cr.update(ContentUris.withAppendedId( - BrowserContract.Bookmarks.CONTENT_URI, c.getLong(0)), - values, null, null); - } while (c.moveToNext()); - } - c.close(); return null; } }.execute(); diff --git a/src/com/android/browser/BookmarksLoader.java b/src/com/android/browser/BookmarksLoader.java index 9d5e3ed..0947184 100644 --- a/src/com/android/browser/BookmarksLoader.java +++ b/src/com/android/browser/BookmarksLoader.java @@ -18,10 +18,13 @@ package com.android.browser; import android.content.Context; import android.content.CursorLoader; +import android.net.Uri; import android.provider.BrowserContract.Bookmarks; +import android.text.TextUtils; public class BookmarksLoader extends CursorLoader { - public static final String ARG_ROOT_FOLDER = "root"; + public static final String ARG_ACCOUNT_TYPE = "acct_type"; + public static final String ARG_ACCOUNT_NAME = "acct_name"; public static final int COLUMN_INDEX_ID = 0; public static final int COLUMN_INDEX_URL = 1; @@ -42,7 +45,26 @@ public class BookmarksLoader extends CursorLoader { Bookmarks.POSITION, // 7 }; - public BookmarksLoader(Context context, int rootFolder) { - super(context, Bookmarks.CONTENT_URI_DEFAULT_FOLDER, PROJECTION, null, null, null); + private String mAccountType; + private String mAccountName; + + public BookmarksLoader(Context context, String accountType, String accountName) { + super(context, addAccount(Bookmarks.CONTENT_URI_DEFAULT_FOLDER, accountType, accountName), + PROJECTION, null, null, null); + mAccountType = accountType; + mAccountName = accountName; + } + + @Override + public void setUri(Uri uri) { + super.setUri(addAccount(uri, mAccountType, mAccountName)); + } + + private static Uri addAccount(Uri uri, String accountType, String accountName) { + if (!TextUtils.isEmpty(accountType) && !TextUtils.isEmpty(accountName)) { + return uri.buildUpon().appendQueryParameter(Bookmarks.PARAM_ACCOUNT_TYPE, accountType). + appendQueryParameter(Bookmarks.PARAM_ACCOUNT_NAME, accountName).build(); + } + return uri; } } diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java index e1e1e18..9dd801d 100644 --- a/src/com/android/browser/BrowserActivity.java +++ b/src/com/android/browser/BrowserActivity.java @@ -69,6 +69,7 @@ import android.os.SystemClock; import android.provider.Browser; import android.provider.BrowserContract; import android.provider.ContactsContract; +import android.provider.BrowserContract.Images; import android.provider.ContactsContract.Intents.Insert; import android.provider.Downloads; import android.provider.MediaStore; @@ -2449,29 +2450,25 @@ public class BrowserActivity extends Activity new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... unused) { - Cursor c = null; + Cursor cursor = null; try { - c = Bookmarks.queryBookmarksForUrl( - 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(BrowserContract.Bookmarks.THUMBNAIL, - os.toByteArray()); - do { - cr.update(ContentUris.withAppendedId( - BrowserContract.Bookmarks.CONTENT_URI, c.getLong(0)), - values, null, null); - } while (c.moveToNext()); - } + cursor = Bookmarks.queryCombinedForUrl(cr, originalUrl, url); + if (cursor != null && cursor.moveToFirst()) { + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + bm.compress(Bitmap.CompressFormat.PNG, 100, os); + + ContentValues values = new ContentValues(); + values.put(Images.THUMBNAIL, os.toByteArray()); + values.put(Images.URL, cursor.getString(0)); + + do { + cr.update(Images.CONTENT_URI, values, null, null); + } while (cursor.moveToNext()); } } catch (IllegalStateException e) { // Ignore } finally { - if (c != null) c.close(); + if (cursor != null) cursor.close(); } return null; } diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java index 91785d5..152d4cf 100644 --- a/src/com/android/browser/BrowserBookmarksPage.java +++ b/src/com/android/browser/BrowserBookmarksPage.java @@ -22,6 +22,7 @@ import android.app.Fragment; import android.app.LoaderManager; import android.content.ClipData; import android.content.ClipboardManager; +import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; @@ -33,23 +34,22 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; -import android.provider.Browser; import android.provider.BrowserContract; import android.util.Pair; import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; import android.view.LayoutInflater; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.View.OnClickListener; import android.webkit.WebIconDatabase.IconListener; import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; import android.widget.Button; import android.widget.GridView; import android.widget.Toast; +import android.widget.AdapterView.OnItemClickListener; import java.util.Stack; @@ -83,11 +83,13 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte public Loader<Cursor> onCreateLoader(int id, Bundle args) { switch (id) { case LOADER_BOOKMARKS: { - int rootFolder = 0; + String accountType = null; + String accountName = null; if (args != null) { - args.getInt(BookmarksLoader.ARG_ROOT_FOLDER, 0); + accountType = args.getString(BookmarksLoader.ARG_ACCOUNT_TYPE); + accountName = args.getString(BookmarksLoader.ARG_ACCOUNT_NAME); } - return new BookmarksLoader(getActivity(), rootFolder); + return new BookmarksLoader(getActivity(), accountType, accountName); } } throw new UnsupportedOperationException("Unknown loader id " + id); @@ -106,8 +108,9 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte // Fill in the "up" button if needed BookmarksLoader bl = (BookmarksLoader) loader; + String path = bl.getUri().getPath(); boolean rootFolder = - (BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER.equals(bl.getUri())); + BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER.getPath().equals(path); if (rootFolder) { mUpButton.setText(R.string.defaultBookmarksUpButton); mUpButton.setEnabled(false); @@ -389,7 +392,6 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte /** * Update a row in the database with new information. - * Requeries the database if the information has changed. * @param map Bundle storing id, title and url of new information */ public void updateRow(Bundle map) { @@ -428,7 +430,6 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id), values, null, null); } - updateView(); } private void displayRemoveBookmarkDialog(final int position) { @@ -436,15 +437,19 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte // delete the bookmark Cursor cursor = (Cursor) mAdapter.getItem(position); Context context = getActivity(); + final ContentResolver resolver = context.getContentResolver(); + final Uri uri = ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, + cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); + new AlertDialog.Builder(context) .setTitle(R.string.delete_bookmark) .setIcon(android.R.drawable.ic_dialog_alert) - .setMessage(context.getText(R.string.delete_bookmark_warning).toString().replace( - "%s", cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE))) + .setMessage(context.getString(R.string.delete_bookmark_warning, + cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE))) .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { - deleteBookmark(position); + resolver.delete(uri, null, null); } }) .setNegativeButton(R.string.cancel, null) @@ -467,16 +472,8 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte */ public void deleteBookmark(int position) { Cursor cursor = (Cursor) mAdapter.getItem(position); - String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); - String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); - Bookmarks.removeFromBookmarks(null, getActivity().getContentResolver(), url, title); - updateView(); + long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID); + Uri uri = ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id); + getActivity().getContentResolver().delete(uri, null, null); } - - private void updateView() { - BookmarksLoader loader = - (BookmarksLoader) (Loader)(getLoaderManager().getLoader(LOADER_BOOKMARKS)); - loader.forceLoad(); - } - } diff --git a/src/com/android/browser/DownloadTouchIcon.java b/src/com/android/browser/DownloadTouchIcon.java index 1442683..7bb93dc 100644 --- a/src/com/android/browser/DownloadTouchIcon.java +++ b/src/com/android/browser/DownloadTouchIcon.java @@ -36,6 +36,7 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.Message; import android.provider.BrowserContract; +import android.provider.BrowserContract.Images; import android.webkit.WebView; import java.io.ByteArrayOutputStream; @@ -101,15 +102,15 @@ class DownloadTouchIcon extends AsyncTask<String, Void, Void> { @Override public Void doInBackground(String... values) { if (mContentResolver != null) { - mCursor = Bookmarks.queryBookmarksForUrl(mContentResolver, + mCursor = Bookmarks.queryCombinedForUrl(mContentResolver, mOriginalUrl, mUrl); } - boolean inBookmarksDatabase = mCursor != null && mCursor.getCount() > 0; + boolean inDatabase = mCursor != null && mCursor.getCount() > 0; String url = values[0]; - if (inBookmarksDatabase || mMessage != null) { + if (inDatabase || mMessage != null) { AndroidHttpClient client = AndroidHttpClient.newInstance(mUserAgent); HttpHost httpHost = Proxy.getPreferredHttpHost(mActivity, url); if (httpHost != null) { @@ -130,7 +131,7 @@ class DownloadTouchIcon extends AsyncTask<String, Void, Void> { if (content != null) { Bitmap icon = BitmapFactory.decodeStream( content, null, null); - if (inBookmarksDatabase) { + if (inDatabase) { storeIcon(icon); } else if (mMessage != null) { Bundle b = mMessage.getData(); @@ -177,17 +178,16 @@ class DownloadTouchIcon extends AsyncTask<String, Void, Void> { return; } - final ByteArrayOutputStream os = new ByteArrayOutputStream(); - icon.compress(Bitmap.CompressFormat.PNG, 100, os); - ContentValues values = new ContentValues(); - values.put(BrowserContract.Bookmarks.TOUCH_ICON, - os.toByteArray()); - if (mCursor.moveToFirst()) { + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + icon.compress(Bitmap.CompressFormat.PNG, 100, os); + + ContentValues values = new ContentValues(); + values.put(Images.TOUCH_ICON, os.toByteArray()); + values.put(Images.URL, mCursor.getString(0)); + do { - mContentResolver.update(ContentUris.withAppendedId( - BrowserContract.Bookmarks.CONTENT_URI, mCursor.getLong(0)), - values, null, null); + mContentResolver.update(Images.CONTENT_URI, values, null, null); } while (mCursor.moveToNext()); } } diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java index 54f3088..dc42428 100644 --- a/src/com/android/browser/Tab.java +++ b/src/com/android/browser/Tab.java @@ -497,7 +497,7 @@ class Tab { // update the bookmark database for favicon if (favicon != null) { - Bookmarks.updateBookmarkFavicon(mActivity + Bookmarks.updateFavicon(mActivity .getContentResolver(), null, url, favicon); } @@ -1035,7 +1035,7 @@ class Tab { @Override public void onReceivedIcon(WebView view, Bitmap icon) { if (icon != null) { - Bookmarks.updateBookmarkFavicon(mActivity + Bookmarks.updateFavicon(mActivity .getContentResolver(), view.getOriginalUrl(), view .getUrl(), icon); } diff --git a/src/com/android/browser/provider/BrowserProvider2.java b/src/com/android/browser/provider/BrowserProvider2.java index 28eed79..a633941 100644 --- a/src/com/android/browser/provider/BrowserProvider2.java +++ b/src/com/android/browser/provider/BrowserProvider2.java @@ -31,25 +31,36 @@ import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.provider.BrowserContract; -import android.provider.SyncStateContract; +import android.provider.BrowserContract.Accounts; import android.provider.BrowserContract.Bookmarks; import android.provider.BrowserContract.ChromeSyncColumns; +import android.provider.BrowserContract.Combined; import android.provider.BrowserContract.History; +import android.provider.BrowserContract.Images; import android.provider.BrowserContract.Searches; import android.provider.BrowserContract.SyncState; import android.provider.ContactsContract.RawContacts; +import android.provider.SyncStateContract; import android.text.TextUtils; import java.util.HashMap; public class BrowserProvider2 extends SQLiteContentProvider { - static final Uri LEGACY_BROWSER_AUTHORITY_URI = Uri.parse("browser"); + static final String LEGACY_AUTHORITY = "browser"; + static final Uri LEGACY_AUTHORITY_URI = new Uri.Builder().authority(LEGACY_AUTHORITY).build(); static final String TABLE_BOOKMARKS = "bookmarks"; static final String TABLE_HISTORY = "history"; + static final String TABLE_IMAGES = "images"; static final String TABLE_SEARCHES = "searches"; static final String TABLE_SYNC_STATE = "syncstate"; + static final String VIEW_COMBINED = "combined"; + + static final String TABLE_BOOKMARKS_JOIN_IMAGES = "bookmarks LEFT OUTER JOIN images " + + "ON bookmarks.url = images." + Images.URL; + static final String TABLE_HISTORY_JOIN_IMAGES = "history LEFT OUTER JOIN images " + + "ON history.url = images." + Images.URL; static final String DEFAULT_SORT_HISTORY = History.DATE_LAST_VISITED + " DESC"; @@ -67,6 +78,13 @@ public class BrowserProvider2 extends SQLiteContentProvider { static final int SYNCSTATE = 4000; static final int SYNCSTATE_ID = 4001; + static final int IMAGES = 5000; + + static final int COMBINED = 6000; + static final int COMBINED_ID = 6001; + + static final int ACCOUNTS = 7000; + static final long FIXED_ID_CHROME_ROOT = 1; static final long FIXED_ID_BOOKMARKS = 2; static final long FIXED_ID_BOOKMARKS_BAR = 3; @@ -74,30 +92,45 @@ public class BrowserProvider2 extends SQLiteContentProvider { static final String DEFAULT_BOOKMARKS_SORT_ORDER = "position ASC, _id ASC"; - static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); + static final HashMap<String, String> ACCOUNTS_PROJECTION_MAP = new HashMap<String, String>(); static final HashMap<String, String> BOOKMARKS_PROJECTION_MAP = new HashMap<String, String>(); static final HashMap<String, String> OTHER_BOOKMARKS_PROJECTION_MAP = new HashMap<String, String>(); static final HashMap<String, String> HISTORY_PROJECTION_MAP = new HashMap<String, String>(); static final HashMap<String, String> SYNC_STATE_PROJECTION_MAP = new HashMap<String, String>(); + static final HashMap<String, String> IMAGES_PROJECTION_MAP = new HashMap<String, String>(); + static final HashMap<String, String> COMBINED_PROJECTION_MAP = new HashMap<String, String>(); static { final UriMatcher matcher = URI_MATCHER; - matcher.addURI(BrowserContract.AUTHORITY, "bookmarks", BOOKMARKS); - matcher.addURI(BrowserContract.AUTHORITY, "bookmarks/#", BOOKMARKS_ID); - matcher.addURI(BrowserContract.AUTHORITY, "bookmarks/folder", BOOKMARKS_FOLDER); - matcher.addURI(BrowserContract.AUTHORITY, "bookmarks/folder/#", BOOKMARKS_FOLDER_ID); - matcher.addURI(BrowserContract.AUTHORITY, "history", HISTORY); - matcher.addURI(BrowserContract.AUTHORITY, "history/#", HISTORY_ID); - matcher.addURI(BrowserContract.AUTHORITY, "searches", SEARCHES); - matcher.addURI(BrowserContract.AUTHORITY, "searches/#", SEARCHES_ID); - matcher.addURI(BrowserContract.AUTHORITY, "syncstate", SYNCSTATE); - matcher.addURI(BrowserContract.AUTHORITY, "syncstate/#", SYNCSTATE_ID); + final String authority = BrowserContract.AUTHORITY; + matcher.addURI(authority, "accounts", ACCOUNTS); + matcher.addURI(authority, "bookmarks", BOOKMARKS); + matcher.addURI(authority, "bookmarks/#", BOOKMARKS_ID); + matcher.addURI(authority, "bookmarks/folder", BOOKMARKS_FOLDER); + matcher.addURI(authority, "bookmarks/folder/#", BOOKMARKS_FOLDER_ID); + matcher.addURI(authority, "history", HISTORY); + matcher.addURI(authority, "history/#", HISTORY_ID); + matcher.addURI(authority, "searches", SEARCHES); + matcher.addURI(authority, "searches/#", SEARCHES_ID); + matcher.addURI(authority, "syncstate", SYNCSTATE); + matcher.addURI(authority, "syncstate/#", SYNCSTATE_ID); + matcher.addURI(authority, "images", IMAGES); + matcher.addURI(authority, "combined", COMBINED); + matcher.addURI(authority, "combined/#", COMBINED_ID); + + // Projection maps + HashMap<String, String> map; + + // Accounts + map = ACCOUNTS_PROJECTION_MAP; + map.put(Accounts.ACCOUNT_TYPE, Accounts.ACCOUNT_TYPE); + map.put(Accounts.ACCOUNT_NAME, Accounts.ACCOUNT_NAME); // Bookmarks - HashMap<String, String> map = BOOKMARKS_PROJECTION_MAP; + map = BOOKMARKS_PROJECTION_MAP; map.put(Bookmarks._ID, qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID)); map.put(Bookmarks.TITLE, Bookmarks.TITLE); map.put(Bookmarks.URL, Bookmarks.URL); @@ -121,6 +154,14 @@ public class BrowserProvider2 extends SQLiteContentProvider { map.put(Bookmarks.SYNC3, Bookmarks.SYNC3); map.put(Bookmarks.SYNC4, Bookmarks.SYNC4); map.put(Bookmarks.SYNC5, Bookmarks.SYNC5); + map.put(Bookmarks.PARENT_SOURCE_ID, "(SELECT " + Bookmarks.SOURCE_ID + + " FROM " + TABLE_BOOKMARKS + " A WHERE " + + "A." + Bookmarks._ID + "=" + TABLE_BOOKMARKS + "." + Bookmarks.PARENT + + ") AS " + Bookmarks.PARENT_SOURCE_ID); + map.put(Bookmarks.INSERT_AFTER_SOURCE_ID, "(SELECT " + Bookmarks.SOURCE_ID + + " FROM " + TABLE_BOOKMARKS + " A WHERE " + + "A." + Bookmarks._ID + "=" + TABLE_BOOKMARKS + "." + Bookmarks.INSERT_AFTER + + ") AS " + Bookmarks.INSERT_AFTER_SOURCE_ID); // Other bookmarks OTHER_BOOKMARKS_PROJECTION_MAP.putAll(BOOKMARKS_PROJECTION_MAP); @@ -130,11 +171,11 @@ public class BrowserProvider2 extends SQLiteContentProvider { // History map = HISTORY_PROJECTION_MAP; 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.TITLE, History.TITLE); + map.put(History.URL, History.URL); + map.put(History.FAVICON, History.FAVICON); + map.put(History.THUMBNAIL, History.THUMBNAIL); + map.put(History.TOUCH_ICON, History.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); @@ -146,6 +187,32 @@ public class BrowserProvider2 extends SQLiteContentProvider { map.put(SyncState.ACCOUNT_NAME, SyncState.ACCOUNT_NAME); map.put(SyncState.ACCOUNT_TYPE, SyncState.ACCOUNT_TYPE); map.put(SyncState.DATA, SyncState.DATA); + + // Images + map = IMAGES_PROJECTION_MAP; + map.put(Images.URL, Images.URL); + map.put(Images.FAVICON, Images.FAVICON); + map.put(Images.THUMBNAIL, Images.THUMBNAIL); + map.put(Images.TOUCH_ICON, Images.TOUCH_ICON); + + // Combined history half + map = COMBINED_PROJECTION_MAP; + map.put(Combined._ID, Combined._ID); + map.put(Combined.TITLE, Combined.TITLE); + map.put(Combined.URL, Combined.URL); + map.put(Combined.DATE_CREATED, Combined.DATE_CREATED); + map.put(Combined.DATE_LAST_VISITED, Combined.DATE_LAST_VISITED); + map.put(Combined.IS_BOOKMARK, Combined.IS_BOOKMARK); + map.put(Combined.VISITS, Combined.VISITS); + map.put(Combined.FAVICON, Combined.FAVICON); + map.put(Combined.THUMBNAIL, Combined.THUMBNAIL); + map.put(Combined.TOUCH_ICON, Combined.TOUCH_ICON); + map.put(Combined.USER_ENTERED, Combined.USER_ENTERED); + } + + static final String bookmarkOrHistoryColumn(String column) { + return "CASE WHEN bookmarks." + column + " IS NOT NULL THEN " + + "bookmarks." + column + " ELSE history." + column + " END AS " + column; } static final String qualifyColumn(String table, String column) { @@ -157,7 +224,7 @@ public class BrowserProvider2 extends SQLiteContentProvider { final class DatabaseHelper extends SQLiteOpenHelper { static final String DATABASE_NAME = "browser2.db"; - static final int DATABASE_VERSION = 16; + static final int DATABASE_VERSION = 22; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @@ -168,11 +235,8 @@ public class BrowserProvider2 extends SQLiteContentProvider { Bookmarks._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + Bookmarks.TITLE + " TEXT," + Bookmarks.URL + " TEXT," + - Bookmarks.FAVICON + " BLOB," + - Bookmarks.THUMBNAIL + " BLOB," + - Bookmarks.TOUCH_ICON + " BLOB," + Bookmarks.IS_FOLDER + " INTEGER NOT NULL DEFAULT 0," + - Bookmarks.PARENT + " INTEGER NOT NULL DEFAULT 0," + + Bookmarks.PARENT + " INTEGER," + Bookmarks.POSITION + " INTEGER NOT NULL," + Bookmarks.INSERT_AFTER + " INTEGER," + Bookmarks.IS_DELETED + " INTEGER NOT NULL DEFAULT 0," + @@ -198,21 +262,58 @@ public class BrowserProvider2 extends SQLiteContentProvider { 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.USER_ENTERED + " INTEGER" + ");"); + db.execSQL("CREATE TABLE " + TABLE_IMAGES + " (" + + Images.URL + " TEXT UNIQUE NOT NULL," + + Images.FAVICON + " BLOB," + + Images.THUMBNAIL + " BLOB," + + Images.TOUCH_ICON + " BLOB" + + ");"); + db.execSQL("CREATE INDEX imagesUrlIndex ON " + TABLE_IMAGES + + "(" + Images.URL + ")"); + db.execSQL("CREATE TABLE " + TABLE_SEARCHES + " (" + Searches._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + Searches.SEARCH + " TEXT," + Searches.DATE + " LONG" + ");"); + db.execSQL("CREATE VIEW " + VIEW_COMBINED + " AS " + + "SELECT " + + bookmarkOrHistoryColumn(Combined._ID) + ", " + + bookmarkOrHistoryColumn(Combined.TITLE) + ", " + + qualifyColumn(TABLE_HISTORY, Combined.URL) + ", " + + qualifyColumn(TABLE_HISTORY, Combined.DATE_CREATED) + ", " + + Combined.DATE_LAST_VISITED + ", " + + "CASE WHEN bookmarks._id IS NOT NULL THEN 1 ELSE 0 END AS " + Combined.IS_BOOKMARK + ", " + + Combined.VISITS + ", " + + Combined.FAVICON + ", " + + Combined.THUMBNAIL + ", " + + Combined.TOUCH_ICON + ", " + + "NULL AS " + Combined.USER_ENTERED + " "+ + "FROM history LEFT OUTER JOIN bookmarks ON history.url = bookmarks.url LEFT OUTER JOIN images ON history.url = images.url_key " + + + "UNION ALL " + + + "SELECT " + + Combined._ID + ", " + + Combined.TITLE + ", " + + Combined.URL + ", " + + Combined.DATE_CREATED + ", " + + "NULL AS " + Combined.DATE_LAST_VISITED + ", "+ + "1 AS " + Combined.IS_BOOKMARK + ", " + + "0 AS " + Combined.VISITS + ", "+ + Combined.FAVICON + ", " + + Combined.THUMBNAIL + ", " + + Combined.TOUCH_ICON + ", " + + "NULL AS " + Combined.USER_ENTERED + " "+ + "FROM bookmarks LEFT OUTER JOIN images ON bookmarks.url = images.url_key WHERE url NOT IN (SELECT url FROM history)"); + mSyncHelper.createDatabase(db); } @@ -222,6 +323,8 @@ public class BrowserProvider2 extends SQLiteContentProvider { db.execSQL("DROP TABLE IF EXISTS " + TABLE_BOOKMARKS); db.execSQL("DROP TABLE IF EXISTS " + TABLE_HISTORY); db.execSQL("DROP TABLE IF EXISTS " + TABLE_SEARCHES); + db.execSQL("DROP TABLE IF EXISTS " + TABLE_IMAGES); + db.execSQL("DROP VIEW IF EXISTS " + VIEW_COMBINED); onCreate(db); } @@ -302,6 +405,8 @@ public class BrowserProvider2 extends SQLiteContentProvider { R.array.bookmarks); int size = bookmarks.length; try { + String parent = Long.toString(parentId); + String now = Long.toString(System.currentTimeMillis()); for (int i = 0; i < size; i = i + 2) { CharSequence bookmarkDestination = replaceSystemPropertyInString(getContext(), bookmarks[i + 1]); @@ -310,13 +415,15 @@ public class BrowserProvider2 extends SQLiteContentProvider { Bookmarks.URL + ", " + Bookmarks.IS_FOLDER + "," + Bookmarks.PARENT + "," + - Bookmarks.POSITION + + Bookmarks.POSITION + "," + + Bookmarks.DATE_CREATED + ") VALUES (" + "'" + bookmarks[i] + "', " + "'" + bookmarkDestination + "', " + "0," + - Long.toString(parentId) + "," + - Integer.toString(i) + + parent + "," + + Integer.toString(i) + "," + + now + ");"); } } catch (ArrayIndexOutOfBoundsException e) { @@ -399,7 +506,7 @@ public class BrowserProvider2 extends SQLiteContentProvider { public void notifyChange(boolean callerIsSyncAdapter) { ContentResolver resolver = getContext().getContentResolver(); resolver.notifyChange(BrowserContract.AUTHORITY_URI, null, !callerIsSyncAdapter); - resolver.notifyChange(LEGACY_BROWSER_AUTHORITY_URI, null, !callerIsSyncAdapter); + resolver.notifyChange(LEGACY_AUTHORITY_URI, null, !callerIsSyncAdapter); } @Override @@ -430,7 +537,15 @@ public class BrowserProvider2 extends SQLiteContentProvider { SQLiteDatabase db = mOpenHelper.getReadableDatabase(); final int match = URI_MATCHER.match(uri); SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + String limit = uri.getQueryParameter(BrowserContract.PARAM_LIMIT); switch (match) { + case ACCOUNTS: { + qb.setTables(TABLE_BOOKMARKS); + qb.setProjectionMap(ACCOUNTS_PROJECTION_MAP); + qb.setDistinct(true); + break; + } + case BOOKMARKS_FOLDER_ID: case BOOKMARKS_ID: case BOOKMARKS: { @@ -442,24 +557,35 @@ public class BrowserProvider2 extends SQLiteContentProvider { if (match == BOOKMARKS_ID) { // Tack on the ID of the specific bookmark requested - selection = DatabaseUtils.concatenateWhere( - TABLE_BOOKMARKS + "." + Bookmarks._ID + "=?", selection); + selection = DatabaseUtils.concatenateWhere(selection, + TABLE_BOOKMARKS + "." + Bookmarks._ID + "=?"); selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, new String[] { Long.toString(ContentUris.parseId(uri)) }); } else if (match == BOOKMARKS_FOLDER_ID) { // Tack on the ID of the specific folder requested - selection = DatabaseUtils.concatenateWhere( - TABLE_BOOKMARKS + "." + Bookmarks.PARENT + "=?", selection); + selection = DatabaseUtils.concatenateWhere(selection, + TABLE_BOOKMARKS + "." + Bookmarks.PARENT + "=?"); selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, new String[] { Long.toString(ContentUris.parseId(uri)) }); } + // Look for account info + String accountType = uri.getQueryParameter(Bookmarks.PARAM_ACCOUNT_TYPE); + String accountName = uri.getQueryParameter(Bookmarks.PARAM_ACCOUNT_NAME); + if (!TextUtils.isEmpty(accountType) && !TextUtils.isEmpty(accountName)) { + selection = DatabaseUtils.concatenateWhere(selection, + Bookmarks.ACCOUNT_TYPE + "=? AND " + Bookmarks.ACCOUNT_NAME + "=? "); + selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, + new String[] { accountType, accountName }); + } + + // Set a default sort order if one isn't specified if (TextUtils.isEmpty(sortOrder)) { sortOrder = DEFAULT_BOOKMARKS_SORT_ORDER; } qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP); - qb.setTables(TABLE_BOOKMARKS); + qb.setTables(TABLE_BOOKMARKS_JOIN_IMAGES); break; } @@ -470,29 +596,63 @@ public class BrowserProvider2 extends SQLiteContentProvider { "selections aren't supported on this URI"); } - qb.setTables(TABLE_BOOKMARKS); - qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP); - String bookmarksBarQuery = qb.buildQuery(projection, - Bookmarks.PARENT + "=? AND " + Bookmarks.IS_DELETED + "=0", - null, null, null, null, null); + // Look for an account + boolean useAccount = false; + String accountType = uri.getQueryParameter(Bookmarks.PARAM_ACCOUNT_TYPE); + String accountName = uri.getQueryParameter(Bookmarks.PARAM_ACCOUNT_NAME); + if (!TextUtils.isEmpty(accountType) && !TextUtils.isEmpty(accountName)) { + useAccount = true; + } - qb.setProjectionMap(OTHER_BOOKMARKS_PROJECTION_MAP); - String otherBookmarksQuery = qb.buildQuery(projection, - Bookmarks._ID + "=?", - null, null, null, null, null); + qb.setTables(TABLE_BOOKMARKS_JOIN_IMAGES); + String bookmarksBarQuery; + String otherBookmarksQuery; + String[] args; + if (!useAccount) { + qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP); + bookmarksBarQuery = qb.buildQuery(projection, + Bookmarks.PARENT + "=? AND " + Bookmarks.IS_DELETED + "=0", + null, null, null, null, null); + + qb.setProjectionMap(OTHER_BOOKMARKS_PROJECTION_MAP); + otherBookmarksQuery = qb.buildQuery(projection, + Bookmarks._ID + "=?", + null, null, null, null, null); + + args = new String[] { Long.toString(FIXED_ID_BOOKMARKS_BAR), + Long.toString(FIXED_ID_OTHER_BOOKMARKS) }; + } else { + qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP); + bookmarksBarQuery = qb.buildQuery(projection, + Bookmarks.ACCOUNT_TYPE + "=? AND " + Bookmarks.ACCOUNT_NAME + "=? " + + "AND parent = " + + "(SELECT _id FROM " + TABLE_BOOKMARKS + " WHERE " + + ChromeSyncColumns.SERVER_UNIQUE + "=" + + "'" + ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR + "' " + + "AND account_type = ? AND account_name = ?) " + + "AND " + Bookmarks.IS_DELETED + "=0", + null, null, null, null, null); + + qb.setProjectionMap(OTHER_BOOKMARKS_PROJECTION_MAP); + otherBookmarksQuery = qb.buildQuery(projection, + Bookmarks.ACCOUNT_TYPE + "=? AND " + Bookmarks.ACCOUNT_NAME + "=?" + + " AND " + ChromeSyncColumns.SERVER_UNIQUE + "=?", + null, null, null, null, null); + + args = new String[] { + accountType, accountName, accountType, accountName, + accountType, accountName, ChromeSyncColumns.FOLDER_NAME_OTHER_BOOKMARKS, + }; + } String query = qb.buildUnionQuery( new String[] { bookmarksBarQuery, otherBookmarksQuery }, - DEFAULT_BOOKMARKS_SORT_ORDER, null); - - return db.rawQuery(query, new String[] { - Long.toString(FIXED_ID_BOOKMARKS_BAR), - Long.toString(FIXED_ID_OTHER_BOOKMARKS)}); + DEFAULT_BOOKMARKS_SORT_ORDER, limit); + return db.rawQuery(query, args); } case HISTORY_ID: { - selection = DatabaseUtils.concatenateWhere( - TABLE_HISTORY + "._id=?", selection); + selection = DatabaseUtils.concatenateWhere(selection, TABLE_HISTORY + "._id=?"); selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, new String[] { Long.toString(ContentUris.parseId(uri)) }); // fall through @@ -502,7 +662,7 @@ public class BrowserProvider2 extends SQLiteContentProvider { sortOrder = DEFAULT_SORT_HISTORY; } qb.setProjectionMap(HISTORY_PROJECTION_MAP); - qb.setTables(TABLE_HISTORY); + qb.setTables(TABLE_HISTORY_JOIN_IMAGES); break; } @@ -518,12 +678,31 @@ public class BrowserProvider2 extends SQLiteContentProvider { return mSyncHelper.query(db, projection, selectionWithId, selectionArgs, sortOrder); } + case IMAGES: { + qb.setTables(TABLE_IMAGES); + qb.setProjectionMap(IMAGES_PROJECTION_MAP); + break; + } + + case COMBINED_ID: { + selection = DatabaseUtils.concatenateWhere(selection, VIEW_COMBINED + "._id=?"); + selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, + new String[] { Long.toString(ContentUris.parseId(uri)) }); + // fall through + } + case COMBINED: { + qb.setTables(VIEW_COMBINED); + qb.setProjectionMap(COMBINED_PROJECTION_MAP); + break; + } + default: { throw new UnsupportedOperationException("Unknown URL " + uri.toString()); } } - Cursor cursor = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); + Cursor cursor = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder, + limit); cursor.setNotificationUri(getContext().getContentResolver(), BrowserContract.AUTHORITY_URI); return cursor; } @@ -603,11 +782,11 @@ public class BrowserProvider2 extends SQLiteContentProvider { values.put(Bookmarks.DATE_CREATED, now); values.put(Bookmarks.DATE_MODIFIED, now); values.put(Bookmarks.DIRTY, 1); - } - // If no parent is set default to the "Bookmarks Bar" folder - if (!values.containsKey(Bookmarks.PARENT)) { - values.put(Bookmarks.PARENT, FIXED_ID_BOOKMARKS_BAR); + // If no parent is set default to the "Bookmarks Bar" folder + if (!values.containsKey(Bookmarks.PARENT)) { + values.put(Bookmarks.PARENT, FIXED_ID_BOOKMARKS_BAR); + } } // If no position is requested put the bookmark at the beginning of the list @@ -615,11 +794,31 @@ public class BrowserProvider2 extends SQLiteContentProvider { values.put(Bookmarks.POSITION, Long.toString(Long.MIN_VALUE)); } + // Extract out the image values so they can be inserted into the images table + String url = values.getAsString(Bookmarks.URL); + ContentValues imageValues = extractImageValues(values, url); + boolean isFolder = values.getAsBoolean(Bookmarks.IS_FOLDER); + if (!isFolder && imageValues != null && !TextUtils.isEmpty(url)) { + db.insertOrThrow(TABLE_IMAGES, Images.FAVICON, imageValues); + } + id = db.insertOrThrow(TABLE_BOOKMARKS, Bookmarks.DIRTY, values); break; } case HISTORY: { + // If no created time is specified set it to now + if (!values.containsKey(History.DATE_CREATED)) { + values.put(History.DATE_CREATED, System.currentTimeMillis()); + } + + // Extract out the image values so they can be inserted into the images table + ContentValues imageValues = extractImageValues(values, + values.getAsString(History.URL)); + if (imageValues != null) { + db.insertOrThrow(TABLE_IMAGES, Images.FAVICON, imageValues); + } + id = db.insertOrThrow(TABLE_HISTORY, History.VISITS, values); break; } @@ -696,7 +895,7 @@ public class BrowserProvider2 extends SQLiteContentProvider { // fall through } case HISTORY: { - return db.update(TABLE_HISTORY, values, selection, selectionArgs); + return updateHistoryInTransaction(values, selection, selectionArgs); } case SYNCSTATE: { @@ -712,6 +911,20 @@ public class BrowserProvider2 extends SQLiteContentProvider { return mSyncHelper.update(mDb, values, selectionWithId, selectionArgs); } + + case IMAGES: { + String url = values.getAsString(Images.URL); + if (TextUtils.isEmpty(url)) { + throw new IllegalArgumentException("Images.URL is required"); + } + int count = db.update(TABLE_IMAGES, values, Images.URL + "=?", + new String[] { url }); + if (count == 0) { + db.insertOrThrow(TABLE_IMAGES, Images.FAVICON, values); + count = 1; + } + return count; + } } throw new UnsupportedOperationException("Unknown update URI " + uri); } @@ -719,21 +932,28 @@ public class BrowserProvider2 extends SQLiteContentProvider { /** * Does a query to find the matching bookmarks and updates each one with the provided values. */ - private int updateBookmarksInTransaction(ContentValues values, String selection, + int updateBookmarksInTransaction(ContentValues values, String selection, String[] selectionArgs, boolean callerIsSyncAdapter) { int count = 0; final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); Cursor cursor = query(Bookmarks.CONTENT_URI, - new String[] { Bookmarks._ID, Bookmarks.VERSION }, + new String[] { Bookmarks._ID, Bookmarks.VERSION, Bookmarks.URL }, selection, selectionArgs, null); try { String[] args = new String[1]; // Mark the bookmark dirty if the caller isn't a sync adapter if (!callerIsSyncAdapter) { - values = new ContentValues(values); values.put(Bookmarks.DATE_MODIFIED, System.currentTimeMillis()); values.put(Bookmarks.DIRTY, 1); } + + boolean updatingUrl = values.containsKey(Bookmarks.URL); + String url = null; + if (updatingUrl) { + url = values.getAsString(Bookmarks.URL); + } + ContentValues imageValues = extractImageValues(values, url); + while (cursor.moveToNext()) { args[0] = cursor.getString(0); if (!callerIsSyncAdapter) { @@ -741,6 +961,21 @@ public class BrowserProvider2 extends SQLiteContentProvider { values.put(Bookmarks.VERSION, cursor.getLong(1) + 1); } count += db.update(TABLE_BOOKMARKS, values, "_id=?", args); + + // Update the images over in their table + if (imageValues != null) { + if (!updatingUrl) { + url = cursor.getString(2); + imageValues.put(Images.URL, url); + } + + if (!TextUtils.isEmpty(url)) { + args[0] = url; + if (db.update(TABLE_IMAGES, imageValues, Images.URL + "=?", args) == 0) { + db.insert(TABLE_IMAGES, Images.FAVICON, imageValues); + } + } + } } } finally { if (cursor != null) cursor.close(); @@ -748,7 +983,48 @@ public class BrowserProvider2 extends SQLiteContentProvider { return count; } - private String appendAccountToSelection(Uri uri, String selection) { + /** + * Does a query to find the matching bookmarks and updates each one with the provided values. + */ + int updateHistoryInTransaction(ContentValues values, String selection, String[] selectionArgs) { + int count = 0; + final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); + Cursor cursor = query(History.CONTENT_URI, + new String[] { History._ID, History.URL }, + selection, selectionArgs, null); + try { + String[] args = new String[1]; + + boolean updatingUrl = values.containsKey(History.URL); + String url = null; + if (updatingUrl) { + url = values.getAsString(History.URL); + } + ContentValues imageValues = extractImageValues(values, url); + + while (cursor.moveToNext()) { + args[0] = cursor.getString(0); + count += db.update(TABLE_HISTORY, values, "_id=?", args); + + // Update the images over in their table + if (imageValues != null) { + if (!updatingUrl) { + url = cursor.getString(1); + imageValues.put(Images.URL, url); + } + args[0] = url; + if (db.update(TABLE_IMAGES, imageValues, Images.URL + "=?", args) == 0) { + db.insert(TABLE_IMAGES, Images.FAVICON, imageValues); + } + } + } + } finally { + if (cursor != null) cursor.close(); + } + return count; + } + + String appendAccountToSelection(Uri uri, String selection) { final String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME); final String accountType = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE); @@ -777,4 +1053,37 @@ public class BrowserProvider2 extends SQLiteContentProvider { return selection; } } + + ContentValues extractImageValues(ContentValues values, String url) { + ContentValues imageValues = null; + // favicon + if (values.containsKey(Bookmarks.FAVICON)) { + imageValues = new ContentValues(); + imageValues.put(Images.FAVICON, values.getAsByteArray(Bookmarks.FAVICON)); + values.remove(Bookmarks.FAVICON); + } + + // thumbnail + if (values.containsKey(Bookmarks.THUMBNAIL)) { + if (imageValues == null) { + imageValues = new ContentValues(); + } + imageValues.put(Images.THUMBNAIL, values.getAsByteArray(Bookmarks.THUMBNAIL)); + values.remove(Bookmarks.THUMBNAIL); + } + + // touch icon + if (values.containsKey(Bookmarks.TOUCH_ICON)) { + if (imageValues == null) { + imageValues = new ContentValues(); + } + imageValues.put(Images.TOUCH_ICON, values.getAsByteArray(Bookmarks.TOUCH_ICON)); + values.remove(Bookmarks.TOUCH_ICON); + } + + if (imageValues != null) { + imageValues.put(Images.URL, url); + } + return imageValues; + } } |