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

Commit 8047e4e2 authored by Sebastian Achim's avatar Sebastian Achim Committed by Steve Statia
Browse files

Move getActiveSubscriptionInfo to solve deadlock

Solve deadlock between system_server and com.android.phone.

A system_server thread hold a TelephonyRegistry mRecords object
while doing a binder transaction with com.android.phone for
getActiveSubscriptionInfo().

When all binder threads in com.android.phone are busy it will take
time until this is scheduled. There are cases when com.android.phone
is doing a binder transaction with system_server to acquire the same
mRecords object, resulting in deadlock.

Align with other getPhoneIdFromSubId() calls and move the call to
SubscriptionManager getActiveSubscriptionInfo outside of synchronized
block to prevent this from happening.

Test: atest TelephonyRegistryTest
Bug: 315932019
Change-Id: Ifadf9d33ef2072352b0bd1a805da9a5f0329114e
parent 0553b14a
Loading
Loading
Loading
Loading
+37 −10
Original line number Diff line number Diff line
@@ -1126,6 +1126,21 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
            return;
        }

        int phoneId = -1;
        int subscriptionId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
        if(Flags.preventSystemServerAndPhoneDeadlock()) {
            // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
            // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
            if (!SubscriptionManager.isValidSubscriptionId(subId)) {
                if (DBG) {
                    log("invalid subscription id, use default id");
                }
            } else { //APP specify subID
                subscriptionId = subId;
            }
            phoneId = getPhoneIdFromSubId(subscriptionId);
        }

        synchronized (mRecords) {
            // register
            IBinder b = callback.asBinder();
@@ -1145,6 +1160,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
            r.renounceFineLocationAccess = renounceFineLocationAccess;
            r.callerUid = Binder.getCallingUid();
            r.callerPid = Binder.getCallingPid();

            if(!Flags.preventSystemServerAndPhoneDeadlock()) {
                // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
                // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
                if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -1156,6 +1173,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
                    r.subId = subId;
                }
                r.phoneId = getPhoneIdFromSubId(r.subId);
            } else {
                r.subId = subscriptionId;
                r.phoneId = phoneId;
            }
            r.eventList = events;

            if (DBG) {
@@ -1893,8 +1914,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
    }

    private void notifyCarrierNetworkChangeWithPermission(int subId, boolean active) {
        int phoneId = -1;
        if(Flags.preventSystemServerAndPhoneDeadlock()) {
            phoneId = getPhoneIdFromSubId(subId);
        }
        synchronized (mRecords) {
            int phoneId = getPhoneIdFromSubId(subId);
            if(!Flags.preventSystemServerAndPhoneDeadlock()) {
                phoneId = getPhoneIdFromSubId(subId);
            }
            mCarrierNetworkChangeState[phoneId] = active;

            if (VDBG) {