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:
Edouard Oger 2017-04-07 12:24:46 -04:00
Родитель 96c75ddc3d
Коммит c48ef3d269
4 изменённых файлов: 162 добавлений и 1 удалений

Просмотреть файл

@ -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,...]

Двоичный файл не отображается.