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

Commit a8354625 authored by Matt Pietal's avatar Matt Pietal
Browse files

Synchronize access to sim data

Mutiple refactors have attempted to remove work from the main
thread. However, KeyguardUpdateMonitor assumes main thread
access to protect data structures like simData. Add synchronized
blocks around mSimData to prevent concurrent modifications.

Fixes: 371663342
Test: manual - race condition crash
Flag: EXEMPT bugfix
Change-Id: I32479d8900dd9719929d0604ca403e5c2095a030
parent 44ad17fa
Loading
Loading
Loading
Loading
+82 −66
Original line number Diff line number Diff line
@@ -315,6 +315,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    };
    private final FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig;

    private final Object mSimDataLockObject = new Object();
    HashMap<Integer, SimData> mSimDatas = new HashMap<>();
    HashMap<Integer, ServiceState> mServiceStates = new HashMap<>();

@@ -610,6 +611,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab

        // It is possible for active subscriptions to become invalid (-1), and these will not be
        // present in the subscriptionInfo list
        synchronized (mSimDataLockObject) {
            Iterator<Map.Entry<Integer, SimData>> iter = mSimDatas.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<Integer, SimData> simData = iter.next();
@@ -638,6 +640,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            }
            callbacksRefreshCarrierInfo();
        }
    }

    private void handleAirplaneModeChanged() {
        callbacksRefreshCarrierInfo();
@@ -3376,15 +3379,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
     * Removes all valid subscription info from the map for the given slotId.
     */
    private void invalidateSlot(int slotId) {
        synchronized (mSimDataLockObject) {
            Iterator<Map.Entry<Integer, SimData>> iter = mSimDatas.entrySet().iterator();
            while (iter.hasNext()) {
                SimData data = iter.next().getValue();
            if (data.slotId == slotId && SubscriptionManager.isValidSubscriptionId(data.subId)) {
                if (data.slotId == slotId
                        && SubscriptionManager.isValidSubscriptionId(data.subId)) {
                    mSimLogger.logInvalidSubId(data.subId);
                    iter.remove();
                }
            }
        }
    }

    /**
     * Handle {@link #MSG_SIM_STATE_CHANGE}
@@ -3408,6 +3414,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        }

        // TODO(b/327476182): Preserve SIM_STATE_CARD_IO_ERROR sims in a separate data source.
        synchronized (mSimDataLockObject) {
            SimData data = mSimDatas.get(subId);
            final boolean changed;
            if (data == null) {
@@ -3429,6 +3436,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                }
            }
        }
    }

    /**
     * Handle {@link #MSG_SERVICE_STATE_CHANGE}
@@ -3684,11 +3692,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        callback.onKeyguardVisibilityChanged(isKeyguardVisible());
        callback.onTelephonyCapable(mTelephonyCapable);

        synchronized (mSimDataLockObject) {
            for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
                final SimData state = data.getValue();
                callback.onSimStateChanged(state.subId, state.slotId, state.simState);
            }
        }
    }

    public void sendKeyguardReset() {
        mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
@@ -3823,20 +3833,24 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    }

    public int getSimState(int subId) {
        synchronized (mSimDataLockObject) {
            if (mSimDatas.containsKey(subId)) {
                return mSimDatas.get(subId).simState;
            } else {
                return TelephonyManager.SIM_STATE_UNKNOWN;
            }
        }
    }

    private int getSlotId(int subId) {
        synchronized (mSimDataLockObject) {
            if (!mSimDatas.containsKey(subId)) {
                refreshSimState(subId, SubscriptionManager.getSlotIndex(subId));
            }
            SimData simData = mSimDatas.get(subId);
            return simData != null ? simData.slotId : SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        }
    }

    private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
        @Override
@@ -3876,6 +3890,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
     */
    private boolean refreshSimState(int subId, int slotId) {
        int state = mTelephonyManager.getSimState(slotId);
        synchronized (mSimDataLockObject) {
            SimData data = mSimDatas.get(subId);

            if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -3893,6 +3908,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            }
            return changed;
        }
    }

    /**
     * If the {@code state} is currently requiring a SIM PIN, PUK, or is disabled.