diff options
author | John Reck <jreck@google.com> | 2010-12-13 11:03:16 -0800 |
---|---|---|
committer | John Reck <jreck@google.com> | 2010-12-15 11:34:05 -0800 |
commit | dd03faf825b24dfaf9422bbd004fb73dc14b89ac (patch) | |
tree | 039c2b4c578b7f64026dce93b030e3ffedf50253 | |
parent | afdb794ba4a05716dfc52be7c4d3885fb4174d4a (diff) | |
download | packages_apps_Browser-dd03faf825b24dfaf9422bbd004fb73dc14b89ac.zip packages_apps_Browser-dd03faf825b24dfaf9422bbd004fb73dc14b89ac.tar.gz packages_apps_Browser-dd03faf825b24dfaf9422bbd004fb73dc14b89ac.tar.bz2 |
BP2 now handles old browser URI
Bug: 3248258
Adds support for handling legacy URIs in BrowserProvider2, and makes
it the handler for all legacy URI requests.
Change-Id: I0a0210a5c8c716452b9a3de5e3294dd5dde1b37c
-rw-r--r-- | AndroidManifest.xml | 10 | ||||
-rw-r--r-- | src/com/android/browser/BookmarkUtils.java | 4 | ||||
-rw-r--r-- | src/com/android/browser/provider/BrowserProvider2.java | 330 |
3 files changed, 308 insertions, 36 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 955687b..227a7ac 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -44,16 +44,8 @@ android:hardwareAccelerated="true" android:taskAffinity="android.task.browser" > - <provider android:name="BrowserProvider" - android:authorities="browser" - android:multiprocess="true" - android:readPermission="com.android.browser.permission.READ_HISTORY_BOOKMARKS" - android:writePermission="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"> - <path-permission android:path="/bookmarks/search_suggest_query" - android:readPermission="android.permission.GLOBAL_SEARCH" /> - </provider> <provider android:name=".provider.BrowserProvider2" - android:authorities="com.android.browser" + android:authorities="com.android.browser;browser" android:multiprocess="true" android:readPermission="com.android.browser.permission.READ_HISTORY_BOOKMARKS" android:writePermission="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"> diff --git a/src/com/android/browser/BookmarkUtils.java b/src/com/android/browser/BookmarkUtils.java index 58622ce..d2eec66 100644 --- a/src/com/android/browser/BookmarkUtils.java +++ b/src/com/android/browser/BookmarkUtils.java @@ -35,7 +35,7 @@ import android.provider.Browser; import android.provider.BrowserContract; import android.text.TextUtils; -class BookmarkUtils { +public class BookmarkUtils { private final static String LOGTAG = "BookmarkUtils"; // XXX: There is no public string defining this intent so if Home changes the value, we @@ -174,7 +174,7 @@ class BookmarkUtils { BrowserContract.Bookmarks.CONTENT_URI.buildUpon()).build(); } - /* package */ static Uri.Builder addAccountInfo(Context context, Uri.Builder ub) { + public static Uri.Builder addAccountInfo(Context context, Uri.Builder ub) { Uri uri = BrowserContract.Bookmarks.CONTENT_URI; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); String accountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null); diff --git a/src/com/android/browser/provider/BrowserProvider2.java b/src/com/android/browser/provider/BrowserProvider2.java index cdda1e4..19d508d 100644 --- a/src/com/android/browser/provider/BrowserProvider2.java +++ b/src/com/android/browser/provider/BrowserProvider2.java @@ -16,23 +16,32 @@ package com.android.browser.provider; +import com.android.browser.BookmarkUtils; +import com.android.browser.BrowserBookmarksPage; import com.android.browser.R; import com.android.common.content.SyncStateContentProviderHelper; import android.accounts.Account; +import android.app.SearchManager; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; import android.content.UriMatcher; import android.content.res.Resources; import android.content.res.TypedArray; +import android.database.AbstractCursor; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; +import android.preference.PreferenceManager; +import android.provider.BaseColumns; +import android.provider.Browser.BookmarkColumns; import android.provider.BrowserContract; import android.provider.BrowserContract.Accounts; import android.provider.BrowserContract.Bookmarks; @@ -78,10 +87,20 @@ public class BrowserProvider2 extends SQLiteContentProvider { static final String DEFAULT_SORT_SEARCHES = Searches.DATE + " DESC"; + private static final String[] SUGGEST_PROJECTION = new String[] { + Bookmarks._ID, + Bookmarks.URL, + Bookmarks.TITLE}; + + private static final String SUGGEST_SELECTION = + "url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ?" + + " OR title LIKE ?"; + static final int BOOKMARKS = 1000; static final int BOOKMARKS_ID = 1001; static final int BOOKMARKS_FOLDER = 1002; static final int BOOKMARKS_FOLDER_ID = 1003; + static final int BOOKMARKS_SUGGESTIONS = 1004; static final int HISTORY = 2000; static final int HISTORY_ID = 2001; @@ -101,6 +120,9 @@ public class BrowserProvider2 extends SQLiteContentProvider { static final int SETTINGS = 8000; + static final int LEGACY = 9000; + static final int LEGACY_ID = 9001; + public static final long FIXED_ID_ROOT = 1; // Default sort order for unsync'd bookmarks @@ -132,6 +154,9 @@ public class BrowserProvider2 extends SQLiteContentProvider { matcher.addURI(authority, "bookmarks/#", BOOKMARKS_ID); matcher.addURI(authority, "bookmarks/folder", BOOKMARKS_FOLDER); matcher.addURI(authority, "bookmarks/folder/#", BOOKMARKS_FOLDER_ID); + matcher.addURI(authority, + "bookmarks/" + SearchManager.SUGGEST_URI_PATH_QUERY, + BOOKMARKS_SUGGESTIONS); matcher.addURI(authority, "history", HISTORY); matcher.addURI(authority, "history/#", HISTORY_ID); matcher.addURI(authority, "searches", SEARCHES); @@ -143,6 +168,15 @@ public class BrowserProvider2 extends SQLiteContentProvider { matcher.addURI(authority, "combined/#", COMBINED_ID); matcher.addURI(authority, "settings", SETTINGS); + // Legacy + matcher.addURI(LEGACY_AUTHORITY, "searches", SEARCHES); + matcher.addURI(LEGACY_AUTHORITY, "searches/#", SEARCHES_ID); + matcher.addURI(LEGACY_AUTHORITY, "bookmarks", LEGACY); + matcher.addURI(LEGACY_AUTHORITY, "bookmarks/#", LEGACY_ID); + matcher.addURI(LEGACY_AUTHORITY, + "bookmarks/" + SearchManager.SUGGEST_URI_PATH_QUERY, + BOOKMARKS_SUGGESTIONS); + // Projection maps HashMap<String, String> map; @@ -688,6 +722,10 @@ public class BrowserProvider2 extends SQLiteContentProvider { return cursor; } + case BOOKMARKS_SUGGESTIONS: { + return doSuggestQuery(selection, selectionArgs, limit); + } + case HISTORY_ID: { selection = DatabaseUtils.concatenateWhere(selection, TABLE_HISTORY + "._id=?"); selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, @@ -737,12 +775,15 @@ public class BrowserProvider2 extends SQLiteContentProvider { break; } + case LEGACY_ID: case COMBINED_ID: { - selection = DatabaseUtils.concatenateWhere(selection, Combined._ID +"=?"); + selection = DatabaseUtils.concatenateWhere( + selection, Combined._ID + " = CAST(? AS INTEGER)"); selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, new String[] { Long.toString(ContentUris.parseId(uri)) }); // fall through } + case LEGACY: case COMBINED: { qb = new SQLiteQueryBuilder(); String[] args = createCombinedQuery(uri, projection, qb); @@ -771,6 +812,48 @@ public class BrowserProvider2 extends SQLiteContentProvider { return cursor; } + private Cursor doSuggestQuery(String selection, String[] selectionArgs, String limit) { + if (selectionArgs[0] == null) { + return null; + } else { + String like = selectionArgs[0] + "%"; + if (selectionArgs[0].startsWith("http") + || selectionArgs[0].startsWith("file")) { + selectionArgs[0] = like; + } else { + selectionArgs = new String[5]; + selectionArgs[0] = "http://" + like; + selectionArgs[1] = "http://www." + like; + selectionArgs[2] = "https://" + like; + selectionArgs[3] = "https://www." + like; + // To match against titles. + selectionArgs[4] = like; + selection = SUGGEST_SELECTION; + } + } + selection = DatabaseUtils.concatenateWhere(selection, + Bookmarks.IS_DELETED + "=0 AND " + Bookmarks.IS_FOLDER + "=0"); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + String accountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null); + String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null); + if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { + selection = DatabaseUtils.concatenateWhere(selection, + Bookmarks.ACCOUNT_TYPE + "=? AND " + Bookmarks.ACCOUNT_NAME + "=? "); + selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, + new String[] { accountType, accountName }); + } else { + selection = DatabaseUtils.concatenateWhere(selection, + Bookmarks.ACCOUNT_TYPE + " IS NULL AND " + + Bookmarks.ACCOUNT_NAME + " IS NULL "); + } + Cursor c = mOpenHelper.getReadableDatabase().query(TABLE_BOOKMARKS, + SUGGEST_PROJECTION, selection, selectionArgs, null, null, + DEFAULT_BOOKMARKS_SORT_ORDER, null); + + return new SuggestionsCursor(c); + } + private String[] createCombinedQuery( Uri uri, String[] projection, SQLiteQueryBuilder qb) { String[] args = null; @@ -819,33 +902,35 @@ public class BrowserProvider2 extends SQLiteContentProvider { return args; } + int deleteBookmarks(String selection, String[] selectionArgs, + boolean callerIsSyncAdapter) { + //TODO cascade deletes down from folders + final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); + if (callerIsSyncAdapter) { + return db.delete(TABLE_BOOKMARKS, selection, selectionArgs); + } + ContentValues values = new ContentValues(); + values.put(Bookmarks.DATE_MODIFIED, System.currentTimeMillis()); + values.put(Bookmarks.IS_DELETED, 1); + return updateInTransaction(Bookmarks.CONTENT_URI, values, + selection, selectionArgs, callerIsSyncAdapter); + } + @Override public int deleteInTransaction(Uri uri, String selection, String[] selectionArgs, boolean callerIsSyncAdapter) { final int match = URI_MATCHER.match(uri); final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); switch (match) { - case BOOKMARKS_ID: + case BOOKMARKS_ID: { + selection = DatabaseUtils.concatenateWhere(selection, + TABLE_BOOKMARKS + "._id=?"); + selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, + new String[] { Long.toString(ContentUris.parseId(uri)) }); + // fall through + } case BOOKMARKS: { - //TODO cascade deletes down from folders - if (!callerIsSyncAdapter) { - // If the caller isn't a sync adapter just go through and update all the - // bookmarks to have the deleted flag set. - ContentValues values = new ContentValues(); - values.put(Bookmarks.DATE_MODIFIED, System.currentTimeMillis()); - values.put(Bookmarks.IS_DELETED, 1); - return updateInTransaction(uri, values, selection, selectionArgs, - callerIsSyncAdapter); - } else { - // Sync adapters are allowed to actually delete things - if (match == BOOKMARKS_ID) { - selection = DatabaseUtils.concatenateWhere(selection, - TABLE_BOOKMARKS + "._id=?"); - selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, - new String[] { Long.toString(ContentUris.parseId(uri)) }); - } - return db.delete(TABLE_BOOKMARKS, selection, selectionArgs); - } + return deleteBookmarks(selection, selectionArgs, callerIsSyncAdapter); } case HISTORY_ID: { @@ -878,15 +963,93 @@ public class BrowserProvider2 extends SQLiteContentProvider { + (selection == null ? "" : " AND (" + selection + ")"); return mSyncHelper.delete(db, selectionWithId, selectionArgs); } + case LEGACY_ID: { + selection = DatabaseUtils.concatenateWhere( + selection, Combined._ID + " = CAST(? AS INTEGER)"); + selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs, + new String[] { Long.toString(ContentUris.parseId(uri)) }); + // fall through + } + case LEGACY: { + String[] projection = new String[] { Combined._ID, + Combined.IS_BOOKMARK, Combined.URL }; + SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + uri = BookmarkUtils.addAccountInfo(getContext(), uri.buildUpon()) + .build(); + String[] args = createCombinedQuery(uri, projection, qb); + if (selectionArgs == null) { + selectionArgs = args; + } else { + selectionArgs = DatabaseUtils.appendSelectionArgs( + args, selectionArgs); + } + Cursor c = qb.query(db, projection, selection, selectionArgs, + null, null, null); + int deleted = 0; + while (c.moveToNext()) { + long id = c.getLong(0); + boolean isBookmark = c.getInt(1) != 0; + String url = c.getString(2); + if (isBookmark) { + deleted += deleteBookmarks(Bookmarks._ID + "=?", + new String[] { Long.toString(id) }, + callerIsSyncAdapter); + db.delete(TABLE_HISTORY, History.URL + "=?", + new String[] { url }); + } else { + deleted += db.delete(TABLE_HISTORY, + Bookmarks._ID + "=?", + new String[] { Long.toString(id) }); + } + } + return deleted; + } } throw new UnsupportedOperationException("Unknown update URI " + uri); } + long queryDefaultFolderId(String accountName, String accountType) { + if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { + final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); + Cursor c = db.query(TABLE_BOOKMARKS, new String[] { Bookmarks._ID }, + ChromeSyncColumns.SERVER_UNIQUE + " = ?" + + " AND account_type = ? AND account_name = ?", + new String[] { ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR, + accountType, accountName }, null, null, null); + if (c.moveToFirst()) { + return c.getLong(0); + } + } + return FIXED_ID_ROOT; + } + @Override public Uri insertInTransaction(Uri uri, ContentValues values, boolean callerIsSyncAdapter) { - final int match = URI_MATCHER.match(uri); + int match = URI_MATCHER.match(uri); final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); long id = -1; + if (match == LEGACY) { + // Intercept and route to the correct table + Integer bookmark = values.getAsInteger(BookmarkColumns.BOOKMARK); + values.remove(BookmarkColumns.BOOKMARK); + if (bookmark == null || bookmark == 0) { + match = HISTORY; + } else { + match = BOOKMARKS; + values.remove(BookmarkColumns.DATE); + values.remove(BookmarkColumns.VISITS); + values.remove(BookmarkColumns.USER_ENTERED); + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getContext()); + String accountType = prefs.getString( + BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null); + String accountName = prefs.getString( + BrowserBookmarksPage.PREF_ACCOUNT_NAME, null); + values.put(Bookmarks.ACCOUNT_TYPE, accountType); + values.put(Bookmarks.ACCOUNT_NAME, accountName); + values.put(Bookmarks.IS_FOLDER, 0); + } + } switch (match) { case BOOKMARKS: { // Mark rows dirty if they're not coming from a sync adapter @@ -897,9 +1060,13 @@ public class BrowserProvider2 extends SQLiteContentProvider { values.put(Bookmarks.DIRTY, 1); // If no parent is set default to the "Bookmarks Bar" folder - // TODO set the parent based on the account info if (!values.containsKey(Bookmarks.PARENT)) { - values.put(Bookmarks.PARENT, FIXED_ID_ROOT); + String accountType = values + .getAsString(Bookmarks.ACCOUNT_TYPE); + String accountName = values + .getAsString(Bookmarks.ACCOUNT_NAME); + values.put(Bookmarks.PARENT, + queryDefaultFolderId(accountName, accountType)); } } @@ -1052,8 +1219,29 @@ public class BrowserProvider2 extends SQLiteContentProvider { @Override public int updateInTransaction(Uri uri, ContentValues values, String selection, String[] selectionArgs, boolean callerIsSyncAdapter) { - final int match = URI_MATCHER.match(uri); + int match = URI_MATCHER.match(uri); final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); + if (match == LEGACY || match == LEGACY_ID) { + // Intercept and route to the correct table + Integer bookmark = values.getAsInteger(BookmarkColumns.BOOKMARK); + values.remove(BookmarkColumns.BOOKMARK); + if (bookmark == null || bookmark == 0) { + if (match == LEGACY) { + match = HISTORY; + } else { + match = HISTORY_ID; + } + } else { + if (match == LEGACY) { + match = BOOKMARKS; + } else { + match = BOOKMARKS_ID; + } + values.remove(BookmarkColumns.DATE); + values.remove(BookmarkColumns.VISITS); + values.remove(BookmarkColumns.USER_ENTERED); + } + } switch (match) { case BOOKMARKS_ID: { selection = DatabaseUtils.concatenateWhere(selection, @@ -1267,4 +1455,96 @@ public class BrowserProvider2 extends SQLiteContentProvider { } return imageValues; } + + static class SuggestionsCursor extends AbstractCursor { + private static final int URL_INDEX = 1; + private static final int TITLE_INDEX = 2; + // shared suggestion array index, make sure to match COLUMNS + private static final int SUGGEST_COLUMN_INTENT_ACTION_ID = 1; + private static final int SUGGEST_COLUMN_INTENT_DATA_ID = 2; + private static final int SUGGEST_COLUMN_TEXT_1_ID = 3; + private static final int SUGGEST_COLUMN_TEXT_2_TEXT_ID = 4; + private static final int SUGGEST_COLUMN_TEXT_2_URL_ID = 5; + private static final int SUGGEST_COLUMN_ICON_1_ID = 6; + + // shared suggestion columns + private static final String[] COLUMNS = new String[] { + BaseColumns._ID, + SearchManager.SUGGEST_COLUMN_INTENT_ACTION, + SearchManager.SUGGEST_COLUMN_INTENT_DATA, + SearchManager.SUGGEST_COLUMN_TEXT_1, + SearchManager.SUGGEST_COLUMN_TEXT_2, + SearchManager.SUGGEST_COLUMN_TEXT_2_URL, + SearchManager.SUGGEST_COLUMN_ICON_1}; + + private Cursor mSource; + + public SuggestionsCursor(Cursor cursor) { + mSource = cursor; + } + + @Override + public String[] getColumnNames() { + return COLUMNS; + } + + @Override + public String getString(int columnIndex) { + switch (columnIndex) { + case 0: + return mSource.getString(columnIndex); + case SUGGEST_COLUMN_INTENT_ACTION_ID: + return Intent.ACTION_VIEW; + case SUGGEST_COLUMN_INTENT_DATA_ID: + case SUGGEST_COLUMN_TEXT_2_TEXT_ID: + case SUGGEST_COLUMN_TEXT_2_URL_ID: + return mSource.getString(URL_INDEX); + case SUGGEST_COLUMN_TEXT_1_ID: + return mSource.getString(TITLE_INDEX); + case SUGGEST_COLUMN_ICON_1_ID: + return Integer.toString(R.drawable.ic_favorite_off_normal); + } + return null; + } + + @Override + public int getCount() { + return mSource.getCount(); + } + + @Override + public double getDouble(int column) { + throw new UnsupportedOperationException(); + } + + @Override + public float getFloat(int column) { + throw new UnsupportedOperationException(); + } + + @Override + public int getInt(int column) { + throw new UnsupportedOperationException(); + } + + @Override + public long getLong(int column) { + throw new UnsupportedOperationException(); + } + + @Override + public short getShort(int column) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isNull(int column) { + return getString(column) == null; + } + + @Override + public boolean onMove(int oldPosition, int newPosition) { + return mSource.moveToPosition(newPosition); + } + } } |