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 Original line Diff line number Diff line
@@ -315,6 +315,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    };
    };
    private final FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig;
    private final FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig;


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


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


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


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


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


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


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


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


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


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


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