зеркало из https://github.com/mozilla/gecko-dev.git
Bug 732768 - Eliminate shared state and concurrency problems in tests. r=nalexander
This commit is contained in:
Родитель
3e39a7f97a
Коммит
eac977d975
|
@ -1,39 +1,6 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Android Sync Client.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Richard Newman <rnewman@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* 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.sync.middleware;
|
||||
|
||||
|
@ -43,16 +10,12 @@ import java.util.concurrent.ExecutorService;
|
|||
import org.mozilla.gecko.sync.CryptoRecord;
|
||||
import org.mozilla.gecko.sync.crypto.CryptoException;
|
||||
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
||||
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
|
||||
import org.mozilla.gecko.sync.repositories.NoStoreDelegateException;
|
||||
import org.mozilla.gecko.sync.repositories.RecordFactory;
|
||||
import org.mozilla.gecko.sync.repositories.RepositorySession;
|
||||
import org.mozilla.gecko.sync.repositories.RepositorySessionBundle;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionGuidsSinceDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionStoreDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.domain.Record;
|
||||
|
||||
/**
|
||||
|
@ -94,14 +57,12 @@ import org.mozilla.gecko.sync.repositories.domain.Record;
|
|||
* @author rnewman
|
||||
*
|
||||
*/
|
||||
public class Crypto5MiddlewareRepositorySession extends RepositorySession {
|
||||
public class Crypto5MiddlewareRepositorySession extends MiddlewareRepositorySession {
|
||||
private KeyBundle keyBundle;
|
||||
private RepositorySession inner;
|
||||
private RecordFactory recordFactory;
|
||||
|
||||
public Crypto5MiddlewareRepositorySession(RepositorySession session, Crypto5MiddlewareRepository repository, RecordFactory recordFactory) {
|
||||
super(repository);
|
||||
this.inner = session;
|
||||
super(session, repository);
|
||||
this.keyBundle = repository.keyBundle;
|
||||
this.recordFactory = recordFactory;
|
||||
}
|
||||
|
@ -180,13 +141,6 @@ public class Crypto5MiddlewareRepositorySession extends RepositorySession {
|
|||
return new DecryptingTransformingFetchDelegate(inner, this.keyBundle, this.recordFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void guidsSince(long timestamp,
|
||||
RepositorySessionGuidsSinceDelegate delegate) {
|
||||
// TODO: need to do anything here?
|
||||
inner.guidsSince(timestamp, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetchSince(long timestamp,
|
||||
RepositorySessionFetchRecordsDelegate delegate) {
|
||||
|
@ -195,7 +149,7 @@ public class Crypto5MiddlewareRepositorySession extends RepositorySession {
|
|||
|
||||
@Override
|
||||
public void fetch(String[] guids,
|
||||
RepositorySessionFetchRecordsDelegate delegate) {
|
||||
RepositorySessionFetchRecordsDelegate delegate) throws InactiveSessionException {
|
||||
inner.fetch(guids, makeUnwrappingDelegate(delegate));
|
||||
}
|
||||
|
||||
|
@ -230,92 +184,4 @@ public class Crypto5MiddlewareRepositorySession extends RepositorySession {
|
|||
// Allow the inner session to do delegate handling.
|
||||
inner.store(rec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wipe(RepositorySessionWipeDelegate delegate) {
|
||||
inner.wipe(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeDone() {
|
||||
inner.storeDone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeDone(long storeEnd) {
|
||||
inner.storeDone(storeEnd);
|
||||
}
|
||||
|
||||
public class Crypto5MiddlewareRepositorySessionBeginDelegate implements RepositorySessionBeginDelegate {
|
||||
private Crypto5MiddlewareRepositorySession outerSession;
|
||||
private RepositorySessionBeginDelegate next;
|
||||
|
||||
public Crypto5MiddlewareRepositorySessionBeginDelegate(Crypto5MiddlewareRepositorySession outerSession, RepositorySessionBeginDelegate next) {
|
||||
this.outerSession = outerSession;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeginFailed(Exception ex) {
|
||||
next.onBeginFailed(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeginSucceeded(RepositorySession session) {
|
||||
outerSession.setStatus(SessionStatus.ACTIVE);
|
||||
next.onBeginSucceeded(outerSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public void begin(RepositorySessionBeginDelegate delegate) {
|
||||
inner.begin(new Crypto5MiddlewareRepositorySessionBeginDelegate(this, delegate));
|
||||
}
|
||||
|
||||
public class Crypto5MiddlewareRepositorySessionFinishDelegate implements RepositorySessionFinishDelegate {
|
||||
private Crypto5MiddlewareRepositorySession outerSession;
|
||||
private RepositorySessionFinishDelegate next;
|
||||
|
||||
public Crypto5MiddlewareRepositorySessionFinishDelegate(Crypto5MiddlewareRepositorySession outerSession, RepositorySessionFinishDelegate next) {
|
||||
this.outerSession = outerSession;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishFailed(Exception ex) {
|
||||
next.onFinishFailed(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishSucceeded(RepositorySession session, RepositorySessionBundle bundle) {
|
||||
outerSession.setStatus(SessionStatus.DONE);
|
||||
next.onFinishSucceeded(outerSession, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositorySessionFinishDelegate deferredFinishDelegate(ExecutorService executor) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish(RepositorySessionFinishDelegate delegate) {
|
||||
inner.finish(new Crypto5MiddlewareRepositorySessionFinishDelegate(this, delegate));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort() {
|
||||
setStatus(SessionStatus.ABORTED);
|
||||
inner.abort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort(RepositorySessionFinishDelegate delegate) {
|
||||
this.status = SessionStatus.DONE; // TODO: ABORTED?
|
||||
inner.abort(new Crypto5MiddlewareRepositorySessionFinishDelegate(this, delegate));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,5 @@ public abstract class MiddlewareRepository extends Repository {
|
|||
public RepositorySessionCreationDelegate deferredCreationDelegate() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
/* 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.sync.middleware;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.mozilla.gecko.sync.Logger;
|
||||
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
|
||||
import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
|
||||
import org.mozilla.gecko.sync.repositories.RepositorySession;
|
||||
import org.mozilla.gecko.sync.repositories.RepositorySessionBundle;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionGuidsSinceDelegate;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
|
||||
|
||||
public abstract class MiddlewareRepositorySession extends RepositorySession {
|
||||
private static final String LOG_TAG = "MiddlewareSession";
|
||||
protected final RepositorySession inner;
|
||||
|
||||
public MiddlewareRepositorySession(RepositorySession innerSession, MiddlewareRepository repository) {
|
||||
super(repository);
|
||||
this.inner = innerSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wipe(RepositorySessionWipeDelegate delegate) {
|
||||
inner.wipe(delegate);
|
||||
}
|
||||
|
||||
public class MiddlewareRepositorySessionBeginDelegate implements RepositorySessionBeginDelegate {
|
||||
|
||||
private MiddlewareRepositorySession outerSession;
|
||||
private RepositorySessionBeginDelegate next;
|
||||
|
||||
public MiddlewareRepositorySessionBeginDelegate(MiddlewareRepositorySession outerSession, RepositorySessionBeginDelegate next) {
|
||||
this.outerSession = outerSession;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeginFailed(Exception ex) {
|
||||
next.onBeginFailed(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeginSucceeded(RepositorySession session) {
|
||||
next.onBeginSucceeded(outerSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
|
||||
final RepositorySessionBeginDelegate deferred = next.deferredBeginDelegate(executor);
|
||||
return new RepositorySessionBeginDelegate() {
|
||||
@Override
|
||||
public void onBeginSucceeded(RepositorySession session) {
|
||||
if (inner != session) {
|
||||
Logger.warn(LOG_TAG, "Got onBeginSucceeded for session " + session + ", not our inner session!");
|
||||
}
|
||||
deferred.onBeginSucceeded(outerSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeginFailed(Exception ex) {
|
||||
deferred.onBeginFailed(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositorySessionBeginDelegate deferredBeginDelegate(ExecutorService executor) {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
|
||||
inner.begin(new MiddlewareRepositorySessionBeginDelegate(this, delegate));
|
||||
}
|
||||
|
||||
public class MiddlewareRepositorySessionFinishDelegate implements RepositorySessionFinishDelegate {
|
||||
private final MiddlewareRepositorySession outerSession;
|
||||
private final RepositorySessionFinishDelegate next;
|
||||
|
||||
public MiddlewareRepositorySessionFinishDelegate(MiddlewareRepositorySession outerSession, RepositorySessionFinishDelegate next) {
|
||||
this.outerSession = outerSession;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishFailed(Exception ex) {
|
||||
next.onFinishFailed(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishSucceeded(RepositorySession session, RepositorySessionBundle bundle) {
|
||||
next.onFinishSucceeded(outerSession, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepositorySessionFinishDelegate deferredFinishDelegate(ExecutorService executor) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish(RepositorySessionFinishDelegate delegate) throws InactiveSessionException {
|
||||
inner.finish(new MiddlewareRepositorySessionFinishDelegate(this, delegate));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void ensureActive() throws InactiveSessionException {
|
||||
inner.ensureActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isActive() {
|
||||
return inner.isActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized SessionStatus getStatus() {
|
||||
return inner.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setStatus(SessionStatus status) {
|
||||
inner.setStatus(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void transitionFrom(SessionStatus from, SessionStatus to)
|
||||
throws InvalidSessionTransitionException {
|
||||
inner.transitionFrom(from, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort() {
|
||||
inner.abort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort(RepositorySessionFinishDelegate delegate) {
|
||||
inner.abort(new MiddlewareRepositorySessionFinishDelegate(this, delegate));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void guidsSince(long timestamp, RepositorySessionGuidsSinceDelegate delegate) {
|
||||
// TODO: need to do anything here?
|
||||
inner.guidsSince(timestamp, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeDone() {
|
||||
inner.storeDone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeDone(long storeEnd) {
|
||||
inner.storeDone(storeEnd);
|
||||
}
|
||||
}
|
|
@ -80,7 +80,7 @@ public abstract class RepositorySession {
|
|||
Logger.trace(LOG_TAG, message);
|
||||
}
|
||||
|
||||
protected SessionStatus status = SessionStatus.UNSTARTED;
|
||||
private SessionStatus status = SessionStatus.UNSTARTED;
|
||||
protected Repository repository;
|
||||
protected RepositorySessionStoreDelegate delegate;
|
||||
|
||||
|
@ -109,7 +109,7 @@ public abstract class RepositorySession {
|
|||
|
||||
public abstract void guidsSince(long timestamp, RepositorySessionGuidsSinceDelegate delegate);
|
||||
public abstract void fetchSince(long timestamp, RepositorySessionFetchRecordsDelegate delegate);
|
||||
public abstract void fetch(String[] guids, RepositorySessionFetchRecordsDelegate delegate);
|
||||
public abstract void fetch(String[] guids, RepositorySessionFetchRecordsDelegate delegate) throws InactiveSessionException;
|
||||
public abstract void fetchAll(RepositorySessionFetchRecordsDelegate delegate);
|
||||
|
||||
/**
|
||||
|
@ -182,21 +182,19 @@ public abstract class RepositorySession {
|
|||
*
|
||||
*/
|
||||
protected void sharedBegin() throws InvalidSessionTransitionException {
|
||||
if (this.status == SessionStatus.UNSTARTED) {
|
||||
this.status = SessionStatus.ACTIVE;
|
||||
} else {
|
||||
Logger.error(LOG_TAG, "Tried to begin() an already active or finished session");
|
||||
Logger.debug(LOG_TAG, "Shared begin.");
|
||||
if (delegateQueue.isShutdown()) {
|
||||
throw new InvalidSessionTransitionException(null);
|
||||
}
|
||||
if (storeWorkQueue.isShutdown()) {
|
||||
throw new InvalidSessionTransitionException(null);
|
||||
}
|
||||
this.transitionFrom(SessionStatus.UNSTARTED, SessionStatus.ACTIVE);
|
||||
}
|
||||
|
||||
public void begin(RepositorySessionBeginDelegate delegate) {
|
||||
try {
|
||||
sharedBegin();
|
||||
delegate.deferredBeginDelegate(delegateQueue).onBeginSucceeded(this);
|
||||
} catch (Exception e) {
|
||||
delegate.deferredBeginDelegate(delegateQueue).onBeginFailed(e);
|
||||
}
|
||||
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
|
||||
sharedBegin();
|
||||
delegate.deferredBeginDelegate(delegateQueue).onBeginSucceeded(this);
|
||||
}
|
||||
|
||||
protected RepositorySessionBundle getBundle() {
|
||||
|
@ -231,43 +229,85 @@ public abstract class RepositorySession {
|
|||
* @param delegate
|
||||
*/
|
||||
public void abort(RepositorySessionFinishDelegate delegate) {
|
||||
this.status = SessionStatus.DONE; // TODO: ABORTED?
|
||||
this.abort();
|
||||
delegate.deferredFinishDelegate(delegateQueue).onFinishSucceeded(this, this.getBundle(null));
|
||||
}
|
||||
|
||||
public void finish(final RepositorySessionFinishDelegate delegate) {
|
||||
if (this.status == SessionStatus.ACTIVE) {
|
||||
this.status = SessionStatus.DONE;
|
||||
delegate.deferredFinishDelegate(delegateQueue).onFinishSucceeded(this, this.getBundle(null));
|
||||
} else {
|
||||
Logger.error(LOG_TAG, "Tried to finish() an unstarted or already finished session");
|
||||
Exception e = new InvalidSessionTransitionException(null);
|
||||
delegate.deferredFinishDelegate(delegateQueue).onFinishFailed(e);
|
||||
}
|
||||
Logger.info(LOG_TAG, "Shutting down work queues.");
|
||||
// storeWorkQueue.shutdown();
|
||||
// delegateQueue.shutdown();
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return status == SessionStatus.ACTIVE;
|
||||
}
|
||||
|
||||
public SessionStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(SessionStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public void abort() {
|
||||
// TODO: do something here.
|
||||
status = SessionStatus.ABORTED;
|
||||
this.setStatus(SessionStatus.ABORTED);
|
||||
try {
|
||||
storeWorkQueue.shutdown();
|
||||
} catch (Exception e) {
|
||||
Logger.error(LOG_TAG, "Caught exception shutting down store work queue.", e);
|
||||
}
|
||||
try {
|
||||
delegateQueue.shutdown();
|
||||
} catch (Exception e) {
|
||||
Logger.error(LOG_TAG, "Caught exception shutting down delegate queue.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void finish(final RepositorySessionFinishDelegate delegate) throws InactiveSessionException {
|
||||
try {
|
||||
this.transitionFrom(SessionStatus.ACTIVE, SessionStatus.DONE);
|
||||
delegate.deferredFinishDelegate(delegateQueue).onFinishSucceeded(this, this.getBundle(null));
|
||||
} catch (InvalidSessionTransitionException e) {
|
||||
Logger.error(LOG_TAG, "Tried to finish() an unstarted or already finished session");
|
||||
InactiveSessionException ex = new InactiveSessionException(null);
|
||||
ex.initCause(e);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
Logger.info(LOG_TAG, "Shutting down work queues.");
|
||||
storeWorkQueue.shutdown();
|
||||
delegateQueue.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the provided command if we're active and our delegate queue
|
||||
* is not shut down.
|
||||
*
|
||||
* @param command
|
||||
* @throws InactiveSessionException
|
||||
*/
|
||||
protected synchronized void executeDelegateCommand(Runnable command)
|
||||
throws InactiveSessionException {
|
||||
if (!isActive() || delegateQueue.isShutdown()) {
|
||||
throw new InactiveSessionException(null);
|
||||
}
|
||||
delegateQueue.execute(command);
|
||||
}
|
||||
|
||||
public synchronized void ensureActive() throws InactiveSessionException {
|
||||
if (!isActive()) {
|
||||
throw new InactiveSessionException(null);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean isActive() {
|
||||
return status == SessionStatus.ACTIVE;
|
||||
}
|
||||
|
||||
public synchronized SessionStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public synchronized void setStatus(SessionStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public synchronized void transitionFrom(SessionStatus from, SessionStatus to) throws InvalidSessionTransitionException {
|
||||
if (from == null || this.status == from) {
|
||||
Logger.trace(LOG_TAG, "Successfully transitioning from " + this.status + " to " + to);
|
||||
|
||||
this.status = to;
|
||||
return;
|
||||
}
|
||||
Logger.warn(LOG_TAG, "Wanted to transition from " + from + " but in state " + this.status);
|
||||
throw new InvalidSessionTransitionException(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce a record that is some combination of the remote and local records
|
||||
* provided.
|
||||
|
|
|
@ -24,7 +24,7 @@ public abstract class StoreTrackingRepositorySession extends RepositorySession {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void begin(RepositorySessionBeginDelegate delegate) {
|
||||
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
|
||||
RepositorySessionBeginDelegate deferredDelegate = delegate.deferredBeginDelegate(delegateQueue);
|
||||
try {
|
||||
super.sharedBegin();
|
||||
|
@ -74,7 +74,7 @@ public abstract class StoreTrackingRepositorySession extends RepositorySession {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void finish(RepositorySessionFinishDelegate delegate) {
|
||||
public void finish(RepositorySessionFinishDelegate delegate) throws InactiveSessionException {
|
||||
super.finish(delegate);
|
||||
this.storeTracker = null;
|
||||
}
|
||||
|
|
|
@ -1,40 +1,6 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Android Sync Client.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jason Voll <jvoll@mozilla.com>
|
||||
* Richard Newman <rnewman@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* 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.sync.repositories.android;
|
||||
|
||||
|
@ -48,7 +14,8 @@ public class AndroidBrowserBookmarksRepository extends AndroidBrowserRepository
|
|||
@Override
|
||||
protected void sessionCreator(RepositorySessionCreationDelegate delegate, Context context) {
|
||||
AndroidBrowserBookmarksRepositorySession session = new AndroidBrowserBookmarksRepositorySession(AndroidBrowserBookmarksRepository.this, context);
|
||||
delegate.onSessionCreated(session);
|
||||
final RepositorySessionCreationDelegate deferredCreationDelegate = delegate.deferredCreationDelegate();
|
||||
deferredCreationDelegate.onSessionCreated(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,8 @@ import org.mozilla.gecko.R;
|
|||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.sync.Logger;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
|
||||
import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
|
||||
import org.mozilla.gecko.sync.repositories.NoGuidForIdException;
|
||||
import org.mozilla.gecko.sync.repositories.NullCursorException;
|
||||
import org.mozilla.gecko.sync.repositories.ParentNotFoundException;
|
||||
|
@ -478,7 +480,7 @@ public class AndroidBrowserBookmarksRepositorySession extends AndroidBrowserRepo
|
|||
}
|
||||
|
||||
@Override
|
||||
public void begin(RepositorySessionBeginDelegate delegate) {
|
||||
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
|
||||
// Check for the existence of special folders
|
||||
// and insert them if they don't exist.
|
||||
Cursor cur;
|
||||
|
@ -526,7 +528,7 @@ public class AndroidBrowserBookmarksRepositorySession extends AndroidBrowserRepo
|
|||
}
|
||||
|
||||
@Override
|
||||
public void finish(RepositorySessionFinishDelegate delegate) {
|
||||
public void finish(RepositorySessionFinishDelegate delegate) throws InactiveSessionException {
|
||||
// Override finish to do this check; make sure all records
|
||||
// needing re-parenting have been re-parented.
|
||||
if (needsReparenting != 0) {
|
||||
|
|
|
@ -141,14 +141,9 @@ public abstract class AndroidBrowserRepositorySession extends StoreTrackingRepos
|
|||
}
|
||||
|
||||
@Override
|
||||
public void begin(RepositorySessionBeginDelegate delegate) {
|
||||
public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
|
||||
RepositorySessionBeginDelegate deferredDelegate = delegate.deferredBeginDelegate(delegateQueue);
|
||||
try {
|
||||
super.sharedBegin();
|
||||
} catch (InvalidSessionTransitionException e) {
|
||||
deferredDelegate.onBeginFailed(e);
|
||||
return;
|
||||
}
|
||||
super.sharedBegin();
|
||||
|
||||
try {
|
||||
// We do this check here even though it results in one extra call to the DB
|
||||
|
@ -241,9 +236,9 @@ public abstract class AndroidBrowserRepositorySession extends StoreTrackingRepos
|
|||
|
||||
@Override
|
||||
public void fetch(String[] guids,
|
||||
RepositorySessionFetchRecordsDelegate delegate) {
|
||||
RepositorySessionFetchRecordsDelegate delegate) throws InactiveSessionException {
|
||||
FetchRunnable command = new FetchRunnable(guids, now(), null, delegate);
|
||||
delegateQueue.execute(command);
|
||||
executeDelegateCommand(command);
|
||||
}
|
||||
|
||||
abstract class FetchingRunnable implements Runnable {
|
||||
|
@ -289,7 +284,7 @@ public abstract class AndroidBrowserRepositorySession extends StoreTrackingRepos
|
|||
}
|
||||
}
|
||||
|
||||
class FetchRunnable extends FetchingRunnable {
|
||||
public class FetchRunnable extends FetchingRunnable {
|
||||
private String[] guids;
|
||||
private long end;
|
||||
private RecordFilter filter;
|
||||
|
@ -392,6 +387,7 @@ public abstract class AndroidBrowserRepositorySession extends StoreTrackingRepos
|
|||
@Override
|
||||
public void run() {
|
||||
if (!isActive()) {
|
||||
Logger.warn(LOG_TAG, "AndroidBrowserRepositorySession is inactive. Store failing.");
|
||||
delegate.onRecordStoreFailed(new InactiveSessionException(null));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ import java.util.concurrent.ExecutorService;
|
|||
|
||||
import org.mozilla.gecko.sync.Logger;
|
||||
import org.mozilla.gecko.sync.ThreadPool;
|
||||
import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
|
||||
import org.mozilla.gecko.sync.repositories.NoStoreDelegateException;
|
||||
import org.mozilla.gecko.sync.repositories.RepositorySession;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.DeferredRepositorySessionBeginDelegate;
|
||||
|
@ -166,8 +167,9 @@ class RecordsChannel implements
|
|||
|
||||
/**
|
||||
* Begin both sessions, invoking flow() when done.
|
||||
* @throws InvalidSessionTransitionException
|
||||
*/
|
||||
public void beginAndFlow() {
|
||||
public void beginAndFlow() throws InvalidSessionTransitionException {
|
||||
Logger.info(LOG_TAG, "Beginning source.");
|
||||
source.begin(this);
|
||||
}
|
||||
|
@ -251,7 +253,11 @@ class RecordsChannel implements
|
|||
public void onBeginSucceeded(RepositorySession session) {
|
||||
if (session == source) {
|
||||
Logger.info(LOG_TAG, "Source session began. Beginning sink session.");
|
||||
sink.begin(this);
|
||||
try {
|
||||
sink.begin(this);
|
||||
} catch (InvalidSessionTransitionException e) {
|
||||
onBeginFailed(e);
|
||||
}
|
||||
}
|
||||
if (session == sink) {
|
||||
Logger.info(LOG_TAG, "Sink session began. Beginning flow.");
|
||||
|
|
|
@ -40,6 +40,8 @@ package org.mozilla.gecko.sync.synchronizer;
|
|||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
|
||||
import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
|
||||
import org.mozilla.gecko.sync.repositories.RepositorySession;
|
||||
import org.mozilla.gecko.sync.repositories.RepositorySessionBundle;
|
||||
import org.mozilla.gecko.sync.repositories.delegates.DeferrableRepositorySessionCreationDelegate;
|
||||
|
@ -170,7 +172,11 @@ implements RecordsChannelDelegate,
|
|||
};
|
||||
final RecordsChannel channelAToB = new RecordsChannel(this.sessionA, this.sessionB, channelDelegate);
|
||||
info("Starting A to B flow. Channel is " + channelAToB);
|
||||
channelAToB.beginAndFlow();
|
||||
try {
|
||||
channelAToB.beginAndFlow();
|
||||
} catch (InvalidSessionTransitionException e) {
|
||||
onFlowBeginFailed(channelAToB, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -183,7 +189,11 @@ implements RecordsChannelDelegate,
|
|||
flowBToACompleted = true;
|
||||
|
||||
// Finish the two sessions.
|
||||
this.sessionA.finish(this);
|
||||
try {
|
||||
this.sessionA.finish(this);
|
||||
} catch (InactiveSessionException e) {
|
||||
this.onFinishFailed(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -297,7 +307,11 @@ implements RecordsChannelDelegate,
|
|||
if (this.sessionB != null) {
|
||||
info("Finishing session B.");
|
||||
// On to the next.
|
||||
this.sessionB.finish(this);
|
||||
try {
|
||||
this.sessionB.finish(this);
|
||||
} catch (InactiveSessionException e) {
|
||||
this.onFinishFailed(e);
|
||||
}
|
||||
}
|
||||
} else if (session == sessionB) {
|
||||
if (flowBToACompleted) {
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Загрузка…
Ссылка в новой задаче