Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 137f9f65 authored by Makoto Onuki's avatar Makoto Onuki Committed by android-build-merger
Browse files

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

am: 079f6d7f

Change-Id: I299267e20b78810002bab56488b9436456936d11
parents 0371d710 079f6d7f
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -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 {
            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;