зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1351805 part 2 - Add remote devices to the Browser Provider. r=Grisha
MozReview-Commit-ID: 9yGU2Gy6mX1 --HG-- extra : rebase_source : 43557fec627f45e4a5e381233c5a5d3115246153
This commit is contained in:
Родитель
96c75ddc3d
Коммит
c48ef3d269
|
@ -60,6 +60,7 @@ public class BrowserContract {
|
|||
public static final String PARAM_GROUP_BY = "group_by";
|
||||
|
||||
public static final String METHOD_INSERT_HISTORY_WITH_VISITS_FROM_SYNC = "insertHistoryWithVisitsSync";
|
||||
public static final String METHOD_REPLACE_REMOTE_CLIENTS = "replaceRemoteClients";
|
||||
public static final String METHOD_RESULT = "methodResult";
|
||||
public static final String METHOD_PARAM_OBJECT = "object";
|
||||
public static final String METHOD_PARAM_DATA = "data";
|
||||
|
@ -461,6 +462,19 @@ public class BrowserContract {
|
|||
public static final String DEVICE_TYPE = "device_type";
|
||||
}
|
||||
|
||||
public static final class RemoteDevices implements CommonColumns, DateSyncColumns {
|
||||
private RemoteDevices() {}
|
||||
public static final String TABLE_NAME = "remote_devices";
|
||||
|
||||
public static final String GUID = "guid"; // FxA device ID
|
||||
public static final String NAME = "name";
|
||||
public static final String TYPE = "type";
|
||||
public static final String IS_CURRENT_DEVICE = "is_current_device";
|
||||
public static final String LAST_ACCESS_TIME = "last_access_time";
|
||||
|
||||
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "remote_devices");
|
||||
}
|
||||
|
||||
// Data storage for dynamic panels on about:home
|
||||
@RobocopTarget
|
||||
public static final class HomeItems implements CommonColumns {
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.mozilla.gecko.db.BrowserContract.ActivityStreamBlocklist;
|
|||
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
|
||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||
import org.mozilla.gecko.db.BrowserContract.Favicons;
|
||||
import org.mozilla.gecko.db.BrowserContract.RemoteDevices;
|
||||
import org.mozilla.gecko.db.BrowserContract.History;
|
||||
import org.mozilla.gecko.db.BrowserContract.Visits;
|
||||
import org.mozilla.gecko.db.BrowserContract.PageMetadata;
|
||||
|
@ -60,7 +61,7 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
|||
|
||||
// Replace the Bug number below with your Bug that is conducting a DB upgrade, as to force a merge conflict with any
|
||||
// other patches that require a DB upgrade.
|
||||
public static final int DATABASE_VERSION = 36; // Bug 1301717
|
||||
public static final int DATABASE_VERSION = 37; // Bug 1351805
|
||||
public static final String DATABASE_NAME = "browser.db";
|
||||
|
||||
final protected Context mContext;
|
||||
|
@ -69,6 +70,7 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
|||
static final String TABLE_HISTORY = History.TABLE_NAME;
|
||||
static final String TABLE_VISITS = Visits.TABLE_NAME;
|
||||
static final String TABLE_PAGE_METADATA = PageMetadata.TABLE_NAME;
|
||||
static final String TABLE_REMOTE_DEVICES = RemoteDevices.TABLE_NAME;
|
||||
static final String TABLE_FAVICONS = Favicons.TABLE_NAME;
|
||||
static final String TABLE_THUMBNAILS = Thumbnails.TABLE_NAME;
|
||||
static final String TABLE_READING_LIST = ReadingListItems.TABLE_NAME;
|
||||
|
@ -236,6 +238,21 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
|||
+ PageMetadata.HISTORY_GUID + ", " + PageMetadata.HAS_IMAGE + ")");
|
||||
}
|
||||
|
||||
private void createRemoteDevicesTable(SQLiteDatabase db) {
|
||||
debug("Creating " + TABLE_REMOTE_DEVICES + " table");
|
||||
db.execSQL("CREATE TABLE " + TABLE_REMOTE_DEVICES + "(" +
|
||||
RemoteDevices._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
|
||||
RemoteDevices.GUID + " TEXT UNIQUE NOT NULL," +
|
||||
RemoteDevices.NAME + " TEXT NOT NULL," +
|
||||
RemoteDevices.TYPE + " TEXT NOT NULL," +
|
||||
RemoteDevices.IS_CURRENT_DEVICE + " INTEGER NOT NULL," +
|
||||
RemoteDevices.DATE_CREATED + " INTEGER NOT NULL," + // Timestamp - in milliseconds.
|
||||
RemoteDevices.DATE_MODIFIED + " INTEGER NOT NULL," +
|
||||
RemoteDevices.LAST_ACCESS_TIME + " INTEGER NOT NULL" + // Timestamp - in milliseconds.
|
||||
");");
|
||||
// Creating an index is not worth it, because most users have less than 3 devices.
|
||||
}
|
||||
|
||||
private void createBookmarksWithFaviconsView(SQLiteDatabase db) {
|
||||
debug("Creating " + VIEW_BOOKMARKS_WITH_FAVICONS + " view");
|
||||
|
||||
|
@ -751,6 +768,8 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
|||
createActivityStreamBlocklistTable(db);
|
||||
|
||||
createPageMetadataTable(db);
|
||||
|
||||
createRemoteDevicesTable(db);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1980,6 +1999,10 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
|||
createPageMetadataTable(db);
|
||||
}
|
||||
|
||||
private void upgradeDatabaseFrom36to37(final SQLiteDatabase db) {
|
||||
createRemoteDevicesTable(db);
|
||||
}
|
||||
|
||||
private void createV33CombinedView(final SQLiteDatabase db) {
|
||||
db.execSQL("DROP VIEW IF EXISTS " + VIEW_COMBINED);
|
||||
db.execSQL("DROP VIEW IF EXISTS " + VIEW_COMBINED_WITH_FAVICONS);
|
||||
|
@ -2115,6 +2138,10 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
|||
case 36:
|
||||
upgradeDatabaseFrom35to36(db);
|
||||
break;
|
||||
|
||||
case 37:
|
||||
upgradeDatabaseFrom36to37(db);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.mozilla.gecko.db.BrowserContract.Bookmarks;
|
|||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||
import org.mozilla.gecko.db.BrowserContract.FaviconColumns;
|
||||
import org.mozilla.gecko.db.BrowserContract.Favicons;
|
||||
import org.mozilla.gecko.db.BrowserContract.RemoteDevices;
|
||||
import org.mozilla.gecko.db.BrowserContract.Highlights;
|
||||
import org.mozilla.gecko.db.BrowserContract.History;
|
||||
import org.mozilla.gecko.db.BrowserContract.Visits;
|
||||
|
@ -94,6 +95,7 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
static final String TABLE_URL_ANNOTATIONS = UrlAnnotations.TABLE_NAME;
|
||||
static final String TABLE_ACTIVITY_STREAM_BLOCKLIST = ActivityStreamBlocklist.TABLE_NAME;
|
||||
static final String TABLE_PAGE_METADATA = PageMetadata.TABLE_NAME;
|
||||
static final String TABLE_REMOTE_DEVICES = RemoteDevices.TABLE_NAME;
|
||||
|
||||
static final String VIEW_COMBINED = Combined.VIEW_NAME;
|
||||
static final String VIEW_BOOKMARKS_WITH_FAVICONS = Bookmarks.VIEW_WITH_FAVICONS;
|
||||
|
@ -147,6 +149,9 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
|
||||
static final int PAGE_METADATA = 1500;
|
||||
|
||||
static final int REMOTE_DEVICES = 1600;
|
||||
static final int REMOTE_DEVICES_ID = 1601;
|
||||
|
||||
static final String DEFAULT_BOOKMARKS_SORT_ORDER = Bookmarks.TYPE
|
||||
+ " ASC, " + Bookmarks.POSITION + " ASC, " + Bookmarks._ID
|
||||
+ " ASC";
|
||||
|
@ -165,6 +170,7 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
static final Map<String, String> URL_ANNOTATIONS_PROJECTION_MAP;
|
||||
static final Map<String, String> VISIT_PROJECTION_MAP;
|
||||
static final Map<String, String> PAGE_METADATA_PROJECTION_MAP;
|
||||
static final Map<String, String> REMOTE_DEVICES_PROJECTION_MAP;
|
||||
static final Table[] sTables;
|
||||
|
||||
static {
|
||||
|
@ -324,6 +330,21 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
URI_MATCHER.addURI(BrowserContract.AUTHORITY, ActivityStreamBlocklist.TABLE_NAME, ACTIVITY_STREAM_BLOCKLIST);
|
||||
|
||||
URI_MATCHER.addURI(BrowserContract.AUTHORITY, "highlight_candidates", HIGHLIGHT_CANDIDATES);
|
||||
|
||||
// FxA Devices
|
||||
URI_MATCHER.addURI(BrowserContract.AUTHORITY, "remote_devices", REMOTE_DEVICES);
|
||||
URI_MATCHER.addURI(BrowserContract.AUTHORITY, "remote_devices/#", REMOTE_DEVICES_ID);
|
||||
|
||||
map = new HashMap<>();
|
||||
map.put(RemoteDevices._ID, RemoteDevices._ID);
|
||||
map.put(RemoteDevices.GUID, RemoteDevices.GUID);
|
||||
map.put(RemoteDevices.NAME, RemoteDevices.NAME);
|
||||
map.put(RemoteDevices.TYPE, RemoteDevices.TYPE);
|
||||
map.put(RemoteDevices.IS_CURRENT_DEVICE, RemoteDevices.IS_CURRENT_DEVICE);
|
||||
map.put(RemoteDevices.DATE_CREATED, RemoteDevices.DATE_CREATED);
|
||||
map.put(RemoteDevices.DATE_MODIFIED, RemoteDevices.DATE_MODIFIED);
|
||||
map.put(RemoteDevices.LAST_ACCESS_TIME, RemoteDevices.LAST_ACCESS_TIME);
|
||||
REMOTE_DEVICES_PROJECTION_MAP = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
private static class ShrinkMemoryReceiver extends BroadcastReceiver {
|
||||
|
@ -649,6 +670,20 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
deleted = deletePageMetadata(uri, selection, selectionArgs);
|
||||
break;
|
||||
|
||||
case REMOTE_DEVICES_ID:
|
||||
debug("Delete on REMOTE_DEVICES_ID: " + uri);
|
||||
|
||||
selection = DBUtils.concatenateWhere(selection, TABLE_REMOTE_DEVICES + "._ID = ?");
|
||||
selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
|
||||
new String[] { Long.toString(ContentUris.parseId(uri)) });
|
||||
// fall through
|
||||
case REMOTE_DEVICES: {
|
||||
trace("Deleting FxA devices: " + uri);
|
||||
beginWrite(db);
|
||||
deleted = deleteRemoteDevices(uri, selection, selectionArgs);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
Table table = findTableFor(match);
|
||||
if (table == null) {
|
||||
|
@ -721,6 +756,12 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
break;
|
||||
}
|
||||
|
||||
case REMOTE_DEVICES: {
|
||||
trace("Insert on REMOTE_DEVICES: " + uri);
|
||||
id = insertFxADevice(uri, values);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
Table table = findTableFor(match);
|
||||
if (table == null) {
|
||||
|
@ -1391,6 +1432,20 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
break;
|
||||
}
|
||||
|
||||
case REMOTE_DEVICES_ID:
|
||||
selection = DBUtils.concatenateWhere(selection, RemoteDevices._ID + " = ?");
|
||||
selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
|
||||
new String[] { Long.toString(ContentUris.parseId(uri)) });
|
||||
// fall through
|
||||
case REMOTE_DEVICES: {
|
||||
debug("FxA devices query: " + uri);
|
||||
|
||||
qb.setProjectionMap(REMOTE_DEVICES_PROJECTION_MAP);
|
||||
qb.setTables(TABLE_REMOTE_DEVICES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
Table table = findTableFor(match);
|
||||
if (table == null) {
|
||||
|
@ -1997,6 +2052,13 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
TABLE_PAGE_METADATA, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||
}
|
||||
|
||||
private long insertFxADevice(final Uri uri, final ContentValues values) {
|
||||
final SQLiteDatabase db = getWritableDatabase(uri);
|
||||
|
||||
beginWrite(db);
|
||||
return db.insertOrThrow(TABLE_REMOTE_DEVICES, null, values);
|
||||
}
|
||||
|
||||
private long insertUrlAnnotation(final Uri uri, final ContentValues values) {
|
||||
final String url = values.getAsString(UrlAnnotations.URL);
|
||||
trace("Inserting url annotations for URL: " + url);
|
||||
|
@ -2020,6 +2082,13 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
return db.delete(TABLE_PAGE_METADATA, selection, selectionArgs);
|
||||
}
|
||||
|
||||
private int deleteRemoteDevices(final Uri uri, final String selection, final String[] selectionArgs) {
|
||||
trace("Deleting FxA Devices for URI: " + uri);
|
||||
|
||||
final SQLiteDatabase db = getWritableDatabase(uri);
|
||||
return db.delete(TABLE_REMOTE_DEVICES, selection, selectionArgs);
|
||||
}
|
||||
|
||||
private void updateUrlAnnotation(final Uri uri, final ContentValues values, final String selection, final String[] selectionArgs) {
|
||||
trace("Updating url annotation for URI: " + uri);
|
||||
|
||||
|
@ -2275,6 +2344,23 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
result.putSerializable(BrowserContract.METHOD_RESULT, e);
|
||||
}
|
||||
break;
|
||||
case BrowserContract.METHOD_REPLACE_REMOTE_CLIENTS:
|
||||
try {
|
||||
final Uri uri = RemoteDevices.CONTENT_URI
|
||||
.buildUpon()
|
||||
.appendQueryParameter(BrowserContract.PARAM_PROFILE,
|
||||
Uri.parse(uriArg).getQueryParameter(BrowserContract.PARAM_PROFILE))
|
||||
.build();
|
||||
bulkReplaceRemoteDevices(uri, extras);
|
||||
result.putSerializable(BrowserContract.METHOD_RESULT, null);
|
||||
|
||||
// If anything went wrong during insertion, we know that changes were rolled back.
|
||||
// Inform our caller that we have failed.
|
||||
} catch (Exception e) {
|
||||
Log.e(LOGTAG, "Unexpected error while bulk inserting remote clients", e);
|
||||
result.putSerializable(BrowserContract.METHOD_RESULT, e);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown method call: " + method);
|
||||
}
|
||||
|
@ -2282,6 +2368,40 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
|||
return result;
|
||||
}
|
||||
|
||||
private void bulkReplaceRemoteDevices(final Uri uri, @NonNull Bundle dataBundle) {
|
||||
final ContentValues[] values = (ContentValues[]) dataBundle.getParcelableArray(BrowserContract.METHOD_PARAM_DATA);
|
||||
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("Received null recordBundle while bulk inserting remote clients.");
|
||||
}
|
||||
|
||||
final SQLiteDatabase db = getWritableDatabase(uri);
|
||||
|
||||
// Wrap everything in a transaction.
|
||||
beginBatch(db);
|
||||
|
||||
try {
|
||||
// First purge our list of remote devices.
|
||||
// We pass "1" to get a count of the affected rows (see SQLiteDatabase#delete)
|
||||
int count = deleteInTransaction(uri, "1", null);
|
||||
Log.i(LOGTAG, "Deleted " + count + " remote devices.");
|
||||
|
||||
// Then insert the new ones.
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
try {
|
||||
insertFxADevice(uri, values[i]);
|
||||
} catch (Exception e) {
|
||||
Log.e(LOGTAG, "Could not insert device with ID " + values[i].getAsString(RemoteDevices.GUID) + ": " + e);
|
||||
}
|
||||
}
|
||||
markBatchSuccessful(db);
|
||||
} finally {
|
||||
endBatch(db);
|
||||
}
|
||||
|
||||
getContext().getContentResolver().notifyChange(uri, null, false);
|
||||
}
|
||||
|
||||
private void bulkInsertHistoryWithVisits(final SQLiteDatabase db, @NonNull Bundle dataBundle) {
|
||||
// NB: dataBundle structure:
|
||||
// Key METHOD_PARAM_DATA=[Bundle,...]
|
||||
|
|
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче