зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1351805) for android Test failures a=backout
Backed out changeset da34da5f310a (bug 1351805) Backed out changeset 430b56176e04 (bug 1351805) Backed out changeset a3dfb4b9dc66 (bug 1351805) MozReview-Commit-ID: AE4RcKV3akz
This commit is contained in:
Родитель
ae260ad8c3
Коммит
c9b3f40856
|
@ -831,11 +831,10 @@ sync_java_files = [TOPSRCDIR + '/mobile/android/services/src/main/java/org/mozil
|
||||||
'fxa/authenticator/FxAccountLoginDelegate.java',
|
'fxa/authenticator/FxAccountLoginDelegate.java',
|
||||||
'fxa/authenticator/FxAccountLoginException.java',
|
'fxa/authenticator/FxAccountLoginException.java',
|
||||||
'fxa/authenticator/FxADefaultLoginStateMachineDelegate.java',
|
'fxa/authenticator/FxADefaultLoginStateMachineDelegate.java',
|
||||||
'fxa/devices/FxAccountDevice.java',
|
|
||||||
'fxa/devices/FxAccountDeviceListUpdater.java',
|
|
||||||
'fxa/devices/FxAccountDeviceRegistrator.java',
|
|
||||||
'fxa/FirefoxAccounts.java',
|
'fxa/FirefoxAccounts.java',
|
||||||
'fxa/FxAccountConstants.java',
|
'fxa/FxAccountConstants.java',
|
||||||
|
'fxa/FxAccountDevice.java',
|
||||||
|
'fxa/FxAccountDeviceRegistrator.java',
|
||||||
'fxa/FxAccountPushHandler.java',
|
'fxa/FxAccountPushHandler.java',
|
||||||
'fxa/login/BaseRequestDelegate.java',
|
'fxa/login/BaseRequestDelegate.java',
|
||||||
'fxa/login/Cohabiting.java',
|
'fxa/login/Cohabiting.java',
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.json.JSONException;
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountUtils;
|
import org.mozilla.gecko.background.fxa.FxAccountUtils;
|
||||||
import org.mozilla.gecko.fxa.FirefoxAccounts;
|
import org.mozilla.gecko.fxa.FirefoxAccounts;
|
||||||
import org.mozilla.gecko.fxa.FxAccountConstants;
|
import org.mozilla.gecko.fxa.FxAccountConstants;
|
||||||
|
import org.mozilla.gecko.fxa.FxAccountDeviceRegistrator;
|
||||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||||
import org.mozilla.gecko.fxa.login.Engaged;
|
import org.mozilla.gecko.fxa.login.Engaged;
|
||||||
import org.mozilla.gecko.fxa.login.State;
|
import org.mozilla.gecko.fxa.login.State;
|
||||||
|
|
|
@ -60,7 +60,6 @@ public class BrowserContract {
|
||||||
public static final String PARAM_GROUP_BY = "group_by";
|
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_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_RESULT = "methodResult";
|
||||||
public static final String METHOD_PARAM_OBJECT = "object";
|
public static final String METHOD_PARAM_OBJECT = "object";
|
||||||
public static final String METHOD_PARAM_DATA = "data";
|
public static final String METHOD_PARAM_DATA = "data";
|
||||||
|
@ -462,19 +461,6 @@ public class BrowserContract {
|
||||||
public static final String DEVICE_TYPE = "device_type";
|
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
|
// Data storage for dynamic panels on about:home
|
||||||
@RobocopTarget
|
@RobocopTarget
|
||||||
public static final class HomeItems implements CommonColumns {
|
public static final class HomeItems implements CommonColumns {
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.mozilla.gecko.db.BrowserContract.ActivityStreamBlocklist;
|
||||||
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
|
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
|
||||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||||
import org.mozilla.gecko.db.BrowserContract.Favicons;
|
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.History;
|
||||||
import org.mozilla.gecko.db.BrowserContract.Visits;
|
import org.mozilla.gecko.db.BrowserContract.Visits;
|
||||||
import org.mozilla.gecko.db.BrowserContract.PageMetadata;
|
import org.mozilla.gecko.db.BrowserContract.PageMetadata;
|
||||||
|
@ -61,7 +60,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
|
// 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.
|
// other patches that require a DB upgrade.
|
||||||
public static final int DATABASE_VERSION = 37; // Bug 1351805
|
public static final int DATABASE_VERSION = 36; // Bug 1301717
|
||||||
public static final String DATABASE_NAME = "browser.db";
|
public static final String DATABASE_NAME = "browser.db";
|
||||||
|
|
||||||
final protected Context mContext;
|
final protected Context mContext;
|
||||||
|
@ -70,7 +69,6 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
||||||
static final String TABLE_HISTORY = History.TABLE_NAME;
|
static final String TABLE_HISTORY = History.TABLE_NAME;
|
||||||
static final String TABLE_VISITS = Visits.TABLE_NAME;
|
static final String TABLE_VISITS = Visits.TABLE_NAME;
|
||||||
static final String TABLE_PAGE_METADATA = PageMetadata.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_FAVICONS = Favicons.TABLE_NAME;
|
||||||
static final String TABLE_THUMBNAILS = Thumbnails.TABLE_NAME;
|
static final String TABLE_THUMBNAILS = Thumbnails.TABLE_NAME;
|
||||||
static final String TABLE_READING_LIST = ReadingListItems.TABLE_NAME;
|
static final String TABLE_READING_LIST = ReadingListItems.TABLE_NAME;
|
||||||
|
@ -238,21 +236,6 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
||||||
+ PageMetadata.HISTORY_GUID + ", " + PageMetadata.HAS_IMAGE + ")");
|
+ 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) {
|
private void createBookmarksWithFaviconsView(SQLiteDatabase db) {
|
||||||
debug("Creating " + VIEW_BOOKMARKS_WITH_FAVICONS + " view");
|
debug("Creating " + VIEW_BOOKMARKS_WITH_FAVICONS + " view");
|
||||||
|
|
||||||
|
@ -768,8 +751,6 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
||||||
createActivityStreamBlocklistTable(db);
|
createActivityStreamBlocklistTable(db);
|
||||||
|
|
||||||
createPageMetadataTable(db);
|
createPageMetadataTable(db);
|
||||||
|
|
||||||
createRemoteDevicesTable(db);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1999,10 +1980,6 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
||||||
createPageMetadataTable(db);
|
createPageMetadataTable(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void upgradeDatabaseFrom36to37(final SQLiteDatabase db) {
|
|
||||||
createRemoteDevicesTable(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createV33CombinedView(final SQLiteDatabase db) {
|
private void createV33CombinedView(final SQLiteDatabase db) {
|
||||||
db.execSQL("DROP VIEW IF EXISTS " + VIEW_COMBINED);
|
db.execSQL("DROP VIEW IF EXISTS " + VIEW_COMBINED);
|
||||||
db.execSQL("DROP VIEW IF EXISTS " + VIEW_COMBINED_WITH_FAVICONS);
|
db.execSQL("DROP VIEW IF EXISTS " + VIEW_COMBINED_WITH_FAVICONS);
|
||||||
|
@ -2138,10 +2115,6 @@ public final class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
||||||
case 36:
|
case 36:
|
||||||
upgradeDatabaseFrom35to36(db);
|
upgradeDatabaseFrom35to36(db);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 37:
|
|
||||||
upgradeDatabaseFrom36to37(db);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import org.mozilla.gecko.db.BrowserContract.Bookmarks;
|
||||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||||
import org.mozilla.gecko.db.BrowserContract.FaviconColumns;
|
import org.mozilla.gecko.db.BrowserContract.FaviconColumns;
|
||||||
import org.mozilla.gecko.db.BrowserContract.Favicons;
|
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.Highlights;
|
||||||
import org.mozilla.gecko.db.BrowserContract.History;
|
import org.mozilla.gecko.db.BrowserContract.History;
|
||||||
import org.mozilla.gecko.db.BrowserContract.Visits;
|
import org.mozilla.gecko.db.BrowserContract.Visits;
|
||||||
|
@ -95,7 +94,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
static final String TABLE_URL_ANNOTATIONS = UrlAnnotations.TABLE_NAME;
|
static final String TABLE_URL_ANNOTATIONS = UrlAnnotations.TABLE_NAME;
|
||||||
static final String TABLE_ACTIVITY_STREAM_BLOCKLIST = ActivityStreamBlocklist.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_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_COMBINED = Combined.VIEW_NAME;
|
||||||
static final String VIEW_BOOKMARKS_WITH_FAVICONS = Bookmarks.VIEW_WITH_FAVICONS;
|
static final String VIEW_BOOKMARKS_WITH_FAVICONS = Bookmarks.VIEW_WITH_FAVICONS;
|
||||||
|
@ -149,9 +147,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
|
|
||||||
static final int PAGE_METADATA = 1500;
|
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
|
static final String DEFAULT_BOOKMARKS_SORT_ORDER = Bookmarks.TYPE
|
||||||
+ " ASC, " + Bookmarks.POSITION + " ASC, " + Bookmarks._ID
|
+ " ASC, " + Bookmarks.POSITION + " ASC, " + Bookmarks._ID
|
||||||
+ " ASC";
|
+ " ASC";
|
||||||
|
@ -170,7 +165,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
static final Map<String, String> URL_ANNOTATIONS_PROJECTION_MAP;
|
static final Map<String, String> URL_ANNOTATIONS_PROJECTION_MAP;
|
||||||
static final Map<String, String> VISIT_PROJECTION_MAP;
|
static final Map<String, String> VISIT_PROJECTION_MAP;
|
||||||
static final Map<String, String> PAGE_METADATA_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 final Table[] sTables;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -330,21 +324,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
URI_MATCHER.addURI(BrowserContract.AUTHORITY, ActivityStreamBlocklist.TABLE_NAME, ACTIVITY_STREAM_BLOCKLIST);
|
URI_MATCHER.addURI(BrowserContract.AUTHORITY, ActivityStreamBlocklist.TABLE_NAME, ACTIVITY_STREAM_BLOCKLIST);
|
||||||
|
|
||||||
URI_MATCHER.addURI(BrowserContract.AUTHORITY, "highlight_candidates", HIGHLIGHT_CANDIDATES);
|
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 {
|
private static class ShrinkMemoryReceiver extends BroadcastReceiver {
|
||||||
|
@ -670,20 +649,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
deleted = deletePageMetadata(uri, selection, selectionArgs);
|
deleted = deletePageMetadata(uri, selection, selectionArgs);
|
||||||
break;
|
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: {
|
default: {
|
||||||
Table table = findTableFor(match);
|
Table table = findTableFor(match);
|
||||||
if (table == null) {
|
if (table == null) {
|
||||||
|
@ -756,12 +721,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case REMOTE_DEVICES: {
|
|
||||||
trace("Insert on REMOTE_DEVICES: " + uri);
|
|
||||||
id = insertFxADevice(uri, values);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
Table table = findTableFor(match);
|
Table table = findTableFor(match);
|
||||||
if (table == null) {
|
if (table == null) {
|
||||||
|
@ -1432,20 +1391,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
break;
|
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: {
|
default: {
|
||||||
Table table = findTableFor(match);
|
Table table = findTableFor(match);
|
||||||
if (table == null) {
|
if (table == null) {
|
||||||
|
@ -2052,13 +1997,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
TABLE_PAGE_METADATA, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
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) {
|
private long insertUrlAnnotation(final Uri uri, final ContentValues values) {
|
||||||
final String url = values.getAsString(UrlAnnotations.URL);
|
final String url = values.getAsString(UrlAnnotations.URL);
|
||||||
trace("Inserting url annotations for URL: " + url);
|
trace("Inserting url annotations for URL: " + url);
|
||||||
|
@ -2082,13 +2020,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
return db.delete(TABLE_PAGE_METADATA, selection, selectionArgs);
|
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) {
|
private void updateUrlAnnotation(final Uri uri, final ContentValues values, final String selection, final String[] selectionArgs) {
|
||||||
trace("Updating url annotation for URI: " + uri);
|
trace("Updating url annotation for URI: " + uri);
|
||||||
|
|
||||||
|
@ -2344,23 +2275,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
result.putSerializable(BrowserContract.METHOD_RESULT, e);
|
result.putSerializable(BrowserContract.METHOD_RESULT, e);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown method call: " + method);
|
throw new IllegalArgumentException("Unknown method call: " + method);
|
||||||
}
|
}
|
||||||
|
@ -2368,40 +2282,6 @@ public class BrowserProvider extends SharedBrowserDatabaseProvider {
|
||||||
return result;
|
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) {
|
private void bulkInsertHistoryWithVisits(final SQLiteDatabase db, @NonNull Bundle dataBundle) {
|
||||||
// NB: dataBundle structure:
|
// NB: dataBundle structure:
|
||||||
// Key METHOD_PARAM_DATA=[Bundle,...]
|
// Key METHOD_PARAM_DATA=[Bundle,...]
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.mozilla.gecko.TelemetryContract;
|
||||||
import org.mozilla.gecko.annotation.ReflectionTarget;
|
import org.mozilla.gecko.annotation.ReflectionTarget;
|
||||||
import org.mozilla.gecko.db.BrowserDB;
|
import org.mozilla.gecko.db.BrowserDB;
|
||||||
import org.mozilla.gecko.fxa.FxAccountConstants;
|
import org.mozilla.gecko.fxa.FxAccountConstants;
|
||||||
import org.mozilla.gecko.fxa.devices.FxAccountDeviceRegistrator;
|
import org.mozilla.gecko.fxa.FxAccountDeviceRegistrator;
|
||||||
import org.mozilla.gecko.fxa.FxAccountPushHandler;
|
import org.mozilla.gecko.fxa.FxAccountPushHandler;
|
||||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||||
import org.mozilla.gecko.fxa.login.State;
|
import org.mozilla.gecko.fxa.login.State;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import org.mozilla.gecko.background.fxa.FxAccountClient20.AccountStatusResponse;
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClient20.RecoveryEmailStatusResponse;
|
import org.mozilla.gecko.background.fxa.FxAccountClient20.RecoveryEmailStatusResponse;
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClient20.RequestDelegate;
|
import org.mozilla.gecko.background.fxa.FxAccountClient20.RequestDelegate;
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClient20.TwoKeys;
|
import org.mozilla.gecko.background.fxa.FxAccountClient20.TwoKeys;
|
||||||
import org.mozilla.gecko.fxa.devices.FxAccountDevice;
|
import org.mozilla.gecko.fxa.FxAccountDevice;
|
||||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClient
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
|
import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
|
||||||
import org.mozilla.gecko.fxa.FxAccountConstants;
|
import org.mozilla.gecko.fxa.FxAccountConstants;
|
||||||
import org.mozilla.gecko.Locales;
|
import org.mozilla.gecko.Locales;
|
||||||
import org.mozilla.gecko.fxa.devices.FxAccountDevice;
|
import org.mozilla.gecko.fxa.FxAccountDevice;
|
||||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
import org.mozilla.gecko.sync.crypto.HKDF;
|
import org.mozilla.gecko.sync.crypto.HKDF;
|
||||||
|
|
|
@ -2,54 +2,48 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
package org.mozilla.gecko.fxa.devices;
|
package org.mozilla.gecko.fxa;
|
||||||
|
|
||||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
|
|
||||||
public class FxAccountDevice {
|
public class FxAccountDevice {
|
||||||
|
|
||||||
private static final String JSON_KEY_NAME = "name";
|
public static final String JSON_KEY_NAME = "name";
|
||||||
private static final String JSON_KEY_ID = "id";
|
public static final String JSON_KEY_ID = "id";
|
||||||
private static final String JSON_KEY_TYPE = "type";
|
public static final String JSON_KEY_TYPE = "type";
|
||||||
private static final String JSON_KEY_ISCURRENTDEVICE = "isCurrentDevice";
|
public static final String JSON_KEY_ISCURRENTDEVICE = "isCurrentDevice";
|
||||||
private static final String JSON_KEY_PUSH_CALLBACK = "pushCallback";
|
public static final String JSON_KEY_PUSH_CALLBACK = "pushCallback";
|
||||||
private static final String JSON_KEY_PUSH_PUBLICKEY = "pushPublicKey";
|
public static final String JSON_KEY_PUSH_PUBLICKEY = "pushPublicKey";
|
||||||
private static final String JSON_KEY_PUSH_AUTHKEY = "pushAuthKey";
|
public static final String JSON_KEY_PUSH_AUTHKEY = "pushAuthKey";
|
||||||
private static final String JSON_LAST_ACCESS_TIME = "lastAccessTime";
|
|
||||||
|
|
||||||
public final String id;
|
public final String id;
|
||||||
public final String name;
|
public final String name;
|
||||||
public final String type;
|
public final String type;
|
||||||
public final Boolean isCurrentDevice;
|
public final Boolean isCurrentDevice;
|
||||||
public final Long lastAccessTime;
|
|
||||||
public final String pushCallback;
|
public final String pushCallback;
|
||||||
public final String pushPublicKey;
|
public final String pushPublicKey;
|
||||||
public final String pushAuthKey;
|
public final String pushAuthKey;
|
||||||
|
|
||||||
public FxAccountDevice(String name, String id, String type, Boolean isCurrentDevice,
|
public FxAccountDevice(String name, String id, String type, Boolean isCurrentDevice,
|
||||||
Long lastAccessTime, String pushCallback, String pushPublicKey,
|
String pushCallback, String pushPublicKey, String pushAuthKey) {
|
||||||
String pushAuthKey) {
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.isCurrentDevice = isCurrentDevice;
|
this.isCurrentDevice = isCurrentDevice;
|
||||||
this.lastAccessTime = lastAccessTime;
|
|
||||||
this.pushCallback = pushCallback;
|
this.pushCallback = pushCallback;
|
||||||
this.pushPublicKey = pushPublicKey;
|
this.pushPublicKey = pushPublicKey;
|
||||||
this.pushAuthKey = pushAuthKey;
|
this.pushAuthKey = pushAuthKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FxAccountDevice fromJson(ExtendedJSONObject json) {
|
public static FxAccountDevice fromJson(ExtendedJSONObject json) {
|
||||||
final String name = json.getString(JSON_KEY_NAME);
|
String name = json.getString(JSON_KEY_NAME);
|
||||||
final String id = json.getString(JSON_KEY_ID);
|
String id = json.getString(JSON_KEY_ID);
|
||||||
final String type = json.getString(JSON_KEY_TYPE);
|
String type = json.getString(JSON_KEY_TYPE);
|
||||||
final Boolean isCurrentDevice = json.getBoolean(JSON_KEY_ISCURRENTDEVICE);
|
Boolean isCurrentDevice = json.getBoolean(JSON_KEY_ISCURRENTDEVICE);
|
||||||
final Long lastAccessTime = json.getLong(JSON_LAST_ACCESS_TIME);
|
String pushCallback = json.getString(JSON_KEY_PUSH_CALLBACK);
|
||||||
final String pushCallback = json.getString(JSON_KEY_PUSH_CALLBACK);
|
String pushPublicKey = json.getString(JSON_KEY_PUSH_PUBLICKEY);
|
||||||
final String pushPublicKey = json.getString(JSON_KEY_PUSH_PUBLICKEY);
|
String pushAuthKey = json.getString(JSON_KEY_PUSH_AUTHKEY);
|
||||||
final String pushAuthKey = json.getString(JSON_KEY_PUSH_AUTHKEY);
|
return new FxAccountDevice(name, id, type, isCurrentDevice, pushCallback, pushPublicKey, pushAuthKey);
|
||||||
return new FxAccountDevice(name, id, type, isCurrentDevice, lastAccessTime, pushCallback,
|
|
||||||
pushPublicKey, pushAuthKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtendedJSONObject toJson() {
|
public ExtendedJSONObject toJson() {
|
||||||
|
@ -79,6 +73,7 @@ public class FxAccountDevice {
|
||||||
private String id;
|
private String id;
|
||||||
private String name;
|
private String name;
|
||||||
private String type;
|
private String type;
|
||||||
|
private Boolean isCurrentDevice;
|
||||||
private String pushCallback;
|
private String pushCallback;
|
||||||
private String pushPublicKey;
|
private String pushPublicKey;
|
||||||
private String pushAuthKey;
|
private String pushAuthKey;
|
||||||
|
@ -95,6 +90,10 @@ public class FxAccountDevice {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void isCurrentDevice() {
|
||||||
|
this.isCurrentDevice = Boolean.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
public void pushCallback(String pushCallback) {
|
public void pushCallback(String pushCallback) {
|
||||||
this.pushCallback = pushCallback;
|
this.pushCallback = pushCallback;
|
||||||
}
|
}
|
||||||
|
@ -108,7 +107,7 @@ public class FxAccountDevice {
|
||||||
}
|
}
|
||||||
|
|
||||||
public FxAccountDevice build() {
|
public FxAccountDevice build() {
|
||||||
return new FxAccountDevice(this.name, this.id, this.type, null, null,
|
return new FxAccountDevice(this.name, this.id, this.type, this.isCurrentDevice,
|
||||||
this.pushCallback, this.pushPublicKey, this.pushAuthKey);
|
this.pushCallback, this.pushPublicKey, this.pushAuthKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
package org.mozilla.gecko.fxa.devices;
|
package org.mozilla.gecko.fxa;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -378,9 +378,8 @@ public class FxAccountDeviceRegistrator implements BundleEventListener {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
final FxAccountDevice updatedDevice = new FxAccountDevice(device.name, fxaDevice.id, device.type,
|
final FxAccountDevice updatedDevice = new FxAccountDevice(device.name, fxaDevice.id, device.type,
|
||||||
null, null,
|
device.isCurrentDevice, device.pushCallback,
|
||||||
device.pushCallback, device.pushPublicKey,
|
device.pushPublicKey, device.pushAuthKey);
|
||||||
device.pushAuthKey);
|
|
||||||
doFxaRegistration(context, fxAccount, updatedDevice, false);
|
doFxaRegistration(context, fxAccount, updatedDevice, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
|
@ -805,15 +805,16 @@ public class AndroidFxAccount {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getUserDataLong(String key, long defaultValue) {
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T extends Number> T getUserDataNumber(String key, T defaultValue) {
|
||||||
final String numStr = accountManager.getUserData(account, key);
|
final String numStr = accountManager.getUserData(account, key);
|
||||||
if (TextUtils.isEmpty(numStr)) {
|
if (TextUtils.isEmpty(numStr)) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return Long.parseLong(key);
|
return (T) NumberFormat.getInstance().parse(numStr);
|
||||||
} catch (NumberFormatException e) {
|
} catch (ParseException e) {
|
||||||
Logger.warn(LOG_TAG, "Couldn't parse " + key + "; defaulting to " + defaultValue, e);
|
Logger.warn(LOG_TAG, "Couldn't parse " + key + "; defaulting to 0L.", e);
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -824,28 +825,19 @@ public class AndroidFxAccount {
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int getDeviceRegistrationVersion() {
|
public synchronized int getDeviceRegistrationVersion() {
|
||||||
final String numStr = accountManager.getUserData(account, ACCOUNT_KEY_DEVICE_REGISTRATION_VERSION);
|
return getUserDataNumber(ACCOUNT_KEY_DEVICE_REGISTRATION_VERSION, 0);
|
||||||
if (TextUtils.isEmpty(numStr)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(numStr);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Logger.warn(LOG_TAG, "Couldn't parse ACCOUNT_KEY_DEVICE_REGISTRATION_VERSION; defaulting to 0", e);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized long getDeviceRegistrationTimestamp() {
|
public synchronized long getDeviceRegistrationTimestamp() {
|
||||||
return getUserDataLong(ACCOUNT_KEY_DEVICE_REGISTRATION_TIMESTAMP, 0L);
|
return getUserDataNumber(ACCOUNT_KEY_DEVICE_REGISTRATION_TIMESTAMP, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized long getDevicePushRegistrationError() {
|
public synchronized long getDevicePushRegistrationError() {
|
||||||
return getUserDataLong(ACCOUNT_KEY_DEVICE_PUSH_REGISTRATION_ERROR, 0L);
|
return getUserDataNumber(ACCOUNT_KEY_DEVICE_PUSH_REGISTRATION_ERROR, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized long getDevicePushRegistrationErrorTime() {
|
public synchronized long getDevicePushRegistrationErrorTime() {
|
||||||
return getUserDataLong(ACCOUNT_KEY_DEVICE_PUSH_REGISTRATION_ERROR_TIME, 0L);
|
return getUserDataNumber(ACCOUNT_KEY_DEVICE_PUSH_REGISTRATION_ERROR_TIME, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setDeviceId(String id) {
|
public synchronized void setDeviceId(String id) {
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
package org.mozilla.gecko.fxa.devices;
|
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.VisibleForTesting;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClient;
|
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClient20;
|
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClientException;
|
|
||||||
import org.mozilla.gecko.db.BrowserContract;
|
|
||||||
import org.mozilla.gecko.db.BrowserContract.RemoteDevices;
|
|
||||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
|
||||||
import org.mozilla.gecko.fxa.login.State;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
public class FxAccountDeviceListUpdater implements FxAccountClient20.RequestDelegate<FxAccountDevice[]> {
|
|
||||||
private static final String LOG_TAG = "FxADeviceListUpdater";
|
|
||||||
|
|
||||||
private final AndroidFxAccount fxAccount;
|
|
||||||
private final ContentResolver contentResolver;
|
|
||||||
|
|
||||||
public FxAccountDeviceListUpdater(final AndroidFxAccount fxAccount, final ContentResolver cr) {
|
|
||||||
this.fxAccount = fxAccount;
|
|
||||||
this.contentResolver = cr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleSuccess(final FxAccountDevice[] result) {
|
|
||||||
final Uri uri = RemoteDevices.CONTENT_URI
|
|
||||||
.buildUpon()
|
|
||||||
.appendQueryParameter(BrowserContract.PARAM_PROFILE, fxAccount.getProfile())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
final Bundle valuesBundle = new Bundle();
|
|
||||||
final ContentValues[] insertValues = new ContentValues[result.length];
|
|
||||||
|
|
||||||
final long now = System.currentTimeMillis();
|
|
||||||
for (int i = 0; i < result.length; i++) {
|
|
||||||
final FxAccountDevice fxADevice = result[i];
|
|
||||||
final ContentValues deviceValues = new ContentValues();
|
|
||||||
deviceValues.put(RemoteDevices.GUID, fxADevice.id);
|
|
||||||
deviceValues.put(RemoteDevices.TYPE, fxADevice.type);
|
|
||||||
deviceValues.put(RemoteDevices.NAME, fxADevice.name);
|
|
||||||
deviceValues.put(RemoteDevices.IS_CURRENT_DEVICE, fxADevice.isCurrentDevice);
|
|
||||||
deviceValues.put(RemoteDevices.DATE_CREATED, now);
|
|
||||||
deviceValues.put(RemoteDevices.DATE_MODIFIED, now);
|
|
||||||
// TODO: Remove that line once FxA sends lastAccessTime all the time.
|
|
||||||
final Long lastAccessTime = fxADevice.lastAccessTime != null ? fxADevice.lastAccessTime : 0;
|
|
||||||
deviceValues.put(RemoteDevices.LAST_ACCESS_TIME, lastAccessTime);
|
|
||||||
insertValues[i] = deviceValues;
|
|
||||||
}
|
|
||||||
valuesBundle.putParcelableArray(BrowserContract.METHOD_PARAM_DATA, insertValues);
|
|
||||||
try {
|
|
||||||
contentResolver.call(uri, BrowserContract.METHOD_REPLACE_REMOTE_CLIENTS, uri.toString(),
|
|
||||||
valuesBundle);
|
|
||||||
Log.i(LOG_TAG, "FxA Device list update done.");
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LOG_TAG, "Error persisting the new remote device list.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleError(Exception e) {
|
|
||||||
onError(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleFailure(FxAccountClientException.FxAccountClientRemoteException e) {
|
|
||||||
onError(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onError(final Exception e) {
|
|
||||||
Log.e(LOG_TAG, "Error while getting the FxA device list.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
FxAccountClient getSynchronousFxaClient() {
|
|
||||||
return new FxAccountClient20(fxAccount.getAccountServerURI(),
|
|
||||||
// Current thread executor :)
|
|
||||||
new Executor() {
|
|
||||||
@Override
|
|
||||||
public void execute(@NonNull Runnable runnable) {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
Log.i(LOG_TAG, "Beginning FxA device list update.");
|
|
||||||
final byte[] sessionToken;
|
|
||||||
try {
|
|
||||||
sessionToken = fxAccount.getState().getSessionToken();
|
|
||||||
} catch (State.NotASessionTokenState e) {
|
|
||||||
// This should never happen, because the caller (FxAccountSyncAdapter) verifies that
|
|
||||||
// we are in a token state before calling this method.
|
|
||||||
throw new IllegalStateException("Could not get a session token during Sync (?) " + e);
|
|
||||||
}
|
|
||||||
final FxAccountClient fxaClient = getSynchronousFxaClient();
|
|
||||||
fxaClient.deviceList(sessionToken, this);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,10 +5,8 @@
|
||||||
package org.mozilla.gecko.fxa.receivers;
|
package org.mozilla.gecko.fxa.receivers;
|
||||||
|
|
||||||
import android.app.IntentService;
|
import android.app.IntentService;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.mozilla.gecko.background.common.log.Logger;
|
import org.mozilla.gecko.background.common.log.Logger;
|
||||||
|
@ -17,7 +15,6 @@ import org.mozilla.gecko.background.fxa.FxAccountClientException;
|
||||||
import org.mozilla.gecko.background.fxa.oauth.FxAccountAbstractClient;
|
import org.mozilla.gecko.background.fxa.oauth.FxAccountAbstractClient;
|
||||||
import org.mozilla.gecko.background.fxa.oauth.FxAccountAbstractClientException.FxAccountAbstractClientRemoteException;
|
import org.mozilla.gecko.background.fxa.oauth.FxAccountAbstractClientException.FxAccountAbstractClientRemoteException;
|
||||||
import org.mozilla.gecko.background.fxa.oauth.FxAccountOAuthClient10;
|
import org.mozilla.gecko.background.fxa.oauth.FxAccountOAuthClient10;
|
||||||
import org.mozilla.gecko.db.BrowserContract;
|
|
||||||
import org.mozilla.gecko.fxa.FxAccountConstants;
|
import org.mozilla.gecko.fxa.FxAccountConstants;
|
||||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||||
import org.mozilla.gecko.fxa.sync.FxAccountNotificationManager;
|
import org.mozilla.gecko.fxa.sync.FxAccountNotificationManager;
|
||||||
|
@ -78,8 +75,6 @@ public class FxAccountDeletedService extends IntentService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearRemoteDevicesList(intent, context);
|
|
||||||
|
|
||||||
// Delete current device the from FxA devices list.
|
// Delete current device the from FxA devices list.
|
||||||
deleteFxADevice(intent);
|
deleteFxADevice(intent);
|
||||||
|
|
||||||
|
@ -164,17 +159,6 @@ public class FxAccountDeletedService extends IntentService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearRemoteDevicesList(Intent intent, Context context) {
|
|
||||||
final Uri remoteDevicesUriWithProfile = BrowserContract.RemoteDevices.CONTENT_URI
|
|
||||||
.buildUpon()
|
|
||||||
.appendQueryParameter(BrowserContract.PARAM_PROFILE,
|
|
||||||
intent.getStringExtra(FxAccountConstants.ACCOUNT_DELETED_INTENT_ACCOUNT_PROFILE))
|
|
||||||
.build();
|
|
||||||
ContentResolver cr = context.getContentResolver();
|
|
||||||
|
|
||||||
cr.delete(remoteDevicesUriWithProfile, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove our current device from the FxA device list.
|
// Remove our current device from the FxA device list.
|
||||||
private void deleteFxADevice(Intent intent) {
|
private void deleteFxADevice(Intent intent) {
|
||||||
final byte[] sessionToken = intent.getByteArrayExtra(FxAccountConstants.ACCOUNT_DELETED_INTENT_ACCOUNT_SESSION_TOKEN);
|
final byte[] sessionToken = intent.getByteArrayExtra(FxAccountConstants.ACCOUNT_DELETED_INTENT_ACCOUNT_SESSION_TOKEN);
|
||||||
|
|
|
@ -6,7 +6,6 @@ package org.mozilla.gecko.fxa.sync;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.content.AbstractThreadedSyncAdapter;
|
import android.content.AbstractThreadedSyncAdapter;
|
||||||
import android.content.ContentProvider;
|
|
||||||
import android.content.ContentProviderClient;
|
import android.content.ContentProviderClient;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -23,8 +22,7 @@ import org.mozilla.gecko.background.fxa.SkewHandler;
|
||||||
import org.mozilla.gecko.browserid.JSONWebTokenUtils;
|
import org.mozilla.gecko.browserid.JSONWebTokenUtils;
|
||||||
import org.mozilla.gecko.fxa.FirefoxAccounts;
|
import org.mozilla.gecko.fxa.FirefoxAccounts;
|
||||||
import org.mozilla.gecko.fxa.FxAccountConstants;
|
import org.mozilla.gecko.fxa.FxAccountConstants;
|
||||||
import org.mozilla.gecko.fxa.devices.FxAccountDeviceListUpdater;
|
import org.mozilla.gecko.fxa.FxAccountDeviceRegistrator;
|
||||||
import org.mozilla.gecko.fxa.devices.FxAccountDeviceRegistrator;
|
|
||||||
import org.mozilla.gecko.fxa.authenticator.AccountPickler;
|
import org.mozilla.gecko.fxa.authenticator.AccountPickler;
|
||||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||||
import org.mozilla.gecko.fxa.authenticator.FxADefaultLoginStateMachineDelegate;
|
import org.mozilla.gecko.fxa.authenticator.FxADefaultLoginStateMachineDelegate;
|
||||||
|
@ -36,6 +34,7 @@ import org.mozilla.gecko.fxa.login.State.StateLabel;
|
||||||
import org.mozilla.gecko.fxa.sync.FxAccountSyncDelegate.Result;
|
import org.mozilla.gecko.fxa.sync.FxAccountSyncDelegate.Result;
|
||||||
import org.mozilla.gecko.sync.BackoffHandler;
|
import org.mozilla.gecko.sync.BackoffHandler;
|
||||||
import org.mozilla.gecko.sync.GlobalSession;
|
import org.mozilla.gecko.sync.GlobalSession;
|
||||||
|
import org.mozilla.gecko.sync.MetaGlobal;
|
||||||
import org.mozilla.gecko.sync.PrefsBackoffHandler;
|
import org.mozilla.gecko.sync.PrefsBackoffHandler;
|
||||||
import org.mozilla.gecko.sync.SharedPreferencesClientsDataDelegate;
|
import org.mozilla.gecko.sync.SharedPreferencesClientsDataDelegate;
|
||||||
import org.mozilla.gecko.sync.SyncConfiguration;
|
import org.mozilla.gecko.sync.SyncConfiguration;
|
||||||
|
@ -420,15 +419,6 @@ public class FxAccountSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSessionTokenStateReached(Context context, AndroidFxAccount fxAccount) {
|
|
||||||
// This does not block the main thread, if work has to be done it is executed in a new thread.
|
|
||||||
maybeRegisterDevice(context, fxAccount);
|
|
||||||
|
|
||||||
FxAccountDeviceListUpdater deviceListUpdater = new FxAccountDeviceListUpdater(fxAccount, context.getContentResolver());
|
|
||||||
// Since the clients stage requires a fresh list of remote devices, we update the device list synchronously.
|
|
||||||
deviceListUpdater.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A trivial Sync implementation that does not cache client keys,
|
* A trivial Sync implementation that does not cache client keys,
|
||||||
* certificates, or tokens.
|
* certificates, or tokens.
|
||||||
|
@ -556,7 +546,7 @@ public class FxAccountSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||||
schedulePolicy.onHandleFinal(notMarried.getNeededAction());
|
schedulePolicy.onHandleFinal(notMarried.getNeededAction());
|
||||||
syncDelegate.handleCannotSync(notMarried);
|
syncDelegate.handleCannotSync(notMarried);
|
||||||
if (notMarried.getStateLabel() == StateLabel.Engaged) {
|
if (notMarried.getStateLabel() == StateLabel.Engaged) {
|
||||||
onSessionTokenStateReached(context, fxAccount);
|
maybeRegisterDevice(context, fxAccount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,8 +589,6 @@ public class FxAccountSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSessionTokenStateReached(context, fxAccount);
|
|
||||||
|
|
||||||
final SessionCallback sessionCallback = new SessionCallback(syncDelegate, schedulePolicy);
|
final SessionCallback sessionCallback = new SessionCallback(syncDelegate, schedulePolicy);
|
||||||
final KeyBundle syncKeyBundle = married.getSyncKeyBundle();
|
final KeyBundle syncKeyBundle = married.getSyncKeyBundle();
|
||||||
final String clientState = married.getClientState();
|
final String clientState = married.getClientState();
|
||||||
|
@ -608,6 +596,8 @@ public class FxAccountSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||||
assertion, tokenServerEndpointURI, tokenBackoffHandler, sharedPrefs,
|
assertion, tokenServerEndpointURI, tokenBackoffHandler, sharedPrefs,
|
||||||
syncKeyBundle, clientState, sessionCallback, extras, fxAccount, syncDeadline);
|
syncKeyBundle, clientState, sessionCallback, extras, fxAccount, syncDeadline);
|
||||||
|
|
||||||
|
maybeRegisterDevice(context, fxAccount);
|
||||||
|
|
||||||
// Force fetch the profile avatar information. (asynchronous, in another thread)
|
// Force fetch the profile avatar information. (asynchronous, in another thread)
|
||||||
Logger.info(LOG_TAG, "Fetching profile avatar information.");
|
Logger.info(LOG_TAG, "Fetching profile avatar information.");
|
||||||
fxAccount.fetchProfileJSON();
|
fxAccount.fetchProfileJSON();
|
||||||
|
|
|
@ -6,6 +6,7 @@ package org.mozilla.gecko.sync;
|
||||||
|
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountUtils;
|
import org.mozilla.gecko.background.fxa.FxAccountUtils;
|
||||||
import org.mozilla.gecko.fxa.FirefoxAccounts;
|
import org.mozilla.gecko.fxa.FirefoxAccounts;
|
||||||
|
import org.mozilla.gecko.fxa.FxAccountDeviceRegistrator;
|
||||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||||
import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
|
import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
|
||||||
import org.mozilla.gecko.util.HardwareUtils;
|
import org.mozilla.gecko.util.HardwareUtils;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
package org.mozilla.gecko.fxa.devices;
|
package org.mozilla.gecko.fxa;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
|
@ -1,188 +0,0 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
package org.mozilla.gecko.fxa.devices;
|
|
||||||
|
|
||||||
import android.content.ContentProviderClient;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.mozilla.gecko.background.db.DelegatingTestContentProvider;
|
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClient;
|
|
||||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
|
||||||
import org.mozilla.gecko.db.BrowserContract;
|
|
||||||
import org.mozilla.gecko.db.BrowserProvider;
|
|
||||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
|
||||||
import org.mozilla.gecko.fxa.login.State;
|
|
||||||
import org.robolectric.shadows.ShadowContentResolver;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static java.util.Objects.deepEquals;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
import static org.mockito.Matchers.anyString;
|
|
||||||
import static org.mockito.Mockito.any;
|
|
||||||
import static org.mockito.Mockito.doReturn;
|
|
||||||
import static org.mockito.Mockito.eq;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@RunWith(TestRunner.class)
|
|
||||||
public class TestFxAccountDeviceListUpdater {
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() {
|
|
||||||
// Process Mockito annotations
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
fxaDevicesUpdater = spy(new FxAccountDeviceListUpdater(fxAccount, contentResolver));
|
|
||||||
}
|
|
||||||
|
|
||||||
FxAccountDeviceListUpdater fxaDevicesUpdater;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
AndroidFxAccount fxAccount;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
State state;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
ContentResolver contentResolver;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
FxAccountClient fxaClient;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdate() throws Throwable {
|
|
||||||
byte[] token = "usertoken".getBytes();
|
|
||||||
|
|
||||||
when(fxAccount.getState()).thenReturn(state);
|
|
||||||
when(state.getSessionToken()).thenReturn(token);
|
|
||||||
doReturn(fxaClient).when(fxaDevicesUpdater).getSynchronousFxaClient();
|
|
||||||
|
|
||||||
fxaDevicesUpdater.update();
|
|
||||||
verify(fxaClient).deviceList(token, fxaDevicesUpdater);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSuccessHandler() throws Throwable {
|
|
||||||
FxAccountDevice[] result = new FxAccountDevice[2];
|
|
||||||
FxAccountDevice device1 = new FxAccountDevice("Current device", "deviceid1", "mobile", true, System.currentTimeMillis(),
|
|
||||||
"https://localhost/push/callback1", "abc123", "321cba");
|
|
||||||
FxAccountDevice device2 = new FxAccountDevice("Desktop PC", "deviceid2", "desktop", true, System.currentTimeMillis(),
|
|
||||||
"https://localhost/push/callback2", "abc123", "321cba");
|
|
||||||
result[0] = device1;
|
|
||||||
result[1] = device2;
|
|
||||||
|
|
||||||
when(fxAccount.getProfile()).thenReturn("default");
|
|
||||||
|
|
||||||
long timeBeforeCall = System.currentTimeMillis();
|
|
||||||
fxaDevicesUpdater.handleSuccess(result);
|
|
||||||
|
|
||||||
ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
|
|
||||||
verify(contentResolver).call(any(Uri.class), eq(BrowserContract.METHOD_REPLACE_REMOTE_CLIENTS), anyString(), captor.capture());
|
|
||||||
List<Bundle> allArgs = captor.getAllValues();
|
|
||||||
assertTrue(allArgs.size() == 1);
|
|
||||||
ContentValues[] allValues = (ContentValues[]) allArgs.get(0).getParcelableArray(BrowserContract.METHOD_PARAM_DATA);
|
|
||||||
|
|
||||||
ContentValues firstDevice = allValues[0];
|
|
||||||
checkInsertDeviceContentValues(device1, firstDevice, timeBeforeCall);
|
|
||||||
ContentValues secondDevice = allValues[1];
|
|
||||||
checkInsertDeviceContentValues(device2, secondDevice, timeBeforeCall);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkInsertDeviceContentValues(FxAccountDevice device, ContentValues firstDevice, long timeBeforeCall) {
|
|
||||||
assertEquals(firstDevice.getAsString(BrowserContract.RemoteDevices.GUID), device.id);
|
|
||||||
assertEquals(firstDevice.getAsString(BrowserContract.RemoteDevices.TYPE), device.type);
|
|
||||||
assertEquals(firstDevice.getAsString(BrowserContract.RemoteDevices.NAME), device.name);
|
|
||||||
assertEquals(firstDevice.getAsBoolean(BrowserContract.RemoteDevices.IS_CURRENT_DEVICE), device.isCurrentDevice);
|
|
||||||
deepEquals(firstDevice.getAsString(BrowserContract.RemoteDevices.LAST_ACCESS_TIME), device.lastAccessTime);
|
|
||||||
assertTrue(firstDevice.getAsLong(BrowserContract.RemoteDevices.DATE_CREATED) < timeBeforeCall + 10000); // Give 10 secs of leeway
|
|
||||||
assertTrue(firstDevice.getAsLong(BrowserContract.RemoteDevices.DATE_MODIFIED) < timeBeforeCall + 10000);
|
|
||||||
assertEquals(firstDevice.getAsString(BrowserContract.RemoteDevices.NAME), device.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBrowserProvider() {
|
|
||||||
Uri uri = testUri(BrowserContract.RemoteDevices.CONTENT_URI);
|
|
||||||
|
|
||||||
BrowserProvider provider = new BrowserProvider();
|
|
||||||
Cursor c = null;
|
|
||||||
try {
|
|
||||||
provider.onCreate();
|
|
||||||
ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY, new DelegatingTestContentProvider(provider));
|
|
||||||
|
|
||||||
final ShadowContentResolver cr = new ShadowContentResolver();
|
|
||||||
ContentProviderClient remoteDevicesClient = cr.acquireContentProviderClient(BrowserContract.RemoteDevices.CONTENT_URI);
|
|
||||||
|
|
||||||
// First let's insert a client for initial state.
|
|
||||||
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
ContentValues device1 = createMockRemoteClientValues("device1");
|
|
||||||
bundle.putParcelableArray(BrowserContract.METHOD_PARAM_DATA, new ContentValues[] { device1 });
|
|
||||||
|
|
||||||
remoteDevicesClient.call(BrowserContract.METHOD_REPLACE_REMOTE_CLIENTS, uri.toString(), bundle);
|
|
||||||
|
|
||||||
c = remoteDevicesClient.query(uri, null, null, null, "name ASC");
|
|
||||||
assertEquals(c.getCount(), 1);
|
|
||||||
c.moveToFirst();
|
|
||||||
int nameCol = c.getColumnIndexOrThrow("name");
|
|
||||||
assertEquals(c.getString(nameCol), "device1");
|
|
||||||
c.close();
|
|
||||||
|
|
||||||
// Then we replace our remote clients list with a new one.
|
|
||||||
|
|
||||||
bundle = new Bundle();
|
|
||||||
ContentValues device2 = createMockRemoteClientValues("device2");
|
|
||||||
ContentValues device3 = createMockRemoteClientValues("device3");
|
|
||||||
bundle.putParcelableArray(BrowserContract.METHOD_PARAM_DATA, new ContentValues[] { device2, device3 });
|
|
||||||
|
|
||||||
remoteDevicesClient.call(BrowserContract.METHOD_REPLACE_REMOTE_CLIENTS, uri.toString(), bundle);
|
|
||||||
|
|
||||||
c = remoteDevicesClient.query(uri, null, null, null, "name ASC");
|
|
||||||
assertEquals(c.getCount(), 2);
|
|
||||||
c.moveToFirst();
|
|
||||||
nameCol = c.getColumnIndexOrThrow("name");
|
|
||||||
assertEquals(c.getString(nameCol), "device2");
|
|
||||||
c.moveToNext();
|
|
||||||
assertEquals(c.getString(nameCol), "device3");
|
|
||||||
c.close();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
} finally {
|
|
||||||
if (c != null && !c.isClosed()) {
|
|
||||||
c.close();
|
|
||||||
}
|
|
||||||
provider.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Uri testUri(Uri baseUri) {
|
|
||||||
return baseUri.buildUpon().appendQueryParameter(BrowserContract.PARAM_IS_TEST, "1").build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContentValues createMockRemoteClientValues(String name) {
|
|
||||||
final long now = System.currentTimeMillis();
|
|
||||||
ContentValues cli = new ContentValues();
|
|
||||||
cli.put(BrowserContract.RemoteDevices.GUID, "R" + Math.floor(Math.random() * 10));
|
|
||||||
cli.put(BrowserContract.RemoteDevices.NAME, name);
|
|
||||||
cli.put(BrowserContract.RemoteDevices.TYPE, "mobile");
|
|
||||||
cli.put(BrowserContract.RemoteDevices.IS_CURRENT_DEVICE, false);
|
|
||||||
cli.put(BrowserContract.RemoteDevices.LAST_ACCESS_TIME, System.currentTimeMillis());
|
|
||||||
cli.put(BrowserContract.RemoteDevices.DATE_CREATED, now);
|
|
||||||
cli.put(BrowserContract.RemoteDevices.DATE_MODIFIED, now);
|
|
||||||
return cli;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,6 +6,7 @@ package org.mozilla.gecko.fxa.login;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClient;
|
import org.mozilla.gecko.background.fxa.FxAccountClient;
|
||||||
|
import org.mozilla.gecko.background.fxa.FxAccountClient20;
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClient20.AccountStatusResponse;
|
import org.mozilla.gecko.background.fxa.FxAccountClient20.AccountStatusResponse;
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClient20.RequestDelegate;
|
import org.mozilla.gecko.background.fxa.FxAccountClient20.RequestDelegate;
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClient20.RecoveryEmailStatusResponse;
|
import org.mozilla.gecko.background.fxa.FxAccountClient20.RecoveryEmailStatusResponse;
|
||||||
|
@ -14,7 +15,7 @@ import org.mozilla.gecko.background.fxa.FxAccountClient20.LoginResponse;
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
|
import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountRemoteError;
|
import org.mozilla.gecko.background.fxa.FxAccountRemoteError;
|
||||||
import org.mozilla.gecko.background.fxa.FxAccountUtils;
|
import org.mozilla.gecko.background.fxa.FxAccountUtils;
|
||||||
import org.mozilla.gecko.fxa.devices.FxAccountDevice;
|
import org.mozilla.gecko.fxa.FxAccountDevice;
|
||||||
import org.mozilla.gecko.browserid.MockMyIDTokenFactory;
|
import org.mozilla.gecko.browserid.MockMyIDTokenFactory;
|
||||||
import org.mozilla.gecko.browserid.RSACryptoImplementation;
|
import org.mozilla.gecko.browserid.RSACryptoImplementation;
|
||||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
|
@ -179,7 +180,7 @@ public class MockFxAccountClient implements FxAccountClient {
|
||||||
String deviceId = deviceToRegister.id;
|
String deviceId = deviceToRegister.id;
|
||||||
if (TextUtils.isEmpty(deviceId)) { // Create
|
if (TextUtils.isEmpty(deviceId)) { // Create
|
||||||
deviceId = UUID.randomUUID().toString();
|
deviceId = UUID.randomUUID().toString();
|
||||||
FxAccountDevice device = new FxAccountDevice(deviceToRegister.name, deviceId, deviceToRegister.type, null, null, null, null, null);
|
FxAccountDevice device = new FxAccountDevice(deviceToRegister.name, deviceId, deviceToRegister.type, null, null, null, null);
|
||||||
requestDelegate.handleSuccess(device);
|
requestDelegate.handleSuccess(device);
|
||||||
} else { // Update
|
} else { // Update
|
||||||
FxAccountDevice existingDevice = user.devices.get(deviceId);
|
FxAccountDevice existingDevice = user.devices.get(deviceId);
|
||||||
|
@ -188,8 +189,8 @@ public class MockFxAccountClient implements FxAccountClient {
|
||||||
if (!TextUtils.isEmpty(deviceToRegister.name)) {
|
if (!TextUtils.isEmpty(deviceToRegister.name)) {
|
||||||
deviceName = deviceToRegister.name;
|
deviceName = deviceToRegister.name;
|
||||||
} // We could also update the other fields..
|
} // We could also update the other fields..
|
||||||
FxAccountDevice device = new FxAccountDevice(deviceName, existingDevice.id, existingDevice.type, existingDevice.isCurrentDevice,
|
FxAccountDevice device = new FxAccountDevice(deviceName, existingDevice.id, existingDevice.type,
|
||||||
existingDevice.lastAccessTime, existingDevice.pushCallback, existingDevice.pushPublicKey,existingDevice.pushAuthKey);
|
existingDevice.isCurrentDevice, existingDevice.pushCallback, existingDevice.pushPublicKey,existingDevice.pushAuthKey);
|
||||||
requestDelegate.handleSuccess(device);
|
requestDelegate.handleSuccess(device);
|
||||||
} else { // Device unknown
|
} else { // Device unknown
|
||||||
handleFailure(requestDelegate, HttpStatus.SC_BAD_REQUEST, FxAccountRemoteError.UNKNOWN_DEVICE, "device is unknown");
|
handleFailure(requestDelegate, HttpStatus.SC_BAD_REQUEST, FxAccountRemoteError.UNKNOWN_DEVICE, "device is unknown");
|
||||||
|
|
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче