mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 22:05:44 +00:00
Bug 1021055 - Add Sync client device type to Fennec's tabs provider. r=rnewman
This is the expedient thing to do. The right thing to do is to deprecate Sync's clients database in favour of Fennec's clients table, but that's a good chunk of work for a small gain.
This commit is contained in:
parent
c4bedd5427
commit
943b7aee84
@ -328,6 +328,8 @@ public class BrowserContract {
|
||||
// Last modified time for the client's tab record. For remote records, a server
|
||||
// timestamp provided by Sync during insertion.
|
||||
public static final String LAST_MODIFIED = "last_modified";
|
||||
|
||||
public static final String DEVICE_TYPE = "device_type";
|
||||
}
|
||||
|
||||
// Data storage for dynamic panels on about:home
|
||||
|
@ -26,7 +26,7 @@ import android.text.TextUtils;
|
||||
public class TabsProvider extends PerProfileDatabaseProvider<TabsProvider.TabsDatabaseHelper> {
|
||||
static final String DATABASE_NAME = "tabs.db";
|
||||
|
||||
static final int DATABASE_VERSION = 2;
|
||||
static final int DATABASE_VERSION = 3;
|
||||
|
||||
static final String TABLE_TABS = "tabs";
|
||||
static final String TABLE_CLIENTS = "clients";
|
||||
@ -67,12 +67,14 @@ public class TabsProvider extends PerProfileDatabaseProvider<TabsProvider.TabsDa
|
||||
map.put(Clients.GUID, Clients.GUID);
|
||||
map.put(Clients.NAME, Clients.NAME);
|
||||
map.put(Clients.LAST_MODIFIED, Clients.LAST_MODIFIED);
|
||||
map.put(Clients.DEVICE_TYPE, Clients.DEVICE_TYPE);
|
||||
TABS_PROJECTION_MAP = Collections.unmodifiableMap(map);
|
||||
|
||||
map = new HashMap<String, String>();
|
||||
map.put(Clients.GUID, Clients.GUID);
|
||||
map.put(Clients.NAME, Clients.NAME);
|
||||
map.put(Clients.LAST_MODIFIED, Clients.LAST_MODIFIED);
|
||||
map.put(Clients.DEVICE_TYPE, Clients.DEVICE_TYPE);
|
||||
CLIENTS_PROJECTION_MAP = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
@ -114,7 +116,8 @@ public class TabsProvider extends PerProfileDatabaseProvider<TabsProvider.TabsDa
|
||||
db.execSQL("CREATE TABLE " + TABLE_CLIENTS + "(" +
|
||||
Clients.GUID + " TEXT PRIMARY KEY," +
|
||||
Clients.NAME + " TEXT," +
|
||||
Clients.LAST_MODIFIED + " INTEGER" +
|
||||
Clients.LAST_MODIFIED + " INTEGER," +
|
||||
Clients.DEVICE_TYPE + " TEXT" +
|
||||
");");
|
||||
|
||||
// Index on GUID.
|
||||
@ -133,6 +136,14 @@ public class TabsProvider extends PerProfileDatabaseProvider<TabsProvider.TabsDa
|
||||
db.insertOrThrow(TABLE_CLIENTS, null, values);
|
||||
}
|
||||
|
||||
protected void upgradeDatabaseFrom2to3(SQLiteDatabase db) {
|
||||
debug("Setting remote client device types to 'mobile' in " + TABLE_CLIENTS + " table");
|
||||
|
||||
// Add type to client, defaulting to mobile. This is correct for our
|
||||
// local client; all remote clients will be updated by Sync.
|
||||
db.execSQL("ALTER TABLE " + TABLE_CLIENTS + " ADD COLUMN " + BrowserContract.Clients.DEVICE_TYPE + " TEXT DEFAULT 'mobile'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
debug("Upgrading tabs.db: " + db.getPath() + " from " +
|
||||
@ -145,6 +156,10 @@ public class TabsProvider extends PerProfileDatabaseProvider<TabsProvider.TabsDa
|
||||
case 2:
|
||||
createLocalClient(db);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
upgradeDatabaseFrom2to3(db);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import java.util.ArrayList;
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
import org.mozilla.gecko.background.db.Tab;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.BrowserContract.Clients;
|
||||
import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
|
||||
import org.mozilla.gecko.sync.repositories.NoContentProviderException;
|
||||
@ -20,6 +21,7 @@ import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecor
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionGuidsSinceDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||
import org.mozilla.gecko.sync.repositories.domain.Record;
|
||||
import org.mozilla.gecko.sync.repositories.domain.TabsRecord;
|
||||
|
||||
@ -38,7 +40,7 @@ public class FennecTabsRepository extends Repository {
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that — unlike most repositories — this will only fetch Fennec's tabs,
|
||||
* Note that -- unlike most repositories -- this will only fetch Fennec's tabs,
|
||||
* and only store tabs from other clients.
|
||||
*
|
||||
* It will never retrieve tabs from other clients, or store tabs for Fennec,
|
||||
@ -53,6 +55,8 @@ public class FennecTabsRepository extends Repository {
|
||||
|
||||
protected final RepoUtils.QueryHelper tabsHelper;
|
||||
|
||||
protected final ClientsDatabaseAccessor clientsDatabase;
|
||||
|
||||
protected ContentProviderClient getContentProvider(final Context context, final Uri uri) throws NoContentProviderException {
|
||||
ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(uri);
|
||||
if (client == null) {
|
||||
@ -68,6 +72,7 @@ public class FennecTabsRepository extends Repository {
|
||||
try {
|
||||
tabsProvider.release();
|
||||
} catch (Exception e) {}
|
||||
clientsDatabase.close();
|
||||
}
|
||||
|
||||
public FennecTabsRepositorySession(Repository repository, Context context) throws NoContentProviderException {
|
||||
@ -85,6 +90,7 @@ public class FennecTabsRepository extends Repository {
|
||||
}
|
||||
|
||||
tabsHelper = new RepoUtils.QueryHelper(context, BrowserContractHelpers.TABS_CONTENT_URI, LOG_TAG);
|
||||
clientsDatabase = new ClientsDatabaseAccessor(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -240,6 +246,12 @@ public class FennecTabsRepository extends Repository {
|
||||
// If it exists, update the client record; otherwise insert.
|
||||
final ContentValues clientsCV = tabsRecord.getClientsContentValues();
|
||||
|
||||
final ClientRecord clientRecord = clientsDatabase.fetchClient(tabsRecord.guid);
|
||||
if (null != clientRecord) {
|
||||
// Null is an acceptable device type.
|
||||
clientsCV.put(Clients.DEVICE_TYPE, clientRecord.type);
|
||||
}
|
||||
|
||||
Logger.debug(LOG_TAG, "Updating clients provider.");
|
||||
final int updated = clientsProvider.update(BrowserContractHelpers.CLIENTS_CONTENT_URI,
|
||||
clientsCV,
|
||||
|
@ -9,12 +9,15 @@ import org.mozilla.gecko.background.sync.helpers.ExpectFetchDelegate;
|
||||
import org.mozilla.gecko.background.sync.helpers.SessionTestHelper;
|
||||
import org.mozilla.gecko.background.testhelpers.MockClientsDataDelegate;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.BrowserContract.Clients;
|
||||
import org.mozilla.gecko.sync.repositories.NoContentProviderException;
|
||||
import org.mozilla.gecko.sync.repositories.RepositorySession;
|
||||
import org.mozilla.gecko.sync.repositories.android.BrowserContractHelpers;
|
||||
import org.mozilla.gecko.sync.repositories.android.ClientsDatabaseAccessor;
|
||||
import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository;
|
||||
import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository.FennecTabsRepositorySession;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||
import org.mozilla.gecko.sync.repositories.domain.Record;
|
||||
import org.mozilla.gecko.sync.repositories.domain.TabsRecord;
|
||||
|
||||
@ -28,11 +31,15 @@ public class TestFennecTabsRepositorySession extends AndroidSyncTestCase {
|
||||
public static final MockClientsDataDelegate clientsDataDelegate = new MockClientsDataDelegate();
|
||||
public static final String TEST_CLIENT_GUID = clientsDataDelegate.getAccountGUID();
|
||||
public static final String TEST_CLIENT_NAME = clientsDataDelegate.getClientName();
|
||||
public static final String TEST_CLIENT_DEVICE_TYPE = "phablet";
|
||||
|
||||
// Override these to test against data that is not live.
|
||||
public static final String TEST_TABS_CLIENT_GUID_IS_LOCAL_SELECTION = BrowserContract.Tabs.CLIENT_GUID + " IS ?";
|
||||
public static final String[] TEST_TABS_CLIENT_GUID_IS_LOCAL_SELECTION_ARGS = new String[] { TEST_CLIENT_GUID };
|
||||
|
||||
public static final String TEST_CLIENTS_GUID_IS_LOCAL_SELECTION = BrowserContract.Clients.GUID + " IS ?";
|
||||
public static final String[] TEST_CLIENTS_GUID_IS_LOCAL_SELECTION_ARGS = new String[] { TEST_CLIENT_GUID };
|
||||
|
||||
protected ContentProviderClient tabsClient = null;
|
||||
|
||||
protected ContentProviderClient getTabsClient() {
|
||||
@ -215,4 +222,55 @@ public class TestFennecTabsRepositorySession extends AndroidSyncTestCase {
|
||||
|
||||
session.abort();
|
||||
}
|
||||
|
||||
// Verify that storing a tabs record writes a clients record with the correct
|
||||
// device type to the Fennec clients provider.
|
||||
public void testStore() throws NoContentProviderException, RemoteException {
|
||||
// Get a valid tabsRecord to write.
|
||||
final TabsRecord tabsRecord = insertTestTabsAndExtractTabsRecord();
|
||||
deleteAllTestTabs(tabsClient);
|
||||
|
||||
final ContentResolver cr = getApplicationContext().getContentResolver();
|
||||
final ContentProviderClient clientsClient = cr.acquireContentProviderClient(BrowserContractHelpers.CLIENTS_CONTENT_URI);
|
||||
|
||||
try {
|
||||
// We can't delete only our test clients due to a Fennec CP issue with guid vs. client_guid.
|
||||
clientsClient.delete(BrowserContractHelpers.CLIENTS_CONTENT_URI, null, null);
|
||||
|
||||
// This clients DB is not the Fennec DB; it's Sync's own clients DB.
|
||||
final ClientsDatabaseAccessor db = new ClientsDatabaseAccessor(getApplicationContext());
|
||||
try {
|
||||
ClientRecord clientRecord = new ClientRecord(TEST_CLIENT_GUID);
|
||||
clientRecord.name = TEST_CLIENT_NAME;
|
||||
clientRecord.type = TEST_CLIENT_DEVICE_TYPE;
|
||||
db.store(clientRecord);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
|
||||
final FennecTabsRepositorySession session = createAndBeginSession();
|
||||
performWait(AndroidBrowserRepositoryTestCase.storeRunnable(session, tabsRecord));
|
||||
|
||||
session.abort();
|
||||
|
||||
// This store should write Sync's idea of the client's device_type to Fennec's clients CP.
|
||||
final Cursor cursor = clientsClient.query(BrowserContractHelpers.CLIENTS_CONTENT_URI, null,
|
||||
TEST_CLIENTS_GUID_IS_LOCAL_SELECTION, TEST_CLIENTS_GUID_IS_LOCAL_SELECTION_ARGS, null);
|
||||
assertNotNull(cursor);
|
||||
|
||||
try {
|
||||
assertTrue(cursor.moveToFirst());
|
||||
assertEquals(TEST_CLIENT_GUID, cursor.getString(cursor.getColumnIndex(Clients.GUID)));
|
||||
assertEquals(TEST_CLIENT_NAME, cursor.getString(cursor.getColumnIndex(Clients.NAME)));
|
||||
assertEquals(TEST_CLIENT_DEVICE_TYPE, cursor.getString(cursor.getColumnIndex(Clients.DEVICE_TYPE)));
|
||||
assertTrue(cursor.isLast());
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
} finally {
|
||||
// We can't delete only our test client due to a Fennec CP issue with guid vs. client_guid.
|
||||
clientsClient.delete(BrowserContractHelpers.CLIENTS_CONTENT_URI, null, null);
|
||||
clientsClient.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user