mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 728612 - Android Sync: upload Fennec's open tabs for display in Tabs From Other Computers. r=rnewman
--HG-- extra : rebase_source : 1f9b99ca3bdb5943603c332d7aea81733725521a
This commit is contained in:
parent
7fd4a3d8cf
commit
8c4fdab81d
@ -4,7 +4,11 @@
|
|||||||
|
|
||||||
package org.mozilla.gecko.sync.repositories.android;
|
package org.mozilla.gecko.sync.repositories.android;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
import org.mozilla.gecko.db.BrowserContract;
|
import org.mozilla.gecko.db.BrowserContract;
|
||||||
|
import org.mozilla.gecko.db.BrowserContract.Tabs;
|
||||||
import org.mozilla.gecko.sync.Logger;
|
import org.mozilla.gecko.sync.Logger;
|
||||||
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
|
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
|
||||||
import org.mozilla.gecko.sync.repositories.NoContentProviderException;
|
import org.mozilla.gecko.sync.repositories.NoContentProviderException;
|
||||||
@ -18,14 +22,23 @@ import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionGuidsSince
|
|||||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
|
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
|
||||||
import org.mozilla.gecko.sync.repositories.domain.Record;
|
import org.mozilla.gecko.sync.repositories.domain.Record;
|
||||||
import org.mozilla.gecko.sync.repositories.domain.TabsRecord;
|
import org.mozilla.gecko.sync.repositories.domain.TabsRecord;
|
||||||
|
import org.mozilla.gecko.sync.repositories.domain.TabsRecord.Tab;
|
||||||
|
|
||||||
import android.content.ContentProviderClient;
|
import android.content.ContentProviderClient;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
|
||||||
public class FennecTabsRepository extends Repository {
|
public class FennecTabsRepository extends Repository {
|
||||||
|
protected final String localClientName;
|
||||||
|
protected final String localClientGuid;
|
||||||
|
|
||||||
|
public FennecTabsRepository(final String localClientName, final String localClientGuid) {
|
||||||
|
this.localClientName = localClientName;
|
||||||
|
this.localClientGuid = localClientGuid;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note that — unlike most repositories — this will only fetch Fennec's tabs,
|
* Note that — unlike most repositories — this will only fetch Fennec's tabs,
|
||||||
@ -35,15 +48,15 @@ public class FennecTabsRepository extends Repository {
|
|||||||
* unless you use {@link #fetch(String[], RepositorySessionFetchRecordsDelegate)}
|
* unless you use {@link #fetch(String[], RepositorySessionFetchRecordsDelegate)}
|
||||||
* and specify an explicit GUID.
|
* and specify an explicit GUID.
|
||||||
*/
|
*/
|
||||||
public static class FennecTabsRepositorySession extends RepositorySession {
|
public class FennecTabsRepositorySession extends RepositorySession {
|
||||||
|
protected static final String LOG_TAG = "FennecTabsSession";
|
||||||
private static final String LOG_TAG = "FennecTabsSession";
|
|
||||||
|
|
||||||
private final ContentProviderClient tabsProvider;
|
private final ContentProviderClient tabsProvider;
|
||||||
private final ContentProviderClient clientsProvider;
|
private final ContentProviderClient clientsProvider;
|
||||||
|
|
||||||
protected ContentProviderClient getContentProvider(final Context context, final Uri uri) throws NoContentProviderException {
|
protected final RepoUtils.QueryHelper tabsHelper;
|
||||||
|
|
||||||
|
protected ContentProviderClient getContentProvider(final Context context, final Uri uri) throws NoContentProviderException {
|
||||||
ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(uri);
|
ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(uri);
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
throw new NoContentProviderException(uri);
|
throw new NoContentProviderException(uri);
|
||||||
@ -60,7 +73,6 @@ public class FennecTabsRepository extends Repository {
|
|||||||
} catch (Exception e) {}
|
} catch (Exception e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public FennecTabsRepositorySession(Repository repository, Context context) throws NoContentProviderException {
|
public FennecTabsRepositorySession(Repository repository, Context context) throws NoContentProviderException {
|
||||||
super(repository);
|
super(repository);
|
||||||
clientsProvider = getContentProvider(context, BrowserContract.Clients.CONTENT_URI);
|
clientsProvider = getContentProvider(context, BrowserContract.Clients.CONTENT_URI);
|
||||||
@ -74,6 +86,8 @@ public class FennecTabsRepository extends Repository {
|
|||||||
// Oh, Java.
|
// Oh, Java.
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tabsHelper = new RepoUtils.QueryHelper(context, BrowserContract.Tabs.CONTENT_URI, LOG_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -88,37 +102,96 @@ public class FennecTabsRepository extends Repository {
|
|||||||
super.finish(delegate);
|
super.finish(delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// Default parameters for local data: local client has null GUID. Override
|
||||||
public void guidsSince(long timestamp,
|
// these to test against non-live data.
|
||||||
RepositorySessionGuidsSinceDelegate delegate) {
|
protected String localClientSelection() {
|
||||||
// Empty until Bug 730039 lands.
|
return BrowserContract.Tabs.CLIENT_GUID + " IS NULL";
|
||||||
delegate.onGuidsSinceSucceeded(new String[] {});
|
}
|
||||||
|
|
||||||
|
protected String[] localClientSelectionArgs() {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetchSince(long timestamp,
|
public void guidsSince(final long timestamp,
|
||||||
RepositorySessionFetchRecordsDelegate delegate) {
|
final RepositorySessionGuidsSinceDelegate delegate) {
|
||||||
// Empty until Bug 730039 lands.
|
// Bug 783692: Now that Bug 730039 has landed, we could implement this,
|
||||||
delegate.onFetchCompleted(now());
|
// but it's not a priority since it's not used (yet).
|
||||||
|
Logger.warn(LOG_TAG, "Not returning anything from guidsSince.");
|
||||||
|
delegateQueue.execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
delegate.onGuidsSinceSucceeded(new String[] {});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetch(String[] guids,
|
public void fetchSince(final long timestamp,
|
||||||
RepositorySessionFetchRecordsDelegate delegate) {
|
final RepositorySessionFetchRecordsDelegate delegate) {
|
||||||
// Incomplete until Bug 730039 lands.
|
if (tabsProvider == null) {
|
||||||
// TODO
|
throw new IllegalArgumentException("tabsProvider was null.");
|
||||||
delegate.onFetchCompleted(now());
|
}
|
||||||
|
if (tabsHelper == null) {
|
||||||
|
throw new IllegalArgumentException("tabsHelper was null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
final String positionAscending = BrowserContract.Tabs.POSITION + " ASC";
|
||||||
|
|
||||||
|
final String localClientSelection = localClientSelection();
|
||||||
|
final String[] localClientSelectionArgs = localClientSelectionArgs();
|
||||||
|
|
||||||
|
final Runnable command = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// We fetch all local tabs (since the record must contain them all)
|
||||||
|
// but only process the record if the timestamp is sufficiently
|
||||||
|
// recent.
|
||||||
|
try {
|
||||||
|
final Cursor cursor = tabsHelper.safeQuery(tabsProvider, ".fetchSince()", null,
|
||||||
|
localClientSelection, localClientSelectionArgs, positionAscending);
|
||||||
|
try {
|
||||||
|
final TabsRecord tabsRecord = FennecTabsRepository.tabsRecordFromCursor(cursor, localClientGuid, localClientName);
|
||||||
|
|
||||||
|
if (tabsRecord.lastModified >= timestamp) {
|
||||||
|
delegate.onFetchedRecord(tabsRecord);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
delegate.onFetchFailed(e, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delegate.onFetchCompleted(now());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
delegateQueue.execute(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetchAll(RepositorySessionFetchRecordsDelegate delegate) {
|
public void fetch(final String[] guids,
|
||||||
// Incomplete until Bug 730039 lands.
|
final RepositorySessionFetchRecordsDelegate delegate) {
|
||||||
// TODO
|
// Bug 783692: Now that Bug 730039 has landed, we could implement this,
|
||||||
delegate.onFetchCompleted(now());
|
// but it's not a priority since it's not used (yet).
|
||||||
|
Logger.warn(LOG_TAG, "Not returning anything from fetch");
|
||||||
|
delegateQueue.execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
delegate.onFetchCompleted(now());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fetchAll(final RepositorySessionFetchRecordsDelegate delegate) {
|
||||||
|
fetchSince(0, delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String TABS_CLIENT_GUID_IS = BrowserContract.Tabs.CLIENT_GUID + " = ?";
|
private static final String TABS_CLIENT_GUID_IS = BrowserContract.Tabs.CLIENT_GUID + " = ?";
|
||||||
private static final String CLIENT_GUID_IS = BrowserContract.Clients.GUID + " = ?";
|
private static final String CLIENT_GUID_IS = BrowserContract.Clients.GUID + " = ?";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void store(final Record record) throws NoStoreDelegateException {
|
public void store(final Record record) throws NoStoreDelegateException {
|
||||||
if (delegate == null) {
|
if (delegate == null) {
|
||||||
@ -219,4 +292,69 @@ public class FennecTabsRepository extends Repository {
|
|||||||
delegate.onSessionCreateFailed(e);
|
delegate.onSessionCreateFailed(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract a <code>Tab</code> from a cursor row.
|
||||||
|
* <p>
|
||||||
|
* Caller is responsible for creating, positioning, and closing the cursor.
|
||||||
|
*
|
||||||
|
* @param cursor
|
||||||
|
* to inspect.
|
||||||
|
* @return <code>Tab</code> instance.
|
||||||
|
*/
|
||||||
|
public static Tab tabFromCursor(final Cursor cursor) {
|
||||||
|
final String title = RepoUtils.getStringFromCursor(cursor, Tabs.TITLE);
|
||||||
|
final String icon = RepoUtils.getStringFromCursor(cursor, Tabs.FAVICON);
|
||||||
|
final JSONArray history = RepoUtils.getJSONArrayFromCursor(cursor, Tabs.HISTORY);
|
||||||
|
final long lastUsed = RepoUtils.getLongFromCursor(cursor, Tabs.LAST_USED);
|
||||||
|
|
||||||
|
return new Tab(title, icon, history, lastUsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract a <code>TabsRecord</code> from a cursor.
|
||||||
|
* <p>
|
||||||
|
* Caller is responsible for creating and closing cursor. Each row of the
|
||||||
|
* cursor should be an individual tab record.
|
||||||
|
* <p>
|
||||||
|
* The extracted tabs record has the given client GUID and client name.
|
||||||
|
*
|
||||||
|
* @param cursor
|
||||||
|
* to inspect.
|
||||||
|
* @param clientGuid
|
||||||
|
* returned tabs record will have this client GUID.
|
||||||
|
* @param clientName
|
||||||
|
* returned tabs record will have this client name.
|
||||||
|
* @return <code>TabsRecord</code> instance.
|
||||||
|
*/
|
||||||
|
public static TabsRecord tabsRecordFromCursor(final Cursor cursor, final String clientGuid, final String clientName) {
|
||||||
|
final String collection = "tabs";
|
||||||
|
final TabsRecord record = new TabsRecord(clientGuid, collection, 0, false);
|
||||||
|
record.tabs = new ArrayList<TabsRecord.Tab>();
|
||||||
|
record.clientName = clientName;
|
||||||
|
|
||||||
|
record.androidID = -1;
|
||||||
|
record.deleted = false;
|
||||||
|
|
||||||
|
record.lastModified = 0;
|
||||||
|
|
||||||
|
int position = cursor.getPosition();
|
||||||
|
try {
|
||||||
|
cursor.moveToFirst();
|
||||||
|
while (!cursor.isAfterLast()) {
|
||||||
|
final Tab tab = FennecTabsRepository.tabFromCursor(cursor);
|
||||||
|
record.tabs.add(tab);
|
||||||
|
|
||||||
|
if (tab.lastUsed > record.lastModified) {
|
||||||
|
record.lastModified = tab.lastUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor.moveToNext();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
cursor.moveToPosition(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
return record;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,14 @@ package org.mozilla.gecko.sync.repositories.domain;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.json.simple.JSONObject;
|
|
||||||
import org.json.simple.JSONArray;
|
import org.json.simple.JSONArray;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
import org.mozilla.gecko.db.BrowserContract;
|
import org.mozilla.gecko.db.BrowserContract;
|
||||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
import org.mozilla.gecko.sync.Logger;
|
import org.mozilla.gecko.sync.Logger;
|
||||||
import org.mozilla.gecko.sync.NonArrayJSONException;
|
import org.mozilla.gecko.sync.NonArrayJSONException;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.sync.repositories.android.RepoUtils;
|
||||||
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
|
|
||||||
@ -80,7 +81,27 @@ public class TabsRecord extends Record {
|
|||||||
out.put(BrowserContract.Tabs.URL, (String) this.history.get(0));
|
out.put(BrowserContract.Tabs.URL, (String) this.history.get(0));
|
||||||
out.put(BrowserContract.Tabs.HISTORY, this.history.toJSONString());
|
out.put(BrowserContract.Tabs.HISTORY, this.history.toJSONString());
|
||||||
return out;
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof Tab)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Tab other = (Tab) o;
|
||||||
|
|
||||||
|
if (!RepoUtils.stringsEqual(this.title, other.title)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!RepoUtils.stringsEqual(this.icon, other.icon)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(this.lastUsed == other.lastUsed)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utils.sameArrays(this.history, other.history);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ package org.mozilla.gecko.sync.stage;
|
|||||||
|
|
||||||
import org.mozilla.gecko.sync.CryptoRecord;
|
import org.mozilla.gecko.sync.CryptoRecord;
|
||||||
import org.mozilla.gecko.sync.GlobalSession;
|
import org.mozilla.gecko.sync.GlobalSession;
|
||||||
|
import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
|
||||||
import org.mozilla.gecko.sync.repositories.RecordFactory;
|
import org.mozilla.gecko.sync.repositories.RecordFactory;
|
||||||
import org.mozilla.gecko.sync.repositories.Repository;
|
import org.mozilla.gecko.sync.repositories.Repository;
|
||||||
import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository;
|
import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository;
|
||||||
@ -46,7 +47,8 @@ public class FennecTabsServerSyncStage extends ServerSyncStage {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Repository getLocalRepository() {
|
protected Repository getLocalRepository() {
|
||||||
return new FennecTabsRepository();
|
final ClientsDataDelegate clientsDelegate = session.getClientsDelegate();
|
||||||
|
return new FennecTabsRepository(clientsDelegate.getClientName(), clientsDelegate.getAccountGUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user