1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-05 10:49:24 +02:00

use sync options in SynchroniserService

This commit is contained in:
Nikolay Pultsin 2014-07-28 04:38:36 +01:00
parent 324a48d384
commit 92759bc5ec
3 changed files with 95 additions and 27 deletions

View file

@ -25,7 +25,7 @@ import java.util.Map;
import android.app.Service;
import android.content.Context;
public final class ServiceNetworkContext extends AndroidNetworkContext {
public class ServiceNetworkContext extends AndroidNetworkContext {
private final Service myService;
public ServiceNetworkContext(Service service) {

View file

@ -24,6 +24,8 @@ import java.util.*;
import android.app.Service;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.IBinder;
import org.json.simple.JSONValue;
@ -32,6 +34,7 @@ import org.geometerplus.zlibrary.core.filesystem.ZLPhysicalFile;
import org.geometerplus.zlibrary.core.network.*;
import org.geometerplus.zlibrary.ui.android.network.SQLiteCookieDatabase;
import org.geometerplus.fbreader.book.*;
import org.geometerplus.fbreader.fbreader.options.SyncOptions;
import org.geometerplus.android.fbreader.libraryService.BookCollectionShadow;
import org.geometerplus.android.fbreader.network.auth.ServiceNetworkContext;
@ -41,6 +44,7 @@ public class SynchroniserService extends Service implements IBookCollection.List
Uploaded(Book.SYNCHRONIZED_LABEL),
ToBeDeleted(Book.SYNC_DELETED_LABEL),
Failure(Book.SYNC_FAILURE_LABEL),
SyncronizationDisabled(null),
FailedPreviuousTime(null),
HashNotComputed(null);
@ -58,14 +62,31 @@ public class SynchroniserService extends Service implements IBookCollection.List
}
}
private final ZLNetworkContext myNetworkContext = new ServiceNetworkContext(this);
private final ConnectivityManager myConnectivityManager =
(ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
private final SyncOptions mySyncOptions = new SyncOptions();
private static final class SyncronizationDisabledException extends RuntimeException {
}
private final ZLNetworkContext myNetworkContext = new ServiceNetworkContext(this) {
@Override
protected void perform(ZLNetworkRequest request, int socketTimeout, int connectionTimeout) throws ZLNetworkException {
if (!canPerformRequest()) {
throw new SyncronizationDisabledException();
}
super.perform(request, socketTimeout, connectionTimeout);
}
};
private final BookCollectionShadow myCollection = new BookCollectionShadow();
private static volatile Thread ourSynchronizationThread;
private final List<Book> myQueue = Collections.synchronizedList(new LinkedList<Book>());
private final Set<Book> myProcessed = new HashSet<Book>();
private final Set<String> myActualHashesFromServer = new HashSet<String>();
private final Set<String> myDeletedHashesFromServer = new HashSet<String>();
private volatile boolean myHashTablesAreInitialized = false;
@Override
public IBinder onBind(Intent intent) {
@ -80,6 +101,54 @@ public class SynchroniserService extends Service implements IBookCollection.List
}
}
private synchronized void clearHashTables() {
myActualHashesFromServer.clear();
myDeletedHashesFromServer.clear();
myHashTablesAreInitialized = false;
}
private synchronized void initHashTables() {
if (myHashTablesAreInitialized) {
return;
}
try {
myNetworkContext.perform(new PostRequest("all.hashes", null) {
@Override
public void processResponse(Object response) {
final Map<String,List<String>> map = (Map<String,List<String>>)response;
myActualHashesFromServer.addAll(map.get("actual"));
myDeletedHashesFromServer.addAll(map.get("deleted"));
myHashTablesAreInitialized = true;
}
});
System.err.println(String.format("RECEIVED: %s/%s HASHES", myActualHashesFromServer.size(), myDeletedHashesFromServer.size()));
} catch (SyncronizationDisabledException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
}
}
private boolean canPerformRequest() {
if (!mySyncOptions.Enabled.getValue()) {
return false;
}
switch (mySyncOptions.UploadAllBooks.getValue()) {
default:
case never:
return false;
case always:
return myConnectivityManager.getActiveNetworkInfo().isConnected();
case viaWifi:
{
final NetworkInfo info = myConnectivityManager.getActiveNetworkInfo();
return info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI;
}
}
}
@Override
public synchronized void run() {
myCollection.addListener(this);
@ -90,23 +159,7 @@ public class SynchroniserService extends Service implements IBookCollection.List
int count = 0;
final Map<SyncStatus,Integer> statusCounts = new HashMap<SyncStatus,Integer>();
try {
myActualHashesFromServer.clear();
myDeletedHashesFromServer.clear();
try {
myNetworkContext.perform(new PostRequest("all.hashes", null) {
@Override
public void processResponse(Object response) {
final Map<String,List<String>> map = (Map<String,List<String>>)response;
myActualHashesFromServer.addAll(map.get("actual"));
myDeletedHashesFromServer.addAll(map.get("deleted"));
}
});
System.err.println(String.format("RECEIVED: %s/%s HASHES", myActualHashesFromServer.size(), myDeletedHashesFromServer.size()));
} catch (Exception e) {
e.printStackTrace();
System.err.println("DO NOT SYNCHRONIZE: ALL HASHES REQUEST FAILED");
return;
}
clearHashTables();
for (BookQuery q = new BookQuery(new Filter.Empty(), 20);; q = q.next()) {
final List<Book> books = myCollection.books(q);
if (books.isEmpty()) {
@ -210,6 +263,14 @@ public class SynchroniserService extends Service implements IBookCollection.List
}
private SyncStatus uploadBookToServer(Book book) {
try {
return uploadBookToServerInternal(book);
} catch (SyncronizationDisabledException e) {
return SyncStatus.SyncronizationDisabled;
}
}
private SyncStatus uploadBookToServerInternal(Book book) {
final ZLPhysicalFile file = book.File.getPhysicalFile();
final String hash = myCollection.getHash(book);
final boolean force = book.labels().contains(Book.SYNC_TOSYNC_LABEL);
@ -222,6 +283,9 @@ public class SynchroniserService extends Service implements IBookCollection.List
} else if (!force && book.labels().contains(Book.SYNC_FAILURE_LABEL)) {
return SyncStatus.FailedPreviuousTime;
}
initHashTables();
final Map<String,Object> result = new HashMap<String,Object>();
final PostRequest verificationRequest =
new PostRequest("book.status.by.hash", Collections.singletonMap("sha1", hash)) {

View file

@ -59,7 +59,15 @@ public abstract class ZLNetworkContext implements ZLNetworkManager.BearerAuthent
getAccountOption(host, realm).setValue(accountName != null ? accountName : "");
}
public boolean performQuietly(ZLNetworkRequest request) {
protected void perform(ZLNetworkRequest request, int socketTimeout, int connectionTimeout) throws ZLNetworkException {
myManager.perform(request, this, socketTimeout, connectionTimeout);
}
public final void perform(ZLNetworkRequest request) throws ZLNetworkException {
perform(request, 30000, 15000);
}
public final boolean performQuietly(ZLNetworkRequest request) {
try {
perform(request);
return true;
@ -68,11 +76,7 @@ public abstract class ZLNetworkContext implements ZLNetworkManager.BearerAuthent
}
}
public void perform(ZLNetworkRequest request) throws ZLNetworkException {
myManager.perform(request, this, 30000, 15000);
}
public void perform(List<? extends ZLNetworkRequest> requests) throws ZLNetworkException {
public final void perform(List<? extends ZLNetworkRequest> requests) throws ZLNetworkException {
if (requests.size() == 0) {
return;
}
@ -107,7 +111,7 @@ public abstract class ZLNetworkContext implements ZLNetworkManager.BearerAuthent
}
private final void downloadToFile(String url, final File outFile, final int bufferSize) throws ZLNetworkException {
myManager.perform(new ZLNetworkRequest.Get(url) {
perform(new ZLNetworkRequest.Get(url) {
public void handleStream(InputStream inputStream, int length) throws IOException, ZLNetworkException {
OutputStream outStream = new FileOutputStream(outFile);
try {
@ -123,7 +127,7 @@ public abstract class ZLNetworkContext implements ZLNetworkManager.BearerAuthent
outStream.close();
}
}
}, this, 0, 0);
}, 0, 0);
}
private ZLStringOption getAccountOption(String host, String realm) {