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

Commit 9981a70d authored by Jack Yu's avatar Jack Yu
Browse files

Fixed a race when slot-to-sub mapping table is rebuilding

When updateSubscriptionInfoByIccId is called, we always clear
the slot-to-sub id map first and then rebuild it. If other threads
access this map while the rebuilding is ongoing, subscription
controller returns an empty map that leads other threads think we
don't have any valid subscription at that moment. This indeed caused
some issues such like no data connection or device issued unexpected
LTE detach request to the mobile network.

Adding a lock to protect the entire rebuilding process and the map
might be an option but actually the Telephony provider, which
also has its own lock, has dependency on this map. The reverse lock
acuisition orders can cause deadlock, which eventually leads to an
ANR.

A workaround here is that we only clear the map when one/some SIMs
are gone.

A more comprehensive refactoring for building this slot-to-sub map
will be added in future releases.

Test: Manual + unit tests
bug: 63949982, 64004402, 63872700, 64176629
Merged-In: I88992d9cc92d18f7e344b58ea49b1d3007b50b41
Change-Id: I88992d9cc92d18f7e344b58ea49b1d3007b50b41
parent 7d64fae5
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -739,10 +739,11 @@ public class SubscriptionController extends ISub.Stub {
                    do {
                        int subId = cursor.getInt(cursor.getColumnIndexOrThrow(
                                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID));
                        // If sSlotIndexToSubId already has a valid subId for a slotIndex/phoneId,
                        // do not add another subId for same slotIndex/phoneId.
                        // If sSlotIndexToSubId already has the same subId for a slotIndex/phoneId,
                        // do not add it.
                        Integer currentSubId = sSlotIndexToSubId.get(slotIndex);
                        if (currentSubId == null
                                || currentSubId != subId
                                || !SubscriptionManager.isValidSubscriptionId(currentSubId)) {
                            // TODO While two subs active, if user deactivats first
                            // one, need to update the default subId with second one.
+7 −2
Original line number Diff line number Diff line
@@ -533,8 +533,6 @@ public class SubscriptionInfoUpdater extends Handler {
    synchronized private void updateSubscriptionInfoByIccId() {
        logd("updateSubscriptionInfoByIccId:+ Start");

        mSubscriptionManager.clearSubscriptionInfo();

        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            mInsertSimState[i] = SIM_NOT_CHANGE;
        }
@@ -548,6 +546,13 @@ public class SubscriptionInfoUpdater extends Handler {
        }
        logd("insertedSimCount = " + insertedSimCount);

        // We only clear the slot-to-sub map when one/some SIM was removed. Note this is a
        // workaround for some race conditions that the empty map was accessed while we are
        // rebuilding the map.
        if (SubscriptionController.getInstance().getActiveSubIdList().length > insertedSimCount) {
            SubscriptionController.getInstance().clearSubInfo();
        }

        int index = 0;
        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            if (mInsertSimState[i] == SIM_NOT_INSERT) {