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

Commit 19a3b32b authored by Amit Mahajan's avatar Amit Mahajan Committed by Gerrit Code Review
Browse files

Merge "Add UiccCard to UiccSlot, and UiccSlot to UiccController."

parents f1aabe15 3caa000d
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ public class IccCardProxy extends Handler implements IccCard {

    private int mCurrentAppType = UiccController.APP_FAM_3GPP; //default to 3gpp?
    private UiccController mUiccController = null;
    private UiccSlot mUiccSlot = null;
    private UiccCard mUiccCard = null;
    private UiccCardApplication mUiccApplication = null;
    private IccRecords mIccRecords = null;
@@ -293,6 +294,7 @@ public class IccCardProxy extends Handler implements IccCard {

    private void updateIccAvailability() {
        synchronized (mLock) {
            UiccSlot newSlot = mUiccController.getUiccSlotForPhone(mPhoneId);
            UiccCard newCard = mUiccController.getUiccCard(mPhoneId);
            UiccCardApplication newApp = null;
            IccRecords newRecords = null;
@@ -303,9 +305,11 @@ public class IccCardProxy extends Handler implements IccCard {
                }
            }

            if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard) {
            if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard
                    || mUiccSlot != newSlot) {
                if (DBG) log("Icc changed. Reregistering.");
                unregisterUiccCardEvents();
                mUiccSlot = newSlot;
                mUiccCard = newCard;
                mUiccApplication = newApp;
                mIccRecords = newRecords;
@@ -406,8 +410,9 @@ public class IccCardProxy extends Handler implements IccCard {
    }

    private void registerUiccCardEvents() {
        if (mUiccCard != null) {
            mUiccCard.registerForAbsent(this, EVENT_ICC_ABSENT, null);
        if (mUiccSlot != null) {
            // todo: reregistration is not needed unless slot mapping changes
            mUiccSlot.registerForAbsent(this, EVENT_ICC_ABSENT, null);
        }
        if (mUiccApplication != null) {
            mUiccApplication.registerForReady(this, EVENT_APP_READY, null);
@@ -422,7 +427,7 @@ public class IccCardProxy extends Handler implements IccCard {
    }

    private void unregisterUiccCardEvents() {
        if (mUiccCard != null) mUiccCard.unregisterForAbsent(this);
        if (mUiccSlot != null) mUiccSlot.unregisterForAbsent(this);
        if (mUiccCard != null) mUiccCard.unregisterForCarrierPrivilegeRulesLoaded(this);
        if (mUiccApplication != null) mUiccApplication.unregisterForReady(this);
        if (mUiccApplication != null) mUiccApplication.unregisterForLocked(this);
+0 −133
Original line number Diff line number Diff line
@@ -18,8 +18,6 @@ package com.android.internal.telephony.uicc;

import android.app.AlertDialog;
import android.app.usage.UsageStatsManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -34,7 +32,6 @@ import android.os.Binder;
import android.os.Handler;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.Registrant;
import android.os.RegistrantList;
import android.preference.PreferenceManager;
@@ -48,7 +45,6 @@ import android.view.WindowManager;

import com.android.internal.R;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.CommandsInterface.RadioState;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.cat.CatService;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
@@ -84,14 +80,10 @@ public class UiccCard {
    private Context mContext;
    private CommandsInterface mCi;
    private CatService mCatService;
    private RadioState mLastRadioState =  RadioState.RADIO_UNAVAILABLE;
    private UiccCarrierPrivilegeRules mCarrierPrivilegeRules;

    private RegistrantList mAbsentRegistrants = new RegistrantList();
    private RegistrantList mCarrierPrivilegeRegistrants = new RegistrantList();

    private static final int EVENT_CARD_REMOVED = 13;
    private static final int EVENT_CARD_ADDED = 14;
    private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 15;
    private static final int EVENT_CLOSE_LOGICAL_CHANNEL_DONE = 16;
    private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 17;
@@ -168,24 +160,6 @@ public class UiccCard {
            }

            sanitizeApplicationIndexesLocked();

            RadioState radioState = mCi.getRadioState();
            if (DBG) log("update: radioState=" + radioState + " mLastRadioState="
                    + mLastRadioState);
            // No notifications while radio is off or we just powering up
            if (radioState == RadioState.RADIO_ON && mLastRadioState == RadioState.RADIO_ON) {
                if (oldState != CardState.CARDSTATE_ABSENT &&
                        mCardState == CardState.CARDSTATE_ABSENT) {
                    if (DBG) log("update: notify card removed");
                    mAbsentRegistrants.notifyRegistrants();
                    mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null));
                } else if (oldState == CardState.CARDSTATE_ABSENT &&
                        mCardState != CardState.CARDSTATE_ABSENT) {
                    if (DBG) log("update: notify card added");
                    mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null));
                }
            }
            mLastRadioState = radioState;
        }
    }

@@ -248,27 +222,6 @@ public class UiccCard {
        return index;
    }

    /**
     * Notifies handler of any transition into State.ABSENT
     */
    public void registerForAbsent(Handler h, int what, Object obj) {
        synchronized (mLock) {
            Registrant r = new Registrant (h, what, obj);

            mAbsentRegistrants.add(r);

            if (mCardState == CardState.CARDSTATE_ABSENT) {
                r.notifyRegistrant();
            }
        }
    }

    public void unregisterForAbsent(Handler h) {
        synchronized (mLock) {
            mAbsentRegistrants.remove(h);
        }
    }

    /**
     * Notifies handler when carrier privilege rules are loaded.
     */
@@ -290,90 +243,10 @@ public class UiccCard {
        }
    }

    private void onIccSwap(boolean isAdded) {

        boolean isHotSwapSupported = mContext.getResources().getBoolean(
                R.bool.config_hotswapCapable);

        if (isHotSwapSupported) {
            log("onIccSwap: isHotSwapSupported is true, don't prompt for rebooting");
            return;
        }
        log("onIccSwap: isHotSwapSupported is false, prompt for rebooting");

        promptForRestart(isAdded);
    }

    private void promptForRestart(boolean isAdded) {
        synchronized (mLock) {
            final Resources res = mContext.getResources();
            final String dialogComponent = res.getString(
                    R.string.config_iccHotswapPromptForRestartDialogComponent);
            if (dialogComponent != null) {
                Intent intent = new Intent().setComponent(ComponentName.unflattenFromString(
                        dialogComponent)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        .putExtra(EXTRA_ICC_CARD_ADDED, isAdded);
                try {
                    mContext.startActivity(intent);
                    return;
                } catch (ActivityNotFoundException e) {
                    loge("Unable to find ICC hotswap prompt for restart activity: " + e);
                }
            }

            // TODO: Here we assume the device can't handle SIM hot-swap
            //      and has to reboot. We may want to add a property,
            //      e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support
            //      hot-swap.
            DialogInterface.OnClickListener listener = null;


            // TODO: SimRecords is not reset while SIM ABSENT (only reset while
            //       Radio_off_or_not_available). Have to reset in both both
            //       added or removed situation.
            listener = new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    synchronized (mLock) {
                        if (which == DialogInterface.BUTTON_POSITIVE) {
                            if (DBG) log("Reboot due to SIM swap");
                            PowerManager pm = (PowerManager) mContext
                                    .getSystemService(Context.POWER_SERVICE);
                            pm.reboot("SIM is added.");
                        }
                    }
                }

            };

            Resources r = Resources.getSystem();

            String title = (isAdded) ? r.getString(R.string.sim_added_title) :
                r.getString(R.string.sim_removed_title);
            String message = (isAdded) ? r.getString(R.string.sim_added_message) :
                r.getString(R.string.sim_removed_message);
            String buttonTxt = r.getString(R.string.sim_restart_button);

            AlertDialog dialog = new AlertDialog.Builder(mContext)
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton(buttonTxt, listener)
            .create();
            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
            dialog.show();
        }
    }

    protected Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg){
            switch (msg.what) {
                case EVENT_CARD_REMOVED:
                    onIccSwap(false);
                    break;
                case EVENT_CARD_ADDED:
                    onIccSwap(true);
                    break;
                case EVENT_OPEN_LOGICAL_CHANNEL_DONE:
                case EVENT_CLOSE_LOGICAL_CHANNEL_DONE:
                case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
@@ -792,13 +665,7 @@ public class UiccCard {
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("UiccCard:");
        pw.println(" mCi=" + mCi);
        pw.println(" mLastRadioState=" + mLastRadioState);
        pw.println(" mCatService=" + mCatService);
        pw.println(" mAbsentRegistrants: size=" + mAbsentRegistrants.size());
        for (int i = 0; i < mAbsentRegistrants.size(); i++) {
            pw.println("  mAbsentRegistrants[" + i + "]="
                    + ((Registrant)mAbsentRegistrants.get(i)).getHandler());
        }
        for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) {
            pw.println("  mCarrierPrivilegeRegistrants[" + i + "]="
                    + ((Registrant)mCarrierPrivilegeRegistrants.get(i)).getHandler());
+123 −50
Original line number Diff line number Diff line
@@ -22,15 +22,13 @@ import android.os.Handler;
import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.SystemProperties;
import android.os.storage.StorageManager;
import android.telephony.TelephonyManager;
import android.telephony.Rlog;
import android.telephony.TelephonyManager;
import android.text.format.Time;

import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.SubscriptionController;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -85,12 +83,21 @@ public class UiccController extends Handler {
    public static final int APP_FAM_IMS   = 3;

    private static final int EVENT_ICC_STATUS_CHANGED = 1;
    private static final int EVENT_GET_ICC_STATUS_DONE = 2;
    private static final int EVENT_RADIO_UNAVAILABLE = 3;
    private static final int EVENT_SIM_REFRESH = 4;

    private static final int EVENT_SLOT_STATUS_CHANGED = 2;
    private static final int EVENT_ICC_OR_SLOT_STATUS_CHANGED = 3;
    private static final int EVENT_GET_ICC_STATUS_DONE = 4;
    private static final int EVENT_RADIO_UNAVAILABLE = 5;
    private static final int EVENT_SIM_REFRESH = 6;

    // this still needs to be here, because on bootup we dont know which index maps to which
    // UiccSlot
    private CommandsInterface[] mCis;
    private UiccCard[] mUiccCards = new UiccCard[TelephonyManager.getDefault().getPhoneCount()];
    // todo: add a system property/mk file constant for this
    private UiccSlot[] mUiccSlots = new UiccSlot[TelephonyManager.getDefault().getPhoneCount()];
    // flag to indicate if UiccSlots have been initialized. This will be set to true only after the
    // first slots status is received. That is when phoneId to slotId mapping is known as well.
    // todo: assuming true for now and hardcoding the mapping between UiccSlot index and phoneId
    private boolean mUiccSlotsInitialized = true;

    private static final Object mLock = new Object();
    private static UiccController mInstance;
@@ -120,17 +127,23 @@ public class UiccController extends Handler {
        mContext = c;
        mCis = ci;
        for (int i = 0; i < mCis.length; i++) {
            Integer index = new Integer(i);
            // todo: get rid of this once hardcoding of mapping between UiccSlot index and phoneId
            // is removed, instead do this when icc/slot status is received
            mUiccSlots[i] = new UiccSlot(c, true /* isActive */);

            Integer index = i;
            mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, index);
            // todo: add registration for slot status changed here

            // TODO remove this once modem correctly notifies the unsols
            // If the device is unencrypted or has been decrypted or FBE is supported,
            // i.e. not in cryptkeeper bounce, read SIM when radio state isavailable.
            // Else wait for radio to be on. This is needed for the scenario when SIM is locked --
            // to avoid overlap of CryptKeeper and SIM unlock screen.
            if (!StorageManager.inCryptKeeperBounce()) {
                mCis[i].registerForAvailable(this, EVENT_ICC_STATUS_CHANGED, index);
                mCis[i].registerForAvailable(this, EVENT_ICC_OR_SLOT_STATUS_CHANGED, index);
            } else {
                mCis[i].registerForOn(this, EVENT_ICC_STATUS_CHANGED, index);
                mCis[i].registerForOn(this, EVENT_ICC_OR_SLOT_STATUS_CHANGED, index);
            }
            mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index);
            mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, index);
@@ -139,6 +152,13 @@ public class UiccController extends Handler {
        mLauncher = new UiccStateChangedLauncher(c, this);
    }

    private int getSlotIdFromPhoneId(int phoneId) {
        // todo: implement (if mUiccSlotsInitialized || if info available about that specific
        // phoneId which will be the case if sim status for that phoneId is received first)
        // else return invalid slotId
        return phoneId;
    }

    public static UiccController getInstance() {
        synchronized (mLock) {
            if (mInstance == null) {
@@ -151,18 +171,74 @@ public class UiccController extends Handler {

    public UiccCard getUiccCard(int phoneId) {
        synchronized (mLock) {
            if (isValidCardIndex(phoneId)) {
                return mUiccCards[phoneId];
            return getUiccCardForPhone(phoneId);
        }
    }

    /**
     * API to get UiccCard corresponding to given physical slot index
     * @param slotId index of physical slot on the device
     * @return UiccCard object corresponting to given physical slot index; null if card is
     * absent
     */
    public UiccCard getUiccCardForSlot(int slotId) {
        synchronized (mLock) {
            UiccSlot uiccSlot = getUiccSlot(slotId);
            if (uiccSlot != null) {
                return uiccSlot.getUiccCard();
            }
            return null;
        }
    }

    public UiccCard[] getUiccCards() {
    /**
     * API to get UiccCard corresponding to given phone id
     * @return UiccCard object corresponding to given phone id; null if there is no card present for
     * the phone id
     */
    public UiccCard getUiccCardForPhone(int phoneId) {
        synchronized (mLock) {
            int slotId = getSlotIdFromPhoneId(phoneId);
            return getUiccCardForSlot(slotId);
        }
    }

    /**
     * API to get an array of all UiccSlots, which represents all physical slots on the device
     * @return array of all UiccSlots
     */
    public UiccSlot[] getUiccSlots() {
        // Return cloned array since we don't want to give out reference
        // to internal data structure.
        synchronized (mLock) {
            return mUiccCards.clone();
            return mUiccSlots.clone();
        }
    }

    /**
     * API to get UiccSlot object for a specific physical slot index on the device
     * @return UiccSlot object for the given physical slot index
     */
    public UiccSlot getUiccSlot(int slotId) {
        synchronized (mLock) {
            if (isValidSlotIndex(slotId)) {
                return mUiccSlots[slotId];
            }
            return null;
        }
    }

    /**
     * API to get UiccSlot object for a given phone id
     * @return UiccSlot object for the given phone id
     */
    public UiccSlot getUiccSlotForPhone(int phoneId) {
        synchronized (mLock) {
            int slotId = getSlotIdFromPhoneId(phoneId);
            if (isValidSlotIndex(slotId)) {
                return mUiccSlots[slotId];
            }
            return null;
        }
    }

@@ -209,34 +285,34 @@ public class UiccController extends Handler {
    @Override
    public void handleMessage (Message msg) {
        synchronized (mLock) {
            Integer index = getCiIndex(msg);
            Integer phoneId = getCiIndex(msg);

            if (index < 0 || index >= mCis.length) {
                Rlog.e(LOG_TAG, "Invalid index : " + index + " received with event " + msg.what);
            if (phoneId < 0 || phoneId >= mCis.length) {
                Rlog.e(LOG_TAG, "Invalid phoneId : " + phoneId + " received with event "
                        + msg.what);
                return;
            }

            AsyncResult ar = (AsyncResult)msg.obj;
            switch (msg.what) {
                case EVENT_ICC_STATUS_CHANGED:
                case EVENT_ICC_OR_SLOT_STATUS_CHANGED:
                    if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
                    mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, index));
                    mCis[phoneId].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE,
                            phoneId));
                    break;
                case EVENT_GET_ICC_STATUS_DONE:
                    if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE");
                    onGetIccCardStatusDone(ar, index);
                    onGetIccCardStatusDone(ar, phoneId);
                    break;
                case EVENT_RADIO_UNAVAILABLE:
                    if (DBG) log("EVENT_RADIO_UNAVAILABLE, dispose card");
                    if (mUiccCards[index] != null) {
                        mUiccCards[index].dispose();
                    }
                    mUiccCards[index] = null;
                    mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null));
                    mUiccSlots[getSlotIdFromPhoneId(phoneId)].onRadioStateUnavailable();
                    mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, phoneId, null));
                    break;
                case EVENT_SIM_REFRESH:
                    if (DBG) log("Received EVENT_SIM_REFRESH");
                    onSimRefresh(ar, index);
                    onSimRefresh(ar, phoneId);
                    break;
                default:
                    Rlog.e(LOG_TAG, " Unknown Event " + msg.what);
@@ -269,11 +345,9 @@ public class UiccController extends Handler {
    // Easy to use API
    public UiccCardApplication getUiccCardApplication(int phoneId, int family) {
        synchronized (mLock) {
            if (isValidCardIndex(phoneId)) {
                UiccCard c = mUiccCards[phoneId];
                if (c != null) {
                    return mUiccCards[phoneId].getApplication(family);
                }
            UiccCard uiccCard = getUiccCardForPhone(phoneId);
            if (uiccCard != null) {
                return uiccCard.getApplication(family);
            }
            return null;
        }
@@ -293,13 +367,7 @@ public class UiccController extends Handler {

        IccCardStatus status = (IccCardStatus)ar.result;

        if (mUiccCards[index] == null) {
            //Create new card
            mUiccCards[index] = new UiccCard(mContext, mCis[index], status, index);
        } else {
            //Update already existing card
            mUiccCards[index].update(mContext, mCis[index] , status);
        }
        mUiccSlots[getSlotIdFromPhoneId(index)].update(mContext, mCis[index], status, index);

        if (DBG) log("Notifying IccChangedRegistrants");
        mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null));
@@ -320,7 +388,8 @@ public class UiccController extends Handler {
        IccRefreshResponse resp = (IccRefreshResponse) ar.result;
        Rlog.d(LOG_TAG, "onSimRefresh: " + resp);

        if (mUiccCards[index] == null) {
        UiccCard uiccCard = getUiccCardForPhone(index);
        if (uiccCard == null) {
            Rlog.e(LOG_TAG,"onSimRefresh: refresh on null card : " + index);
            return;
        }
@@ -332,7 +401,7 @@ public class UiccController extends Handler {

        Rlog.d(LOG_TAG, "Handling refresh reset: " + resp);

        boolean changed = mUiccCards[index].resetAppWithAid(resp.aid);
        boolean changed = uiccCard.resetAppWithAid(resp.aid);
        if (changed) {
            boolean requirePowerOffOnSimRefreshReset = mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_requireRadioPowerOffOnSimRefreshReset);
@@ -346,7 +415,11 @@ public class UiccController extends Handler {
    }

    private boolean isValidCardIndex(int index) {
        return (index >= 0 && index < mUiccCards.length);
        return (index >= 0 && index < TelephonyManager.getDefault().getPhoneCount());
    }

    private boolean isValidSlotIndex(int index) {
        return (index >= 0 && index < mUiccSlots.length);
    }

    private void log(String string) {
@@ -374,13 +447,13 @@ public class UiccController extends Handler {
        }
        pw.println();
        pw.flush();
        pw.println(" mUiccCards: size=" + mUiccCards.length);
        for (int i = 0; i < mUiccCards.length; i++) {
            if (mUiccCards[i] == null) {
                pw.println("  mUiccCards[" + i + "]=null");
        pw.println(" mUiccSlots: size=" + mUiccSlots.length);
        for (int i = 0; i < mUiccSlots.length; i++) {
            if (mUiccSlots[i] == null) {
                pw.println("  mUiccSlots[" + i + "]=null");
            } else {
                pw.println("  mUiccCards[" + i + "]=" + mUiccCards[i]);
                mUiccCards[i].dump(fd, pw, args);
                pw.println("  mUiccSlots[" + i + "]=" + mUiccSlots[i]);
                mUiccSlots[i].dump(fd, pw, args);
            }
        }
        pw.println("mCardLogs: ");
+72 −21

File changed.

Preview size limit exceeded, changes collapsed.

+5 −4
Original line number Diff line number Diff line
@@ -65,11 +65,12 @@ public class UiccStateChangedLauncher extends Handler {
                    mIsRestricted = new boolean[TelephonyManager.getDefault().getPhoneCount()];
                    shouldNotify = true;
                }
                UiccCard[] cards = mUiccController.getUiccCards();
                for (int i = 0; cards != null && i < cards.length; ++i) {
                UiccSlot[] uiccSlots = mUiccController.getUiccSlots();
                for (int i = 0; uiccSlots != null && i < uiccSlots.length; ++i) {
                    // Update only if restricted state changes.
                    if ((cards[i] == null
                            || cards[i].getCardState() != CardState.CARDSTATE_RESTRICTED)
                    UiccCard uiccCard = uiccSlots[i].getUiccCard();
                    if ((uiccCard == null
                            || uiccCard.getCardState() != CardState.CARDSTATE_RESTRICTED)
                            != mIsRestricted[i]) {
                        mIsRestricted[i] = !mIsRestricted[i];
                        shouldNotify = true;
Loading