Merge "Serialize AM.getContentProvider() calls in client side" into pi-dev

This commit is contained in:
Makoto Onuki
2018-06-01 05:35:02 +00:00
committed by Android (Google) Code Review

View File

@@ -347,6 +347,13 @@ public final class ActivityThread extends ClientTransactionHandler {
final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
= new ArrayMap<ComponentName, ProviderClientRecord>();
// Mitigation for b/74523247: Used to serialize calls to AM.getContentProvider().
// Note we never removes items from this map but that's okay because there are only so many
// users and so many authorities.
// TODO Remove it once we move CPR.wait() from AMS to the client side.
@GuardedBy("mGetProviderLocks")
final ArrayMap<ProviderKey, Object> mGetProviderLocks = new ArrayMap<>();
final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
= new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
@@ -5959,8 +5966,10 @@ public final class ActivityThread extends ClientTransactionHandler {
// be re-entrant in the case where the provider is in the same process.
ContentProviderHolder holder = null;
try {
holder = ActivityManager.getService().getContentProvider(
getApplicationThread(), auth, userId, stable);
synchronized (getGetProviderLock(auth, userId)) {
holder = ActivityManager.getService().getContentProvider(
getApplicationThread(), auth, userId, stable);
}
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -5976,6 +5985,18 @@ public final class ActivityThread extends ClientTransactionHandler {
return holder.provider;
}
private Object getGetProviderLock(String auth, int userId) {
final ProviderKey key = new ProviderKey(auth, userId);
synchronized (mGetProviderLocks) {
Object lock = mGetProviderLocks.get(key);
if (lock == null) {
lock = key;
mGetProviderLocks.put(key, lock);
}
return lock;
}
}
private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
if (stable) {
prc.stableCount += 1;