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

Commit 6095eb5a authored by Shishir Agrawal's avatar Shishir Agrawal
Browse files

SubscriptionInfoUpdater: Do not do work in the BroadcastReciever.

Currently a lot of work is done in the BR, which is bad design, possibly
problematic. Also removes the EVENT_OFFSET encoding what was not required.

Bug: 18156403
Change-Id: I6400eb27a77858efdbdd69289602fb2b5d7aaf83
parent f60ab49b
Loading
Loading
Loading
Loading
+132 −112
Original line number Diff line number Diff line
@@ -48,9 +48,13 @@ import java.util.List;
public class SubscriptionInfoUpdater extends Handler {
    private static final String LOG_TAG = "SubscriptionInfoUpdater";
    private static final int PROJECT_SIM_NUM = TelephonyManager.getDefault().getPhoneCount();
    private static final int EVENT_OFFSET = 8;

    private static final int EVENT_QUERY_ICCID_DONE = 1;
    private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 2;
    private static final int EVENT_SIM_LOADED = 3;
    private static final int EVENT_SIM_ABSENT = 4;
    private static final int EVENT_SIM_READY_OR_LOCKED = 5;

    private static final String ICCID_STRING_FOR_NO_SIM = "";
    /**
     *  int[] sInsertSimState maintains all slots' SIM inserted status currently,
@@ -101,10 +105,6 @@ public class SubscriptionInfoUpdater extends Handler {
        mContext.registerReceiver(sReceiver, intentFilter);
    }

    private int encodeEventId(int event, int slotId) {
        return event << (slotId * EVENT_OFFSET);
    }

    private final BroadcastReceiver sReceiver = new  BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
@@ -112,6 +112,7 @@ public class SubscriptionInfoUpdater extends Handler {
            String action = intent.getAction();
            int slotId;
            logd("Action: " + action);

            if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
                String simStatus = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
                slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY,
@@ -123,14 +124,9 @@ public class SubscriptionInfoUpdater extends Handler {
                if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(simStatus)
                        || IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(simStatus)
                        || IccCardConstants.INTENT_VALUE_ICC_INTERNAL_LOCKED.equals(simStatus)) {
                    if (mIccId[slotId] != null && mIccId[slotId].equals(ICCID_STRING_FOR_NO_SIM)) {
                        logd("SIM" + (slotId + 1) + " hot plug in");
                        mIccId[slotId] = null;
                        mNeedUpdate = true;
                    }
                    //TODO: Use RetryManager to limit number of retries and do a exponential backoff
                    if (((PhoneProxy)mPhone[slotId]).getIccFileHandler() != null) {
                        queryIccId(slotId);
                        sendMessage(obtainMessage(EVENT_SIM_READY_OR_LOCKED, slotId, -1));
                    } else {
                        intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE,
                                IccCardConstants.INTENT_VALUE_ICC_INTERNAL_LOCKED);
@@ -138,12 +134,122 @@ public class SubscriptionInfoUpdater extends Handler {
                                "android.permission.READ_PHONE_STATE", UserHandle.USER_ALL);
                    }
                } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(simStatus)) {
                    int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                            SubscriptionManager.INVALID_SUBSCRIPTION_ID);
                    sendMessage(obtainMessage(EVENT_SIM_LOADED, slotId, subId));
                } else if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(simStatus)) {
                    sendMessage(obtainMessage(EVENT_SIM_ABSENT, slotId, -1));
                }
            }
            logd("[Receiver]-");
        }
    };

    private boolean isAllIccIdQueryDone() {
        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            if (mIccId[i] == null) {
                logd("Wait for SIM" + (i + 1) + " IccId");
                return false;
            }
        }
        logd("All IccIds query complete");

        return true;
    }

    public void setDisplayNameForNewSub(String newSubName, int subId, int newNameSource) {
        SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(subId);
        if (subInfo != null) {
            // overwrite SIM display name if it is not assigned by user
            int oldNameSource = subInfo.getNameSource();
            CharSequence oldSubName = subInfo.getDisplayName();
            logd("[setDisplayNameForNewSub] subId = " + subInfo.getSubscriptionId()
                    + ", oldSimName = " + oldSubName + ", oldNameSource = " + oldNameSource
                    + ", newSubName = " + newSubName + ", newNameSource = " + newNameSource);
            if (oldSubName == null ||
                (oldNameSource ==
                    SubscriptionManager.NAME_SOURCE_DEFAULT_SOURCE && newSubName != null) ||
                (oldNameSource == SubscriptionManager.NAME_SOURCE_SIM_SOURCE && newSubName != null
                        && !newSubName.equals(oldSubName))) {
                mSubscriptionManager.setDisplayName(newSubName, subInfo.getSubscriptionId(),
                        newNameSource);
            }
        } else {
            logd("SUB" + (subId + 1) + " SubInfo not created yet");
        }
    }

    @Override
    public void handleMessage(Message msg) {
        AsyncResult ar = (AsyncResult)msg.obj;
        switch (msg.what) {
            case EVENT_QUERY_ICCID_DONE: {
                Integer slotId = (Integer)ar.userObj;
                logd("handleMessage : <EVENT_QUERY_ICCID_DONE> SIM" + (slotId + 1));
                if (ar.exception == null) {
                    if (ar.result != null) {
                        byte[] data = (byte[])ar.result;
                        mIccId[slotId] = IccUtils.bcdToString(data, 0, data.length);
                    } else {
                        logd("Null ar");
                        mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
                    }
                } else {
                    mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
                    logd("Query IccId fail: " + ar.exception);
                }
                logd("sIccId[" + slotId + "] = " + mIccId[slotId]);
                if (isAllIccIdQueryDone() && mNeedUpdate) {
                    updateSubscriptionInfoByIccId();
                }
                break;
            }

            case EVENT_GET_NETWORK_SELECTION_MODE_DONE: {
                Integer slotId = (Integer)ar.userObj;
                if (ar.exception == null && ar.result != null) {
                    int[] modes = (int[])ar.result;
                    if (modes[0] == 1) {  // Manual mode.
                        mPhone[slotId].setNetworkSelectionModeAutomatic(null);
                    }
                } else {
                    logd("EVENT_GET_NETWORK_SELECTION_MODE_DONE: error getting network mode.");
                }
                break;
            }

           case EVENT_SIM_LOADED:
                handleSimLoaded(msg.arg1, msg.arg2);
                break;

            case EVENT_SIM_ABSENT:
                handleSimAbsent(msg.arg1);
                break;

            case EVENT_SIM_READY_OR_LOCKED:
                handleSimReadyOrLocked(msg.arg1);
                break;

            default:
                logd("Unknown msg:" + msg.what);
        }
    }

    private void handleSimReadyOrLocked(int slotId) {
        if (mIccId[slotId] != null && mIccId[slotId].equals(ICCID_STRING_FOR_NO_SIM)) {
            logd("SIM" + (slotId + 1) + " hot plug in");
            mIccId[slotId] = null;
            mNeedUpdate = true;
        }

        queryIccId(slotId);
    }

    private void handleSimLoaded(int slotId, int subId) {
        queryIccId(slotId);
        if (mTelephonyMgr == null) {
            mTelephonyMgr = TelephonyManager.from(mContext);
        }
                    int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                            SubscriptionManager.INVALID_SUBSCRIPTION_ID);

        if (SubscriptionManager.isValidSubscriptionId(subId)) {
            String msisdn = TelephonyManager.getDefault()
@@ -191,7 +297,7 @@ public class SubscriptionInfoUpdater extends Handler {
             * Storing last IMSI in SharedPreference for now. Can consider making it
             * part of subscription info db */
            SharedPreferences sp =
                                PreferenceManager.getDefaultSharedPreferences(context);
                    PreferenceManager.getDefaultSharedPreferences(mContext);
            String storedImsi = sp.getString(CURR_IMSI + slotId, "");
            String newImsi = mPhone[slotId].getSubscriberId();

@@ -206,7 +312,7 @@ public class SubscriptionInfoUpdater extends Handler {

                // Only support automatic selection mode on IMSI change.
                mPhone[slotId].getNetworkSelectionMode(
                                    obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE));
                        obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, new Integer(slotId)));

                // Update stored IMSI
                SharedPreferences.Editor editor = sp.edit();
@@ -214,9 +320,11 @@ public class SubscriptionInfoUpdater extends Handler {
                editor.apply();
            }
        } else {
                        logd("[Receiver] Invalid subId, could not update ContentResolver");
            logd("Invalid subId, could not update ContentResolver");
        }
                } else if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(simStatus)) {
    }

    private void handleSimAbsent(int slotId) {
        if (mIccId[slotId] != null && !mIccId[slotId].equals(ICCID_STRING_FOR_NO_SIM)) {
            logd("SIM" + (slotId + 1) + " hot plug out");
            mNeedUpdate = true;
@@ -227,94 +335,6 @@ public class SubscriptionInfoUpdater extends Handler {
            updateSubscriptionInfoByIccId();
        }
    }
            }
            logd("[Receiver]-");
        }
    };

    private boolean isAllIccIdQueryDone() {
        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            if (mIccId[i] == null) {
                logd("Wait for SIM" + (i + 1) + " IccId");
                return false;
            }
        }
        logd("All IccIds query complete");

        return true;
    }

    public void setDisplayNameForNewSub(String newSubName, int subId, int newNameSource) {
        SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(subId);
        if (subInfo != null) {
            // overwrite SIM display name if it is not assigned by user
            int oldNameSource = subInfo.getNameSource();
            CharSequence oldSubName = subInfo.getDisplayName();
            logd("[setDisplayNameForNewSub] subId = " + subInfo.getSubscriptionId()
                    + ", oldSimName = " + oldSubName + ", oldNameSource = " + oldNameSource
                    + ", newSubName = " + newSubName + ", newNameSource = " + newNameSource);
            if (oldSubName == null ||
                (oldNameSource ==
                    SubscriptionManager.NAME_SOURCE_DEFAULT_SOURCE && newSubName != null) ||
                (oldNameSource == SubscriptionManager.NAME_SOURCE_SIM_SOURCE && newSubName != null
                        && !newSubName.equals(oldSubName))) {
                mSubscriptionManager.setDisplayName(newSubName, subInfo.getSubscriptionId(),
                        newNameSource);
            }
        } else {
            logd("SUB" + (subId + 1) + " SubInfo not created yet");
        }
    }

    @Override
    public void handleMessage(Message msg) {
        AsyncResult ar = (AsyncResult)msg.obj;
        int msgNum = msg.what;
        int slotId;
        for (slotId = PhoneConstants.SUB1; slotId <= PhoneConstants.SUB3; slotId++) {
            int pivot = 1 << (slotId * EVENT_OFFSET);
            if (msgNum >= pivot) {
                continue;
            } else {
                break;
            }
        }
        slotId--;
        int event = msgNum >> (slotId * EVENT_OFFSET);
        switch (event) {
            case EVENT_QUERY_ICCID_DONE:
                logd("handleMessage : <EVENT_QUERY_ICCID_DONE> SIM" + (slotId + 1));
                if (ar.exception == null) {
                    if (ar.result != null) {
                        byte[] data = (byte[])ar.result;
                        mIccId[slotId] = IccUtils.bcdToString(data, 0, data.length);
                    } else {
                        logd("Null ar");
                        mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
                    }
                } else {
                    mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
                    logd("Query IccId fail: " + ar.exception);
                }
                logd("sIccId[" + slotId + "] = " + mIccId[slotId]);
                if (isAllIccIdQueryDone() && mNeedUpdate) {
                    updateSubscriptionInfoByIccId();
                }
                break;
            case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
                if (ar.exception == null && ar.result != null) {
                    int[] modes = (int[])ar.result;
                    if (modes[0] == 1) {  // Manual mode.
                        mPhone[slotId].setNetworkSelectionModeAutomatic(null);
                    }
                } else {
                    logd("EVENT_GET_NETWORK_SELECTION_MODE_DONE: error getting network mode.");
                }
                break;
            default:
                logd("Unknown msg:" + msg.what);
        }
    }

    private void queryIccId(int slotId) {
        logd("queryIccId: slotid=" + slotId);
@@ -337,7 +357,7 @@ public class SubscriptionInfoUpdater extends Handler {
            if (iccId == null) {
                logd("Querying IccId");
                mFh[slotId].loadEFTransparent(IccConstants.EF_ICCID,
                        obtainMessage(encodeEventId(EVENT_QUERY_ICCID_DONE, slotId)));
                        obtainMessage(EVENT_QUERY_ICCID_DONE, new Integer(slotId)));
            } else {
                logd("NOT Querying IccId its already set sIccid[" + slotId + "]=" + iccId);
            }