Skip to content

Commit b7ce7f2

Browse files
committed
move ping to SyncService
1 parent 59bc4df commit b7ce7f2

5 files changed

Lines changed: 54 additions & 50 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package pl.selvin.android.listsyncsample.network;
2+
3+
import java.util.concurrent.TimeUnit;
4+
5+
import okhttp3.ConnectionPool;
6+
import okhttp3.OkHttpClient;
7+
import pl.selvin.android.listsyncsample.BuildConfig;
8+
9+
public class HttpClient {
10+
public static final OkHttpClient DEFAULT;
11+
12+
static {
13+
final int connectTimeout = 3;
14+
final int timeout = 15;
15+
final String USER_AGENT = String.format("%s(%s)(%s)(%s)", BuildConfig.APPLICATION_ID, BuildConfig.BUILD_TYPE, BuildConfig.FLAVOR, BuildConfig.VERSION_NAME);
16+
final OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(
17+
chain -> chain.proceed(chain.request().newBuilder().header("User-Agent", USER_AGENT).build()));
18+
DEFAULT = builder
19+
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
20+
.callTimeout(timeout, TimeUnit.MINUTES)
21+
.readTimeout(timeout, TimeUnit.MINUTES)
22+
.writeTimeout(timeout, TimeUnit.MINUTES)
23+
.connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES))
24+
.build();
25+
}
26+
}

demo/src/main/java/pl/selvin/android/listsyncsample/provider/RequestExecutor.java

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import java.io.InputStream;
1414
import java.util.concurrent.TimeUnit;
1515

16-
import okhttp3.CacheControl;
1716
import okhttp3.ConnectionPool;
1817
import okhttp3.MediaType;
1918
import okhttp3.OkHttpClient;
@@ -25,28 +24,12 @@
2524
import pl.selvin.android.listsyncsample.BuildConfig;
2625
import pl.selvin.android.listsyncsample.Constants;
2726
import pl.selvin.android.listsyncsample.authenticator.NetworkOperations;
27+
import pl.selvin.android.listsyncsample.network.HttpClient;
2828
import pl.selvin.android.syncframework.content.BaseContentProvider;
2929

3030
public class RequestExecutor implements pl.selvin.android.syncframework.content.RequestExecutor {
3131
public final static String ACCOUNT_PARAMETER = "ACCOUNT_PARAMETER";
3232

33-
private final OkHttpClient client;
34-
35-
public RequestExecutor() {
36-
final int connectTimeout = 3;
37-
final int timeout = 15;
38-
final String USER_AGENT = String.format("%s(%s)(%s)(%s)", BuildConfig.APPLICATION_ID, BuildConfig.BUILD_TYPE, BuildConfig.FLAVOR, BuildConfig.VERSION_NAME);
39-
final OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(
40-
chain -> chain.proceed(chain.request().newBuilder().header("User-Agent", USER_AGENT).build()));
41-
client = builder
42-
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
43-
.callTimeout(timeout, TimeUnit.MINUTES)
44-
.readTimeout(timeout, TimeUnit.MINUTES)
45-
.writeTimeout(timeout, TimeUnit.MINUTES)
46-
.connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES))
47-
.build();
48-
}
49-
5033
@Override
5134
@NonNull
5235
public Result execute(@NonNull Context context, @Nullable final BaseContentProvider.ISyncContentProducer syncContentProducer, @NonNull Bundle parameters) throws IOException, AuthenticatorException {
@@ -75,7 +58,7 @@ public void writeTo(@NonNull BufferedSink sink) throws IOException {
7558
}
7659
});
7760
}
78-
final Response response = client.newCall(requestBuilder.build()).execute();
61+
final Response response = HttpClient.DEFAULT.newCall(requestBuilder.build()).execute();
7962
final ResponseBody body = response.body();
8063
if (body != null) {
8164
final String error;
@@ -90,17 +73,6 @@ public void writeTo(@NonNull BufferedSink sink) throws IOException {
9073
throw new RuntimeException("Response body is null");
9174
}
9275

93-
@Override
94-
public void doPing() {
95-
try {
96-
final Request.Builder requestBuilder = new Request.Builder().url(Constants.SERVICE_URI + "DefaultScopeSyncService.svc/$syncscopes")
97-
.method("HEAD", null).cacheControl(new CacheControl.Builder().noCache().noStore().build());
98-
final Response response = client.newCall(requestBuilder.build()).execute();
99-
response.close();
100-
} catch (Exception ignore) {
101-
}
102-
}
103-
10476
private static class OkHttpResult extends Result {
10577
private Response response;
10678

demo/src/main/java/pl/selvin/android/listsyncsample/syncadapter/SyncService.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,17 @@
2828
import androidx.annotation.NonNull;
2929
import androidx.annotation.Nullable;
3030

31+
import java.util.concurrent.Executors;
32+
import java.util.concurrent.ScheduledExecutorService;
33+
import java.util.concurrent.ScheduledFuture;
34+
import java.util.concurrent.TimeUnit;
35+
36+
import okhttp3.CacheControl;
37+
import okhttp3.Request;
38+
import okhttp3.Response;
3139
import pl.selvin.android.listsyncsample.Constants;
3240
import pl.selvin.android.listsyncsample.authenticator.NetworkOperations;
41+
import pl.selvin.android.listsyncsample.network.HttpClient;
3342
import pl.selvin.android.listsyncsample.provider.Database;
3443
import pl.selvin.android.listsyncsample.provider.ListProvider;
3544
import pl.selvin.android.listsyncsample.provider.RequestExecutor;
@@ -41,12 +50,13 @@ public class SyncService extends Service {
4150
public static final int SYNC_PENDING = 2;
4251

4352
private static final Object sSyncAdapterLock = new Object();
53+
private static final long PING_DELAY_SECONDS = 60;
4454

4555
private final static String TAG = "SyncService";
4656
private static SyncAdapter sSyncAdapter;
4757
private final RemoteCallbackList<ISyncStatusObserver> mObservers = new RemoteCallbackList<>();
48-
private int mLastStatus = SYNC_IDLE;
4958

59+
private int mLastStatus = SYNC_IDLE;
5060
private final ISyncService.Stub mBinder = new ISyncService.Stub() {
5161
public void addSyncStatusObserver(ISyncStatusObserver cb) {
5262
if (cb != null) {
@@ -146,11 +156,13 @@ public void onDestroy() {
146156

147157
static class SyncAdapter extends AbstractThreadedSyncAdapter {
148158

159+
private final ScheduledExecutorService pingExecutor;
149160
private SyncService mService;
150161

151162
SyncAdapter(SyncService service) {
152163
super(service.getApplicationContext(), true);
153164
mService = service;
165+
pingExecutor = Executors.newScheduledThreadPool(1);
154166
}
155167

156168
void setService(SyncService service) {
@@ -159,6 +171,8 @@ void setService(SyncService service) {
159171

160172
@Override
161173
synchronized public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
174+
final ScheduledFuture<?> scheduledFuture =
175+
pingExecutor.scheduleWithFixedDelay(this::doPing, PING_DELAY_SECONDS, PING_DELAY_SECONDS, TimeUnit.SECONDS);
162176
mService.mLastStatus = SYNC_ACTIVE;
163177
mService.fireStatusChanged();
164178
extras.putParcelable(RequestExecutor.ACCOUNT_PARAMETER, account);
@@ -191,5 +205,15 @@ synchronized public void onPerformSync(Account account, Bundle extras, String au
191205
mService.mLastStatus = SYNC_IDLE;
192206
mService.fireStatusChanged();
193207
}
208+
209+
private void doPing() {
210+
try {
211+
final Request.Builder requestBuilder = new Request.Builder().url(Constants.SERVICE_URI + "DefaultScopeSyncService.svc/$syncscopes")
212+
.method("HEAD", null).cacheControl(new CacheControl.Builder().noCache().noStore().build());
213+
final Response response = HttpClient.DEFAULT.newCall(requestBuilder.build()).execute();
214+
response.close();
215+
} catch (Exception ignore) {
216+
}
217+
}
194218
}
195219
}

sync-framework/src/main/java/pl/selvin/android/syncframework/content/BaseContentProvider.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@
3838
import java.util.Calendar;
3939
import java.util.HashMap;
4040
import java.util.Objects;
41-
import java.util.concurrent.Executors;
42-
import java.util.concurrent.ScheduledExecutorService;
43-
import java.util.concurrent.ScheduledFuture;
44-
import java.util.concurrent.TimeUnit;
4541

4642
import pl.selvin.android.autocontentprovider.content.AutoContentProvider;
4743
import pl.selvin.android.autocontentprovider.db.TableInfo;
@@ -53,15 +49,13 @@ public abstract class BaseContentProvider extends AutoContentProvider {
5349
public final static String DATABASE_OPERATION_TYPE_CREATE = "DATABASE_OPERATION_TYPE_CREATE";
5450
public final static String ACTION_SYNC_FRAMEWORK_DATABASE = "ACTION_SYNC_FRAMEWORK_DATABASE";
5551
private final static String DATABASE_OPERATION_TYPE = "DATABASE_OPERATION_TYPE";
56-
private final static long PING_DELAY_SECONDS = 60;
5752
protected final RequestExecutor executor;
5853
private final SyncContentHelper syncContentHelper;
59-
private final ScheduledExecutorService pingExecutor;
54+
6055

6156
public BaseContentProvider(SyncContentHelper contentHelper, Logger logger, SupportSQLiteOpenHelperFactoryProvider supportSQLiteOpenHelperFactoryProvider, RequestExecutor executor) {
6257
super(contentHelper, logger, supportSQLiteOpenHelperFactoryProvider);
6358
syncContentHelper = contentHelper;
64-
pingExecutor = Executors.newScheduledThreadPool(1);
6559
this.executor = executor;
6660
}
6761

@@ -100,7 +94,6 @@ public Bundle call(@NonNull String method, String arg, Bundle extras) {
10094

10195
@SuppressLint("DefaultLocale")
10296
public Bundle sync(Bundle parameters) {
103-
//Account account, String service, String scope, String params, Stats stats) {
10497
final String scope = parameters.getString(RequestExecutor.SCOPE_PARAMETER);
10598
final SyncResult syncResult = Objects.requireNonNull(parameters.getParcelable(RequestExecutor.SYNC_RESULT_PARAMETER));
10699
final long start = System.currentTimeMillis();
@@ -109,8 +102,6 @@ public Bundle sync(Bundle parameters) {
109102
final ArrayList<SyncTableInfo> notifyTableInfo = new ArrayList<>();
110103
final JsonFactory jsonFactory = new JsonFactory();
111104
JsonToken current;
112-
final ScheduledFuture<?> scheduledFuture =
113-
pingExecutor.scheduleWithFixedDelay(executor::doPing, PING_DELAY_SECONDS, PING_DELAY_SECONDS, TimeUnit.SECONDS);
114105
String serverBlob = null;
115106
final Cursor cur = db.query(
116107
SupportSQLiteQueryBuilder.builder(BlobsTable.NAME).columns(new String[]{BlobsTable.C_VALUE})
@@ -376,7 +367,6 @@ public Bundle sync(Bundle parameters) {
376367
db.insert(BlobsTable.NAME, SQLiteDatabase.CONFLICT_REPLACE, cv);
377368
}
378369
logger.LogTimeD(clazz, "*Sync* time", start);
379-
scheduledFuture.cancel(true);
380370
return parameters;
381371
}
382372

sync-framework/src/main/java/pl/selvin/android/syncframework/content/RequestExecutor.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,6 @@ public interface RequestExecutor {
3838
@NonNull
3939
Result execute(@NonNull Context context, @Nullable BaseContentProvider.ISyncContentProducer syncContentProducer, @NonNull Bundle parameters) throws IOException, AuthenticatorException;
4040

41-
/*
42-
If execution of synchronisation is longer than some 5 min(I believe)
43-
and there is no IO involved android OS kills sync process.
44-
To avoid you need to provide implementation which will called every 1 minute
45-
which will do some "internet" operation fx do HEAD request to your server
46-
*/
47-
void doPing();
48-
4941
@Retention(RetentionPolicy.SOURCE)
5042
@StringDef({UPLOAD, DOWNLOAD})
5143
@interface RequestType {

0 commit comments

Comments
 (0)