Skip to content

Commit e63d0b5

Browse files
committed
auth: timeout refresh token to avoid ANR in authenticator
1 parent b7bae7d commit e63d0b5

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ lint-*ml
3333

3434
# Prevent exidental commits of build folders
3535
opencloudApp/release
36+
settings.local.json

opencloudApp/src/main/java/eu/opencloud/android/presentation/authentication/AccountAuthenticator.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949
import timber.log.Timber;
5050

5151
import java.io.File;
52+
import java.util.concurrent.ExecutorService;
53+
import java.util.concurrent.Executors;
54+
import java.util.concurrent.Future;
55+
import java.util.concurrent.TimeUnit;
56+
import java.util.concurrent.TimeoutException;
5257

5358
import static eu.opencloud.android.data.authentication.AuthenticationConstantsKt.KEY_CLIENT_REGISTRATION_CLIENT_EXPIRATION_DATE;
5459
import static eu.opencloud.android.data.authentication.AuthenticationConstantsKt.KEY_CLIENT_REGISTRATION_CLIENT_ID;
@@ -318,6 +323,30 @@ private String refreshToken(
318323
String authTokenType,
319324
AccountManager accountManager
320325
) {
326+
// Run refresh on a worker with a short timeout to avoid ANR in AccountAuthenticatorService.
327+
ExecutorService executor = Executors.newSingleThreadExecutor();
328+
Future<String> future = executor.submit(() ->
329+
refreshTokenInternal(account, authTokenType, accountManager)
330+
);
331+
try {
332+
return future.get(10, TimeUnit.SECONDS); // stay below 20s ANR window
333+
} catch (TimeoutException e) {
334+
Timber.w(e, "OAuth token refresh timed out, fallback to interactive login");
335+
future.cancel(true);
336+
return null;
337+
} catch (Exception e) {
338+
Timber.e(e, "OAuth token refresh failed");
339+
return null;
340+
} finally {
341+
executor.shutdownNow();
342+
}
343+
}
344+
345+
private String refreshTokenInternal(
346+
Account account,
347+
String authTokenType,
348+
AccountManager accountManager
349+
) {
321350

322351
// Prepare everything to perform the token request
323352
String refreshToken = accountManager.getUserData(account, KEY_OAUTH2_REFRESH_TOKEN);

0 commit comments

Comments
 (0)