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

Commit 89f0e803 authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Fix ImsService Callback synchronization issues

ImsService was holding a lock when calling back
ImsService status. This could lead to a situation
where a call into ImsServiceController from the
platform and a call into the ImsServiceController
from the ImsService could cause a deadlock.

Bug: 74119196
Test: Manual

Change-Id: I9c58d7d5e2a8021cc1bfefc4ea08cb29ce8591e5
parent eebc0c0b
Loading
Loading
Loading
Loading
+33 −40
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import com.android.internal.telephony.ExponentialBackoff;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Manages the Binding lifecycle of one ImsService as well as the relevant ImsFeatures that the
@@ -201,7 +202,7 @@ public class ImsServiceController {
    private IBinder mImsServiceControllerBinder;
    private ImsServiceConnection mImsServiceConnection;
    private ImsDeathRecipient mImsDeathRecipient;
    private Set<IImsServiceFeatureCallback> mImsStatusCallbacks = new HashSet<>();
    private Set<IImsServiceFeatureCallback> mImsStatusCallbacks = ConcurrentHashMap.newKeySet();
    // Only added or removed, never accessed on purpose.
    private Set<ImsFeatureStatusCallback> mFeatureStatusCallbacks = new HashSet<>();

@@ -456,8 +457,8 @@ public class ImsServiceController {
     * Add a callback to ImsManager that signals a new feature that the ImsServiceProxy can handle.
     */
    public void addImsServiceFeatureCallback(IImsServiceFeatureCallback callback) {
        synchronized (mLock) {
        mImsStatusCallbacks.add(callback);
        synchronized (mLock) {
            if (mImsFeatures == null || mImsFeatures.isEmpty()) {
                return;
            }
@@ -587,10 +588,8 @@ public class ImsServiceController {

    @VisibleForTesting
    public void removeImsServiceFeatureCallbacks() {
        synchronized (mLock) {
            mImsStatusCallbacks.clear();
    }
    }

    // Only add a new rebind if there are no pending rebinds waiting.
    private void startDelayedRebindToService() {
@@ -613,7 +612,6 @@ public class ImsServiceController {
    }

    private void sendImsFeatureCreatedCallback(int slot, int feature) {
        synchronized (mLock) {
        for (Iterator<IImsServiceFeatureCallback> i = mImsStatusCallbacks.iterator();
                i.hasNext(); ) {
            IImsServiceFeatureCallback callbacks = i.next();
@@ -627,10 +625,8 @@ public class ImsServiceController {
            }
        }
    }
    }

    private void sendImsFeatureRemovedCallback(int slot, int feature) {
        synchronized (mLock) {
        for (Iterator<IImsServiceFeatureCallback> i = mImsStatusCallbacks.iterator();
                i.hasNext(); ) {
            IImsServiceFeatureCallback callbacks = i.next();
@@ -644,10 +640,8 @@ public class ImsServiceController {
            }
        }
    }
    }

    private void sendImsFeatureStatusChanged(int slot, int feature, int status) {
        synchronized (mLock) {
        for (Iterator<IImsServiceFeatureCallback> i = mImsStatusCallbacks.iterator();
                i.hasNext(); ) {
            IImsServiceFeatureCallback callbacks = i.next();
@@ -661,7 +655,6 @@ public class ImsServiceController {
            }
        }
    }
    }

    // This method should only be called when synchronized on mLock
    private void addImsServiceFeature(ImsFeatureConfiguration.FeatureSlotPair featurePair)