Skip to content

Commit

Permalink
Merge branch 'hotfix/5.2.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
ccomeaux committed Apr 27, 2016
2 parents 2d0f339 + f02dd4e commit 8135e47
Show file tree
Hide file tree
Showing 16 changed files with 140 additions and 70 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Release Notes
=============

Version 5.2.6
-------------
* Improvements to syncing logic (it won't completely fix the syncing problems, but it's a start!
* Bug fixes

Version 5.2.5
-------------
* Really fix the disappearing collection
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ android {
applicationId "com.boardgamegeek"
minSdkVersion 9
targetSdkVersion 23
versionCode 57
versionName "5.2.5"
versionCode 58
versionName "5.2.6"
buildConfigField "String", "BRANCH", "\"" + getBranchName() + "\""
}
buildTypes {
Expand Down
46 changes: 32 additions & 14 deletions app/src/main/java/com/boardgamegeek/io/Adapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@

import com.boardgamegeek.BuildConfig;
import com.boardgamegeek.auth.Authenticator;
import com.boardgamegeek.util.HelpUtils;
import com.squareup.okhttp.OkHttpClient;

import java.io.IOException;

import retrofit.RequestInterceptor;
import retrofit.RequestInterceptor.RequestFacade;
import retrofit.RestAdapter;
import retrofit.RestAdapter.Builder;
import retrofit.RestAdapter.LogLevel;
Expand Down Expand Up @@ -49,8 +51,16 @@ private static Builder createBuilderWithoutConverter() {
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new RetryInterceptor());

RequestInterceptor requestInterceptor = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
addUserAgent(request, null);
}
};

Builder builder = new RestAdapter.Builder()
.setEndpoint("https://www.boardgamegeek.com/")
.setRequestInterceptor(requestInterceptor)
.setClient(new OkClient(client));
if (DEBUG) {
builder.setLog(new AndroidLog("BGG-retrofit")).setLogLevel(LogLevel.FULL);
Expand All @@ -59,30 +69,38 @@ private static Builder createBuilderWithoutConverter() {
return builder;
}

private static Builder addAuth(Context context, Builder builder) {
private static Builder addAuth(final Context context, Builder builder) {
RequestInterceptor requestInterceptor = null;

AccountManager accountManager = AccountManager.get(context);
final Account account = Authenticator.getAccount(accountManager);
if (account != null) {
try {
final String authToken = accountManager.blockingGetAuthToken(account, Authenticator.AUTH_TOKEN_TYPE, true);
requestInterceptor = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
if (!TextUtils.isEmpty(account.name) && !TextUtils.isEmpty(authToken)) {
request.addHeader("Cookie", "bggusername=" + account.name + "; bggpassword=" + authToken);
}
try {
final String authToken = accountManager.blockingGetAuthToken(account, Authenticator.AUTH_TOKEN_TYPE, true);
requestInterceptor = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
// this replaces the previous interceptor, so we must re-add the user-agent
addUserAgent(request, context);
if (account != null && !TextUtils.isEmpty(account.name) && !TextUtils.isEmpty(authToken)) {
request.addHeader("Cookie", "bggusername=" + account.name + "; bggpassword=" + authToken);
}
};
} catch (OperationCanceledException | AuthenticatorException | IOException e) {
// TODO handle this somehow; maybe just return create()
}
}
};
} catch (OperationCanceledException | AuthenticatorException | IOException e) {
// TODO handle this somehow; maybe just return create()
}

if (requestInterceptor != null) {
builder.setRequestInterceptor(requestInterceptor);
}
return builder;
}

private static void addUserAgent(RequestFacade request, Context context) {
String userAgent = "BGG4Android";
if (context != null) {
userAgent += "/" + HelpUtils.getVersionName(context);
}
request.addHeader("User-Agent", userAgent);
}
}
21 changes: 14 additions & 7 deletions app/src/main/java/com/boardgamegeek/io/RetryInterceptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,18 @@ public class RetryInterceptor implements Interceptor {
private static final int BACKOFF_TYPE_EXPONENTIAL = 0;
private static final int BACKOFF_TYPE_GEOMETRIC = 1;

private static final long MIN_WAIT_TIME = 100L;
private static final long MIN_WAIT_TIME = 1000L;
private static final long MAX_WAIT_TIME = 60000L;
private static final int MAX_RETRIES = 10;
private static final int MAX_RETRIES = 4;

@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
int numberOfRetries = 0;
int responseCode;
do {
Response response = chain.proceed(originalRequest);
final int responseCode = response.code();
responseCode = response.code();
if (responseCode == COLLECTION_REQUEST_PROCESSING ||
responseCode == API_RATE_EXCEEDED) {
Timber.i("Retry-able response code %s", responseCode);
Expand All @@ -36,8 +37,8 @@ public Response intercept(Chain chain) throws IOException {
} else {
return response;
}
} while (numberOfRetries < getMaxRetries());
Timber.w("Exceeded maximum number of retries of %,d.", getMaxRetries());
} while (numberOfRetries < getMaxRetries(responseCode));
Timber.w("Exceeded maximum number of retries of %,d.", getMaxRetries(responseCode));
return chain.proceed(originalRequest);
}

Expand All @@ -47,7 +48,7 @@ private void wait(int numberOfRetries) {
try {
Thread.sleep(waitTime);
} catch (InterruptedException e) {
Timber.e(e, "Interrupted while sleeping during retry.");
Timber.w(e, "Interrupted while sleeping during retry.");
}
}

Expand Down Expand Up @@ -77,7 +78,13 @@ protected long getMaxWaitTime() {
return MAX_WAIT_TIME;
}

protected int getMaxRetries() {
protected int getMaxRetries(int responseCode) {
if (responseCode == COLLECTION_REQUEST_PROCESSING) {
return 8;
}
if (responseCode == API_RATE_EXCEEDED) {
return 2;
}
return MAX_RETRIES;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,23 @@ public int save(List<User> buddies) {
StringBuilder debugMessage = new StringBuilder();
if (buddies != null) {
for (User buddy : buddies) {
Uri uri = Buddies.buildBuddyUri(buddy.name);
ContentValues values = new ContentValues();
values.put(Buddies.UPDATED, updateTime);
int oldSyncHashCode = ResolverUtils.queryInt(resolver, uri, Buddies.SYNC_HASH_CODE);
int newSyncHashCode = generateSyncHashCode(buddy);
if (oldSyncHashCode != newSyncHashCode) {
values.put(Buddies.BUDDY_ID, buddy.getId());
values.put(Buddies.BUDDY_NAME, buddy.name);
values.put(Buddies.BUDDY_FIRSTNAME, buddy.firstName);
values.put(Buddies.BUDDY_LASTNAME, buddy.lastName);
values.put(Buddies.AVATAR_URL, buddy.avatarUrl);
values.put(Buddies.SYNC_HASH_CODE, newSyncHashCode);
if (!TextUtils.isEmpty(buddy.name)) {
Uri uri = Buddies.buildBuddyUri(buddy.name);
ContentValues values = new ContentValues();
values.put(Buddies.UPDATED, updateTime);
int oldSyncHashCode = ResolverUtils.queryInt(resolver, uri, Buddies.SYNC_HASH_CODE);
int newSyncHashCode = generateSyncHashCode(buddy);
if (oldSyncHashCode != newSyncHashCode) {
values.put(Buddies.BUDDY_ID, buddy.getId());
values.put(Buddies.BUDDY_NAME, buddy.name);
values.put(Buddies.BUDDY_FIRSTNAME, buddy.firstName);
values.put(Buddies.BUDDY_LASTNAME, buddy.lastName);
values.put(Buddies.AVATAR_URL, buddy.avatarUrl);
values.put(Buddies.SYNC_HASH_CODE, newSyncHashCode);
}
debugMessage.append("Saving ").append(uri).append("; ");
addToBatch(resolver, values, batch, uri, debugMessage);
}
debugMessage.append("Updating ").append(uri).append("; ");
addToBatch(resolver, values, batch, uri, debugMessage);
}
}
ContentProviderResult[] result = ResolverUtils.applyBatch(context, batch, debugMessage.toString());
Expand Down
18 changes: 14 additions & 4 deletions app/src/main/java/com/boardgamegeek/service/SyncAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@
import com.boardgamegeek.util.NotificationUtils;
import com.boardgamegeek.util.PreferencesUtils;

import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;

import de.greenrobot.event.EventBus;
import hugo.weaving.DebugLog;
import retrofit.RetrofitError;
import timber.log.Timber;

public class SyncAdapter extends AbstractThreadedSyncAdapter {
Expand Down Expand Up @@ -72,7 +74,7 @@ public void onPerformSync(@NonNull Account account, @NonNull Bundle extras, Stri
ContentResolver.setIsSyncable(account, authority, 1);
ContentResolver.setSyncAutomatically(account, authority, true);
Bundle b = new Bundle();
ContentResolver.addPeriodicSync(account, authority, b, 8 * 60 * 60); // 8 hours
ContentResolver.addPeriodicSync(account, authority, b, 24 * 60 * 60); // 24 hours
}

if (!shouldContinueSync(uploadOnly)) {
Expand All @@ -97,10 +99,18 @@ public void onPerformSync(@NonNull Account account, @NonNull Bundle extras, Stri
currentTask.execute(account, syncResult);
EventBus.getDefault().post(new SyncCompleteEvent());
EventBus.getDefault().removeStickyEvent(SyncEvent.class);
} catch (RetrofitError re) {
Timber.e(re, "Syncing " + currentTask);
syncResult.stats.numIoExceptions += 10;
showError(currentTask, re);
break;
} catch (Exception e) {
Timber.e(e, "Syncing " + currentTask);
syncResult.stats.numIoExceptions++;
syncResult.stats.numIoExceptions += 10;
showError(currentTask, e);
if (e.getCause() instanceof SocketTimeoutException) {
break;
}
}
}
toggleReceiver(false);
Expand Down Expand Up @@ -192,8 +202,8 @@ private void toggleReceiver(boolean enable) {
ComponentName receiver = new ComponentName(context, CancelReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver, enable ?
PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}

Expand Down
35 changes: 17 additions & 18 deletions app/src/main/java/com/boardgamegeek/service/SyncGames.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@
import com.boardgamegeek.model.persister.GamePersister;
import com.boardgamegeek.util.StringUtils;

import java.net.SocketTimeoutException;
import java.util.List;

import timber.log.Timber;

public abstract class SyncGames extends SyncTask {
private static final int GAMES_PER_FETCH = 16;
private static final int GAMES_PER_FETCH = 10;
private int fetchSize;

public SyncGames(Context context, BggService service) {
Expand Down Expand Up @@ -72,24 +71,24 @@ protected int getMaxFetchCount() {
}

private ThingResponse getThingResponse(BggService service, List<String> gameIds) {
while (true) {
try {
// while (true) {
// try {
String ids = TextUtils.join(",", gameIds);
return new ThingRequest(service, ids).execute();
} catch (Exception e) {
if (e.getCause() instanceof SocketTimeoutException) {
if (fetchSize == 1) {
Timber.i("...timeout with only 1 game; aborting.");
break;
}
fetchSize = fetchSize / 2;
Timber.i("...timeout - reducing games per fetch to " + fetchSize);
} else {
throw e;
}
}
}
return new ThingResponse();
// } catch (Exception e) {
// if (e.getCause() instanceof SocketTimeoutException) {
// if (fetchSize == 1) {
// Timber.i("...timeout with only 1 game; aborting.");
// break;
// }
// fetchSize = fetchSize / 2;
// Timber.i("...timeout - reducing games per fetch to " + fetchSize);
// } else {
// throw e;
// }
// }
// }
// return new ThingResponse();
}

@NonNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ protected List<String> getGameIds(int gamesPerFetch) {

@Override
protected int getMaxFetchCount() {
return 100;
return 20;
}

@Override
Expand Down
13 changes: 8 additions & 5 deletions app/src/main/java/com/boardgamegeek/sorter/PlaysDateSorter.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package com.boardgamegeek.sorter;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;

import android.content.Context;
import android.database.Cursor;
import android.support.annotation.NonNull;
Expand All @@ -13,6 +8,13 @@
import com.boardgamegeek.R;
import com.boardgamegeek.provider.BggContract.Plays;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;

import timber.log.Timber;

public class PlaysDateSorter extends PlaysSorter {
private final SimpleDateFormat formatter = new SimpleDateFormat("MMMM", Locale.getDefault());
private final GregorianCalendar calendar = new GregorianCalendar();
Expand Down Expand Up @@ -48,6 +50,7 @@ public String getHeaderText(@NonNull Cursor cursor) {

private String getYearAndMonth(@NonNull Cursor cursor) {
String date = getString(cursor, Plays.DATE);
Timber.w("Attempting to parse date %s", date);
if (TextUtils.isEmpty(date)) {
return "1969-01";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,10 @@ void onFabClick(View view) {
fragment.setOnColorSelectedListener(new ColorPickerDialogFragment.OnColorSelectedListener() {
@Override
public void onColorSelected(String description, int color) {
colors.add(new BuddyColor(description, colors.size() + 1));
bindUi();
if (colors != null) {
colors.add(new BuddyColor(description, colors.size() + 1));
bindUi();
}
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,10 @@ public void onDestroyActionMode(ActionMode mode) {
@Override
@DebugLog
public void onItemCheckedStateChanged(@NonNull ActionMode mode, int position, long id, boolean checked) {
if (!isAdded()) {
return;
}

if (checked) {
selectedPositions.add(position);
} else {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/boardgamegeek/ui/GameFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
LoaderManager lm = getLoaderManager();
lm.restartLoader(GameQuery._TOKEN, null, this);
lm.restartLoader(RankQuery._TOKEN, null, this);
lm.restartLoader(CollectionQuery._TOKEN, null, this);
if (shouldShowPlays()) {
lm.restartLoader(PlaysQuery._TOKEN, null, this);
}
Expand Down Expand Up @@ -315,6 +314,7 @@ public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
case GameQuery._TOKEN:
onGameQueryComplete(cursor);
LoaderManager lm = getLoaderManager();
lm.restartLoader(CollectionQuery._TOKEN, null, this);
lm.restartLoader(DesignerQuery._TOKEN, null, this);
lm.restartLoader(ArtistQuery._TOKEN, null, this);
lm.restartLoader(PublisherQuery._TOKEN, null, this);
Expand Down
Loading

0 comments on commit 8135e47

Please sign in to comment.