зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1351104 part 2 - Filter the clients list in Send Tab with the FxA device list. r=Grisha
MozReview-Commit-ID: KqSyWVfwva3 --HG-- extra : rebase_source : 49b3eadec9527bc51f99747bc9f5a2bc9f24822a
This commit is contained in:
Родитель
322ba44ea6
Коммит
5fccf18ee5
|
@ -74,41 +74,6 @@ public class LocalTabsAccessor implements TabsAccessor {
|
|||
clientsNoStaleSortedUriWithProfile = DBUtils.appendProfileWithDefault(profileName, BrowserContract.Clients.CONTENT_NO_STALE_SORTED_URI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a List of just RemoteClients from a cursor.
|
||||
* The supplied cursor should be grouped by guid and sorted by name alphabetically.
|
||||
*/
|
||||
@Override
|
||||
public List<RemoteClient> getClientsWithoutTabsNoStaleSortedFromCursor(Cursor cursor) {
|
||||
final ArrayList<RemoteClient> clients = new ArrayList<>(cursor.getCount());
|
||||
|
||||
final int originalPosition = cursor.getPosition();
|
||||
try {
|
||||
if (!cursor.moveToFirst()) {
|
||||
return clients;
|
||||
}
|
||||
|
||||
final int clientGuidIndex = cursor.getColumnIndex(BrowserContract.Clients.GUID);
|
||||
final int clientNameIndex = cursor.getColumnIndex(BrowserContract.Clients.NAME);
|
||||
final int clientLastModifiedIndex = cursor.getColumnIndex(BrowserContract.Clients.LAST_MODIFIED);
|
||||
final int clientDeviceTypeIndex = cursor.getColumnIndex(BrowserContract.Clients.DEVICE_TYPE);
|
||||
|
||||
while (!cursor.isAfterLast()) {
|
||||
final String clientGuid = cursor.getString(clientGuidIndex);
|
||||
final String clientName = cursor.getString(clientNameIndex);
|
||||
final String deviceType = cursor.getString(clientDeviceTypeIndex);
|
||||
final long lastModified = cursor.getLong(clientLastModifiedIndex);
|
||||
|
||||
clients.add(new RemoteClient(clientGuid, clientName, lastModified, deviceType));
|
||||
|
||||
cursor.moveToNext();
|
||||
}
|
||||
} finally {
|
||||
cursor.moveToPosition(originalPosition);
|
||||
}
|
||||
return clients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract client and tab records from a cursor.
|
||||
* <p>
|
||||
|
|
|
@ -20,7 +20,6 @@ public interface TabsAccessor {
|
|||
public Cursor getRemoteClientsNoStaleSorted(Context context);
|
||||
public Cursor getRemoteTabsCursor(Context context);
|
||||
public Cursor getRemoteTabsCursor(Context context, int limit);
|
||||
public List<RemoteClient> getClientsWithoutTabsNoStaleSortedFromCursor(final Cursor cursor);
|
||||
public List<RemoteClient> getClientsFromCursor(final Cursor cursor);
|
||||
public void getTabs(final Context context, final OnQueryTabsCompleteListener listener);
|
||||
public void getTabs(final Context context, final int limit, final OnQueryTabsCompleteListener listener);
|
||||
|
|
|
@ -9,16 +9,12 @@ import android.accounts.AccountManager;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.db.RemoteClient;
|
||||
import org.mozilla.gecko.db.TabsAccessor;
|
||||
import org.mozilla.gecko.fxa.FxAccountConstants;
|
||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||
import org.mozilla.gecko.fxa.login.State;
|
||||
|
@ -28,7 +24,11 @@ import org.mozilla.gecko.sync.CommandProcessor;
|
|||
import org.mozilla.gecko.sync.CommandRunner;
|
||||
import org.mozilla.gecko.sync.GlobalSession;
|
||||
import org.mozilla.gecko.sync.SyncConfiguration;
|
||||
import org.mozilla.gecko.sync.repositories.NullCursorException;
|
||||
import org.mozilla.gecko.sync.repositories.android.ClientsDatabaseAccessor;
|
||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -238,16 +238,19 @@ public class SendTab extends ShareMethod {
|
|||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final BrowserDB browserDB = BrowserDB.from(context);
|
||||
final TabsAccessor tabsAccessor = browserDB.getTabsAccessor();
|
||||
final Cursor remoteTabsCursor = tabsAccessor.getRemoteClientsNoStaleSorted(context);
|
||||
final ClientsDatabaseAccessor clientsDatabaseAccessor = new ClientsDatabaseAccessor(context);
|
||||
try {
|
||||
if (remoteTabsCursor.getCount() == 0) {
|
||||
return Collections.emptyList();
|
||||
final String[] remoteDevicesIds = clientsDatabaseAccessor.getRemoteDevicesIds(context);
|
||||
final Collection<ClientRecord> clientRecords = clientsDatabaseAccessor.fetchNonStaleClients(remoteDevicesIds);
|
||||
final Collection<RemoteClient> remoteClients = new ArrayList<>(clientRecords.size());
|
||||
for (ClientRecord cr : clientRecords) {
|
||||
remoteClients.add(new RemoteClient(cr.guid, cr.name, cr.lastModified, cr.type));
|
||||
}
|
||||
return tabsAccessor.getClientsWithoutTabsNoStaleSortedFromCursor(remoteTabsCursor);
|
||||
return remoteClients;
|
||||
} catch (NullCursorException e) {
|
||||
return Collections.emptyList();
|
||||
} finally {
|
||||
remoteTabsCursor.close();
|
||||
clientsDatabaseAccessor.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@ package org.mozilla.gecko.widget;
|
|||
import android.accounts.Account;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.db.TabsAccessor;
|
||||
import org.mozilla.gecko.distribution.Distribution;
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.fxa.FirefoxAccounts;
|
||||
|
@ -40,7 +38,6 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.database.Cursor;
|
||||
import android.database.DataSetObservable;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.TextUtils;
|
||||
|
@ -52,6 +49,9 @@ import android.util.Xml;
|
|||
*/
|
||||
//import com.android.internal.content.PackageMonitor;
|
||||
|
||||
import org.mozilla.gecko.sync.repositories.NullCursorException;
|
||||
import org.mozilla.gecko.sync.repositories.android.ClientsDatabaseAccessor;
|
||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
@ -62,6 +62,7 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
@ -1314,18 +1315,14 @@ public class ActivityChooserModel extends DataSetObservable {
|
|||
return false;
|
||||
}
|
||||
|
||||
final BrowserDB browserDB = BrowserDB.from(mContext);
|
||||
final TabsAccessor tabsAccessor = browserDB.getTabsAccessor();
|
||||
final Cursor remoteClientsCursor = tabsAccessor
|
||||
.getRemoteClientsNoStaleSorted(mContext);
|
||||
if (remoteClientsCursor == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ClientsDatabaseAccessor clientsDatabaseAccessor = new ClientsDatabaseAccessor(mContext.getApplicationContext());
|
||||
try {
|
||||
return remoteClientsCursor.getCount() > 0;
|
||||
final String[] remoteDevicesIds = clientsDatabaseAccessor.getRemoteDevicesIds(mContext);
|
||||
return clientsDatabaseAccessor.hasNonStaleClients(remoteDevicesIds);
|
||||
} catch (NullCursorException e) {
|
||||
return false;
|
||||
} finally {
|
||||
remoteClientsCursor.close();
|
||||
clientsDatabaseAccessor.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -249,6 +249,14 @@ public class ClientsDatabase extends CachedSQLiteOpenHelper {
|
|||
return queryHelper.safeQuery(db, ".fetchAllClients", TBL_CLIENTS, TBL_CLIENTS_COLUMNS, null, null);
|
||||
}
|
||||
|
||||
public Cursor fetchClientsWithFxADeviceIds(String[] fxaDeviceIds) throws NullCursorException {
|
||||
String inClause = computeSQLInClause(fxaDeviceIds.length, COL_FXA_DEVICE_ID);
|
||||
String query = inClause + " OR " + COL_FXA_DEVICE_ID + " IS NULL";
|
||||
SQLiteDatabase db = this.getCachedReadableDatabase();
|
||||
|
||||
return queryHelper.safeQuery(db, ".fetchClientsWithFxADeviceIds", TBL_CLIENTS, TBL_CLIENTS_COLUMNS, query, fxaDeviceIds);
|
||||
}
|
||||
|
||||
public Cursor fetchAllCommands() throws NullCursorException {
|
||||
SQLiteDatabase db = this.getCachedReadableDatabase();
|
||||
|
||||
|
@ -261,4 +269,19 @@ public class ClientsDatabase extends CachedSQLiteOpenHelper {
|
|||
SQLiteDatabase db = this.getCachedWritableDatabase();
|
||||
db.delete(TBL_CLIENTS, TBL_CLIENTS_KEY, args);
|
||||
}
|
||||
|
||||
// Pulled from DBUtils
|
||||
private static String computeSQLInClause(int items, String field) {
|
||||
final StringBuilder builder = new StringBuilder(field);
|
||||
builder.append(" IN (");
|
||||
int i = 0;
|
||||
for (; i < items - 1; ++i) {
|
||||
builder.append("?, ");
|
||||
}
|
||||
if (i < items) {
|
||||
builder.append("?");
|
||||
}
|
||||
builder.append(")");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,16 +8,21 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.fxa.devices.FxAccountDevice;
|
||||
import org.mozilla.gecko.sync.CommandProcessor.Command;
|
||||
import org.mozilla.gecko.sync.repositories.NullCursorException;
|
||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||
import org.mozilla.gecko.sync.setup.Constants;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
|
||||
|
@ -79,6 +84,58 @@ public class ClientsDatabaseAccessor {
|
|||
}
|
||||
}
|
||||
|
||||
// Filters our list of clients with the device list we have from FxA.
|
||||
public Collection<ClientRecord> fetchNonStaleClients(String[] fxaDeviceIds) throws NullCursorException {
|
||||
final Cursor cur = db.fetchClientsWithFxADeviceIds(fxaDeviceIds);
|
||||
final Collection<ClientRecord> clients = new ArrayList<>(cur.getCount());
|
||||
try {
|
||||
if (!cur.moveToFirst()) {
|
||||
return clients;
|
||||
}
|
||||
|
||||
while (!cur.isAfterLast()) {
|
||||
ClientRecord clientRecord = recordFromCursor(cur);
|
||||
clients.add(clientRecord);
|
||||
cur.moveToNext();
|
||||
}
|
||||
return clients;
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNonStaleClients(String[] fxaDeviceIds) throws NullCursorException {
|
||||
try {
|
||||
final Cursor cur = db.fetchClientsWithFxADeviceIds(fxaDeviceIds);
|
||||
try {
|
||||
return cur.getCount() > 0;
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
} catch (NullCursorException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getRemoteDevicesIds(Context context) {
|
||||
final ContentResolver cr = context.getContentResolver();
|
||||
final String[] guidProjection = new String[] {
|
||||
BrowserContract.RemoteDevices.GUID, // 0
|
||||
};
|
||||
final Cursor c = cr.query(BrowserContract.RemoteDevices.CONTENT_URI, guidProjection, null, null, "NAME ASC");
|
||||
final String[] remoteDevicesIds = new String[c.getCount()];
|
||||
try {
|
||||
int i = 0;
|
||||
while (c.moveToNext()) {
|
||||
remoteDevicesIds[i] = c.getString(c.getColumnIndexOrThrow(BrowserContract.RemoteDevices.GUID));
|
||||
i++;
|
||||
}
|
||||
} finally {
|
||||
c.close();
|
||||
}
|
||||
return remoteDevicesIds;
|
||||
}
|
||||
|
||||
public List<Command> fetchAllCommands() throws NullCursorException {
|
||||
final List<Command> commands = new ArrayList<Command>();
|
||||
final Cursor cur = db.fetchAllCommands();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
package org.mozilla.gecko.background.db;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -125,4 +126,40 @@ public class TestClientsDatabaseAccessor extends AndroidTestCase {
|
|||
}
|
||||
assertTrue(thrown);
|
||||
}
|
||||
|
||||
public void testFetchNonStaleClients() throws NullCursorException {
|
||||
String goodRecord1 = Utils.generateGuid();
|
||||
ClientRecord record1 = new ClientRecord(goodRecord1);
|
||||
record1.fxaDeviceId = "fxa1";
|
||||
ClientRecord record2 = new ClientRecord(Utils.generateGuid());
|
||||
record2.fxaDeviceId = "fxa2";
|
||||
String goodRecord2 = Utils.generateGuid();
|
||||
ClientRecord record3 = new ClientRecord(goodRecord2);
|
||||
record3.fxaDeviceId = "fxa4";
|
||||
|
||||
ArrayList<ClientRecord> list = new ArrayList<>();
|
||||
list.add(record1);
|
||||
list.add(record2);
|
||||
list.add(record3);
|
||||
db.store(list);
|
||||
|
||||
assertTrue(db.hasNonStaleClients(new String[]{"fxa1", "fxa-unknown"}));
|
||||
assertFalse(db.hasNonStaleClients(new String[]{}));
|
||||
|
||||
String noFxADeviceId = Utils.generateGuid();
|
||||
ClientRecord record4 = new ClientRecord(noFxADeviceId);
|
||||
record4.fxaDeviceId = null;
|
||||
list.clear();
|
||||
list.add(record4);
|
||||
db.store(list);
|
||||
|
||||
assertTrue(db.hasNonStaleClients(new String[]{}));
|
||||
|
||||
Collection<ClientRecord> filtered = db.fetchNonStaleClients(new String[]{"fxa1", "fxa4", "fxa-unknown"});
|
||||
ClientRecord[] filteredArr = filtered.toArray(new ClientRecord[0]);
|
||||
assertEquals(3, filteredArr.length);
|
||||
assertEquals(filteredArr[0].guid, goodRecord1);
|
||||
assertEquals(filteredArr[1].guid, goodRecord2);
|
||||
assertEquals(filteredArr[2].guid, noFxADeviceId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,247 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
package org.mozilla.gecko.background.db;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.LocalTabsAccessor;
|
||||
import org.mozilla.gecko.db.RemoteClient;
|
||||
import org.mozilla.gecko.db.TabsProvider;
|
||||
import org.mozilla.gecko.sync.repositories.android.BrowserContractHelpers;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.internal.runtime.RuntimeAdapter;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(TestRunner.class)
|
||||
public class TestTabsProviderRemoteTabs {
|
||||
private static final long ONE_DAY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;
|
||||
private static final long ONE_WEEK_IN_MILLISECONDS = 7 * ONE_DAY_IN_MILLISECONDS;
|
||||
private static final long THREE_WEEKS_IN_MILLISECONDS = 3 * ONE_WEEK_IN_MILLISECONDS;
|
||||
|
||||
private static final String CLIENT_LOCAL_NAME = "our local";
|
||||
private static final String CLIENT_REMOTE1_NAME = "The remote1";
|
||||
private static final String CLIENT_REMOTE2_NAME = "another remote2";
|
||||
|
||||
protected TabsProvider provider;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
provider = new TabsProvider();
|
||||
provider.onCreate();
|
||||
ShadowContentResolver.registerProvider(BrowserContract.TABS_AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
provider.shutdown();
|
||||
provider = null;
|
||||
}
|
||||
|
||||
protected ContentProviderClient getClientsClient() {
|
||||
final ShadowContentResolver cr = new ShadowContentResolver();
|
||||
return cr.acquireContentProviderClient(BrowserContractHelpers.CLIENTS_CONTENT_URI);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetClientsWithoutTabsNoStaleSortedFromCursor() throws Exception {
|
||||
final Uri uri = BrowserContractHelpers.CLIENTS_CONTENT_URI;
|
||||
final ContentProviderClient cpc = getClientsClient();
|
||||
final LocalTabsAccessor accessor = new LocalTabsAccessor("test"); // The profile name given doesn't matter.
|
||||
|
||||
try {
|
||||
// Delete all tabs to begin with.
|
||||
cpc.delete(uri, null, null);
|
||||
Cursor allClients = cpc.query(uri, null, null, null, null);
|
||||
try {
|
||||
Assert.assertEquals(0, allClients.getCount());
|
||||
} finally {
|
||||
allClients.close();
|
||||
}
|
||||
|
||||
// Insert a local and remote1 client record, neither with tabs.
|
||||
final long now = System.currentTimeMillis();
|
||||
// Local client has GUID = null.
|
||||
final ContentValues local = new ContentValues();
|
||||
local.put(BrowserContract.Clients.NAME, CLIENT_LOCAL_NAME);
|
||||
local.put(BrowserContract.Clients.LAST_MODIFIED, now + 1);
|
||||
// Remote clients have GUID != null.
|
||||
final ContentValues remote1 = new ContentValues();
|
||||
remote1.put(BrowserContract.Clients.GUID, "guid1");
|
||||
remote1.put(BrowserContract.Clients.NAME, CLIENT_REMOTE1_NAME);
|
||||
remote1.put(BrowserContract.Clients.LAST_MODIFIED, now + 2);
|
||||
|
||||
final ContentValues remote2 = new ContentValues();
|
||||
remote2.put(BrowserContract.Clients.GUID, "guid2");
|
||||
remote2.put(BrowserContract.Clients.NAME, CLIENT_REMOTE2_NAME);
|
||||
remote2.put(BrowserContract.Clients.LAST_MODIFIED, now + 3);
|
||||
|
||||
ContentValues[] values = new ContentValues[]{local, remote1, remote2};
|
||||
int inserted = cpc.bulkInsert(uri, values);
|
||||
Assert.assertEquals(3, inserted);
|
||||
|
||||
allClients = cpc.query(BrowserContract.Clients.CONTENT_NO_STALE_SORTED_URI, null, null, null, null);
|
||||
try {
|
||||
CursorDumper.dumpCursor(allClients);
|
||||
// The local client is not ignored.
|
||||
Assert.assertEquals(3, allClients.getCount());
|
||||
final List<RemoteClient> clients = accessor.getClientsWithoutTabsNoStaleSortedFromCursor(allClients);
|
||||
Assert.assertEquals(3, clients.size());
|
||||
for (RemoteClient client : clients) {
|
||||
// Each client should not have any tabs.
|
||||
Assert.assertNotNull(client.tabs);
|
||||
Assert.assertEquals(0, client.tabs.size());
|
||||
}
|
||||
// Client should sorted by name alphabetically.
|
||||
Assert.assertEquals(CLIENT_REMOTE2_NAME, clients.get(0).name);
|
||||
Assert.assertEquals(CLIENT_LOCAL_NAME, clients.get(1).name);
|
||||
Assert.assertEquals(CLIENT_REMOTE1_NAME, clients.get(2).name);
|
||||
} finally {
|
||||
allClients.close();
|
||||
}
|
||||
|
||||
// Now let's add a few tabs to one client. The times are chosen so that one tab's
|
||||
// last used is not relevant, and the other tab is the most recent used.
|
||||
final ContentValues remoteTab1 = new ContentValues();
|
||||
remoteTab1.put(BrowserContract.Tabs.CLIENT_GUID, "guid1");
|
||||
remoteTab1.put(BrowserContract.Tabs.TITLE, "title1");
|
||||
remoteTab1.put(BrowserContract.Tabs.URL, "http://test.com/test1");
|
||||
remoteTab1.put(BrowserContract.Tabs.HISTORY, "[\"http://test.com/test1\"]");
|
||||
remoteTab1.put(BrowserContract.Tabs.LAST_USED, now);
|
||||
remoteTab1.put(BrowserContract.Tabs.POSITION, 0);
|
||||
|
||||
final ContentValues remoteTab2 = new ContentValues();
|
||||
remoteTab2.put(BrowserContract.Tabs.CLIENT_GUID, "guid1");
|
||||
remoteTab2.put(BrowserContract.Tabs.TITLE, "title2");
|
||||
remoteTab2.put(BrowserContract.Tabs.URL, "http://test.com/test2");
|
||||
remoteTab2.put(BrowserContract.Tabs.HISTORY, "[\"http://test.com/test2\"]");
|
||||
remoteTab2.put(BrowserContract.Tabs.LAST_USED, now + 5);
|
||||
remoteTab2.put(BrowserContract.Tabs.POSITION, 1);
|
||||
|
||||
values = new ContentValues[]{remoteTab1, remoteTab2};
|
||||
inserted = cpc.bulkInsert(BrowserContract.Tabs.CONTENT_URI, values);
|
||||
Assert.assertEquals(2, inserted);
|
||||
|
||||
allClients = cpc.query(BrowserContract.Clients.CONTENT_NO_STALE_SORTED_URI, null, BrowserContract.Clients.GUID + " IS NOT NULL", null, null);
|
||||
try {
|
||||
CursorDumper.dumpCursor(allClients);
|
||||
// The local client is ignored.
|
||||
Assert.assertEquals(2, allClients.getCount());
|
||||
final List<RemoteClient> clients = accessor.getClientsWithoutTabsNoStaleSortedFromCursor(allClients);
|
||||
Assert.assertEquals(2, clients.size());
|
||||
for (RemoteClient client : clients) {
|
||||
// Each client should be remote and should not have any tabs.
|
||||
Assert.assertNotNull(client.guid);
|
||||
Assert.assertNotNull(client.tabs);
|
||||
Assert.assertEquals(0, client.tabs.size());
|
||||
}
|
||||
// Client should sorted by name alphabetically.
|
||||
Assert.assertEquals(CLIENT_REMOTE2_NAME, clients.get(0).name);
|
||||
Assert.assertEquals(CLIENT_REMOTE1_NAME, clients.get(1).name);
|
||||
} finally {
|
||||
allClients.close();
|
||||
}
|
||||
} finally {
|
||||
cpc.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRecentRemoteClientsUpToOneWeekOld() throws Exception {
|
||||
final Uri uri = BrowserContractHelpers.CLIENTS_CONTENT_URI;
|
||||
final ContentProviderClient cpc = getClientsClient();
|
||||
final LocalTabsAccessor accessor = new LocalTabsAccessor("test"); // The profile name given doesn't matter.
|
||||
final Context context = RuntimeEnvironment.application.getApplicationContext();
|
||||
|
||||
try {
|
||||
// Start Clean
|
||||
cpc.delete(uri, null, null);
|
||||
final Cursor allClients = cpc.query(uri, null, null, null, null);
|
||||
try {
|
||||
Assert.assertEquals(0, allClients.getCount());
|
||||
} finally {
|
||||
allClients.close();
|
||||
}
|
||||
|
||||
// Insert a local and remote1 client record, neither with tabs.
|
||||
final long now = System.currentTimeMillis();
|
||||
// Local client has GUID = null.
|
||||
final ContentValues local = new ContentValues();
|
||||
local.put(BrowserContract.Clients.NAME, "local");
|
||||
local.put(BrowserContract.Clients.LAST_MODIFIED, now + 1);
|
||||
// Remote clients have GUID != null.
|
||||
final ContentValues remote1 = new ContentValues();
|
||||
remote1.put(BrowserContract.Clients.GUID, "guid1");
|
||||
remote1.put(BrowserContract.Clients.NAME, "remote1");
|
||||
remote1.put(BrowserContract.Clients.LAST_MODIFIED, now + 2);
|
||||
|
||||
// Insert a Remote Client that is 6 days old.
|
||||
final ContentValues remote2 = new ContentValues();
|
||||
remote2.put(BrowserContract.Clients.GUID, "guid2");
|
||||
remote2.put(BrowserContract.Clients.NAME, "remote2");
|
||||
remote2.put(BrowserContract.Clients.LAST_MODIFIED, now - ONE_WEEK_IN_MILLISECONDS + ONE_DAY_IN_MILLISECONDS);
|
||||
|
||||
// Insert a Remote Client with the same name as previous but with more than 3 weeks old
|
||||
final ContentValues remote3 = new ContentValues();
|
||||
remote3.put(BrowserContract.Clients.GUID, "guid21");
|
||||
remote3.put(BrowserContract.Clients.NAME, "remote2");
|
||||
remote3.put(BrowserContract.Clients.LAST_MODIFIED, now - THREE_WEEKS_IN_MILLISECONDS - ONE_DAY_IN_MILLISECONDS);
|
||||
|
||||
// Insert another remote client with the same name as previous but with 3 weeks - 1 day old.
|
||||
final ContentValues remote4 = new ContentValues();
|
||||
remote4.put(BrowserContract.Clients.GUID, "guid22");
|
||||
remote4.put(BrowserContract.Clients.NAME, "remote2");
|
||||
remote4.put(BrowserContract.Clients.LAST_MODIFIED, now - THREE_WEEKS_IN_MILLISECONDS + ONE_DAY_IN_MILLISECONDS);
|
||||
|
||||
// Insert a Remote Client that is exactly one week old.
|
||||
final ContentValues remote5 = new ContentValues();
|
||||
remote5.put(BrowserContract.Clients.GUID, "guid3");
|
||||
remote5.put(BrowserContract.Clients.NAME, "remote3");
|
||||
remote5.put(BrowserContract.Clients.LAST_MODIFIED, now - ONE_WEEK_IN_MILLISECONDS);
|
||||
|
||||
ContentValues[] values = new ContentValues[]{local, remote1, remote2, remote3, remote4, remote5};
|
||||
int inserted = cpc.bulkInsert(uri, values);
|
||||
Assert.assertEquals(values.length, inserted);
|
||||
|
||||
final Cursor remoteClients =
|
||||
accessor.getRemoteClientsNoStaleSorted(context);
|
||||
|
||||
try {
|
||||
CursorDumper.dumpCursor(remoteClients);
|
||||
// Local client is not included.
|
||||
// (remote1, guid1), (remote2, guid2), (remote3, guid3) are expected.
|
||||
Assert.assertEquals(3, remoteClients.getCount());
|
||||
|
||||
// Check the inner data, according to recency.
|
||||
List<RemoteClient> recentRemoteClientsList =
|
||||
accessor.getClientsWithoutTabsNoStaleSortedFromCursor(remoteClients);
|
||||
Assert.assertEquals(3, recentRemoteClientsList.size());
|
||||
Assert.assertEquals("remote1", recentRemoteClientsList.get(0).name);
|
||||
Assert.assertEquals("guid1", recentRemoteClientsList.get(0).guid);
|
||||
Assert.assertEquals("remote2", recentRemoteClientsList.get(1).name);
|
||||
Assert.assertEquals("guid2", recentRemoteClientsList.get(1).guid);
|
||||
Assert.assertEquals("remote3", recentRemoteClientsList.get(2).name);
|
||||
Assert.assertEquals("guid3", recentRemoteClientsList.get(2).guid);
|
||||
} finally {
|
||||
remoteClients.close();
|
||||
}
|
||||
} finally {
|
||||
cpc.release();
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче