forcedotcom / forcedotcom/SalesforceMobileSDK-Android
SecurityException on addAccountExplicitly after app update — AuthenticatorService not yet registered
- Dominant language
- Kotlin
- Stars
- 361
- Forks
- 393
- Avg merge
- 17h 17m
- Merged PRs (30d)
- 36
Description
## Description
After an app update, `UserAccountManager.createAccount()` crashes with a `SecurityException` on `accountManager.addAccountExplicitly()` because the Android OS has not yet re-registered the app's `AuthenticatorService`.
This is a race condition between the app launching after an update and the OS recognizing the updated authenticator. It occurs sporadically in production — we see it in Crashlytics on multiple devices.
## Stack Trace
```
java.lang.SecurityException: caller uid XXXXX is different than the authenticator's uid
at android.os.Parcel.createExceptionOrNull(Parcel.java:3057)
at android.os.Parcel.createException(Parcel.java:3041)
at android.accounts.AccountManager.addAccountExplicitly(AccountManager.java:892)
at com.salesforce.androidsdk.accounts.UserAccountManager.createAccount(UserAccountManager.java:446)
```
## Root Cause
In `UserAccountManager.createAccount()`, `accountManager.addAccountExplicitly()` is called once with no error handling for `SecurityException`. After an app update, Android may not have re-registered the authenticator yet, causing a UID mismatch.
## Expected Behavior
`addAccountExplicitly()` should retry with a short backoff to allow the OS to register the authenticator:
```java
SecurityException lastException = null;
int maxRetries = 3;
for (int attempt = 0; attempt < maxRetries; attempt++) {
try {
success = accountManager.addAccountExplicitly(acc, password, new Bundle());
break;
} catch (SecurityException e) {
lastException = e;
if (attempt < maxRetries - 1 && Looper.myLooper() != Looper.getMainLooper()) {
Thread.sleep(500);
}
}
}
if (lastException != null) throw lastException;
```
## Affected Versions
- Confirmed on **13.2.0** and **13.2.1**
- Likely affects all versions using Android AccountManager
## Environment
- Android SDK 13.2.0/13.2.1
- Various Android versions (seen on Android 13, 14, 15)
- Occurs after app updates via Play Store or side-loading
Contributor guide
Research direction
Start in UserAccountManager.java at createAccount(), around the accountManager.addAccountExplicitly() call shown in the stack trace, and inspect how authenticator registration is handled after an update. Reproduce or exercise the post-update account-creation path, then verify that a temporary SecurityException no longer causes an unrecovered crash and that the retry behavior is bounded.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, java
- Domain
- authentication, mobile-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 65/100