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

Commit fe37acae authored by Alex Yakavenka's avatar Alex Yakavenka Committed by Android (Google) Code Review
Browse files

Telephony: Dynamically instantiate IccCard

Change-Id: I8c4d800158fb1eb12de66d437cb0d76695ff98d3
parent df1423e2
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.util.Log;

import com.android.internal.R;
import com.android.internal.telephony.DataConnection.FailCause;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;

@@ -57,6 +58,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * {@hide}
@@ -138,6 +140,7 @@ public abstract class DataConnectionTracker extends Handler {
    public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 30;
    public static final int CMD_SET_DEPENDENCY_MET = BASE + 31;
    public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32;
    protected static final int EVENT_ICC_CHANGED = BASE + 33;

    /***** Constants *****/

@@ -250,6 +253,8 @@ public abstract class DataConnectionTracker extends Handler {

    // member variables
    protected PhoneBase mPhone;
    protected UiccController mUiccController;
    protected AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
    protected Activity mActivity = Activity.NONE;
    protected State mState = State.IDLE;
    protected Handler mDataConnectionTracker = null;
@@ -500,6 +505,8 @@ public abstract class DataConnectionTracker extends Handler {
    protected DataConnectionTracker(PhoneBase phone) {
        super();
        mPhone = phone;
        mUiccController = UiccController.getInstance();
        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);

        IntentFilter filter = new IntentFilter();
        filter.addAction(getActionIntentReconnectAlarm());
@@ -541,6 +548,7 @@ public abstract class DataConnectionTracker extends Handler {
        mIsDisposed = true;
        mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
        mDataRoamingSettingObserver.unregister(mPhone.getContext());
        mUiccController.unregisterForIccChanged(this);
    }

    protected void broadcastMessenger() {
@@ -663,6 +671,7 @@ public abstract class DataConnectionTracker extends Handler {
    protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason);
    protected abstract void onCleanUpAllConnections(String cause);
    protected abstract boolean isDataPossible(String apnType);
    protected abstract void onUpdateIcc();

    protected void onDataStallAlarm(int tag) {
        loge("onDataStallAlarm: not impleted tag=" + tag);
@@ -773,6 +782,10 @@ public abstract class DataConnectionTracker extends Handler {
                onSetPolicyDataEnabled(enabled);
                break;
            }
            case EVENT_ICC_CHANGED:
                onUpdateIcc();
                break;

            default:
                Log.e("DATA", "Unidentified event msg=" + msg);
                break;
+55 −67
Original line number Diff line number Diff line
@@ -35,10 +35,12 @@ import android.view.WindowManager;

import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.CommandsInterface.RadioState;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.gsm.SIMFileHandler;
import com.android.internal.telephony.gsm.SIMRecords;
import com.android.internal.telephony.cat.CatService;
import com.android.internal.telephony.cdma.CDMALTEPhone;
import com.android.internal.telephony.cdma.CDMAPhone;
import com.android.internal.telephony.cdma.CdmaLteUiccFileHandler;
import com.android.internal.telephony.cdma.CdmaLteUiccRecords;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
@@ -114,8 +116,6 @@ public class IccCard {
    protected static final int EVENT_ICC_LOCKED = 1;
    private static final int EVENT_GET_ICC_STATUS_DONE = 2;
    protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3;
    private static final int EVENT_PINPUK_DONE = 4;
    private static final int EVENT_REPOLL_STATUS_DONE = 5;
    protected static final int EVENT_ICC_READY = 6;
    private static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7;
    private static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8;
@@ -178,34 +178,19 @@ public class IccCard {
        return State.UNKNOWN;
    }

    public IccCard(PhoneBase phone, String logTag, Boolean is3gpp, Boolean dbg) {
    public IccCard(PhoneBase phone, IccCardStatus ics, String logTag, boolean dbg) {
        mLogTag = logTag;
        mDbg = dbg;
        if (mDbg) log("[IccCard] Creating card type " + (is3gpp ? "3gpp" : "3gpp2"));
        mPhone = phone;
        this.is3gpp = is3gpp;
        if (mDbg) log("Creating");
        update(phone, ics);
        mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(),
                mPhone.mCM, mHandler, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
        if (phone.mCM.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE
                && phone instanceof CDMALTEPhone) {
            mIccFileHandler = new CdmaLteUiccFileHandler(this, "", mPhone.mCM);
            mIccRecords = new CdmaLteUiccRecords(this, mPhone.mContext, mPhone.mCM);
        } else {
            // Correct aid will be set later (when GET_SIM_STATUS returns)
            mIccFileHandler = is3gpp ? new SIMFileHandler(this, "", mPhone.mCM) :
                                       new RuimFileHandler(this, "", mPhone.mCM);
            mIccRecords = is3gpp ? new SIMRecords(this, mPhone.mContext, mPhone.mCM) :
                                   new RuimRecords(this, mPhone.mContext, mPhone.mCM);
        }
        mCatService = CatService.getInstance(mPhone.mCM, mIccRecords,
                mPhone.mContext, mIccFileHandler, this);
        mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
        mPhone.mCM.registerForOn(mHandler, EVENT_RADIO_ON, null);
        mPhone.mCM.registerForIccStatusChanged(mHandler, EVENT_ICC_STATUS_CHANGED, null);
    }

    public void dispose() {
        if (mDbg) log("[IccCard] Disposing card type " + (is3gpp ? "3gpp" : "3gpp2"));
        if (mDbg) log("Disposing card type " + (is3gpp ? "3gpp" : "3gpp2"));
        mPhone.mCM.unregisterForIccStatusChanged(mHandler);
        mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
        mPhone.mCM.unregisterForOn(mHandler);
@@ -215,6 +200,40 @@ public class IccCard {
        mIccFileHandler.dispose();
    }

    public void update(PhoneBase phone, IccCardStatus ics) {
        if (phone != mPhone) {
            PhoneBase oldPhone = mPhone;
            mPhone = phone;
            log("Update");
            if (phone instanceof GSMPhone) {
                is3gpp = true;
            } else if (phone instanceof CDMALTEPhone){
                is3gpp = true;
            } else if (phone instanceof CDMAPhone){
                is3gpp = false;
            } else {
                throw new RuntimeException("Update: Unhandled phone type. Critical error!" +
                        phone.getPhoneName());
            }


            if (phone.mCM.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE
                    && phone instanceof CDMALTEPhone) {
                mIccFileHandler = new CdmaLteUiccFileHandler(this, "", mPhone.mCM);
                mIccRecords = new CdmaLteUiccRecords(this, mPhone.mContext, mPhone.mCM);
            } else {
                // Correct aid will be set later (when GET_SIM_STATUS returns)
                mIccFileHandler = is3gpp ? new SIMFileHandler(this, "", mPhone.mCM) :
                                           new RuimFileHandler(this, "", mPhone.mCM);
                mIccRecords = is3gpp ? new SIMRecords(this, mPhone.mContext, mPhone.mCM) :
                                       new RuimRecords(this, mPhone.mContext, mPhone.mCM);
            }
            mCatService = CatService.getInstance(mPhone.mCM, mIccRecords, mPhone.mContext,
                    mIccFileHandler, this);
        }
        mHandler.sendMessage(mHandler.obtainMessage(EVENT_GET_ICC_STATUS_DONE, ics));
    }

    protected void finalize() {
        if (mDbg) log("[IccCard] Finalized card type " + (is3gpp ? "3gpp" : "3gpp2"));
    }
@@ -344,27 +363,23 @@ public class IccCard {
     */

    public void supplyPin (String pin, Message onComplete) {
        mPhone.mCM.supplyIccPin(pin, mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
        mPhone.mCM.supplyIccPin(pin, onComplete);
    }

    public void supplyPuk (String puk, String newPin, Message onComplete) {
        mPhone.mCM.supplyIccPuk(puk, newPin,
                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
        mPhone.mCM.supplyIccPuk(puk, newPin, onComplete);
    }

    public void supplyPin2 (String pin2, Message onComplete) {
        mPhone.mCM.supplyIccPin2(pin2,
                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
        mPhone.mCM.supplyIccPin2(pin2, onComplete);
    }

    public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
        mPhone.mCM.supplyIccPuk2(puk2, newPin2,
                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
        mPhone.mCM.supplyIccPuk2(puk2, newPin2, onComplete);
    }

    public void supplyNetworkDepersonalization (String pin, Message onComplete) {
        mPhone.mCM.supplyNetworkDepersonalization(pin,
                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
        mPhone.mCM.supplyNetworkDepersonalization(pin, onComplete);
    }

    /**
@@ -494,21 +509,15 @@ public class IccCard {
     *
     */
    public String getServiceProviderName () {
        return mPhone.mIccRecords.getServiceProviderName();
        return mIccRecords.getServiceProviderName();
    }

    protected void updateStateProperty() {
        mPhone.setSystemProperty(TelephonyProperties.PROPERTY_SIM_STATE, getState().toString());
    }

    private void getIccCardStatusDone(AsyncResult ar) {
        if (ar.exception != null) {
            Log.e(mLogTag,"Error getting ICC status. "
                    + "RIL_REQUEST_GET_ICC_STATUS should "
                    + "never return an error", ar.exception);
            return;
        }
        handleIccCardStatus((IccCardStatus) ar.result);
    private void getIccCardStatusDone(IccCardStatus ics) {
        handleIccCardStatus(ics);
    }

    private void handleIccCardStatus(IccCardStatus newCardStatus) {
@@ -584,6 +593,7 @@ public class IccCard {
        if (oldState != State.READY && newState == State.READY &&
                (is3gpp || isSubscriptionFromIccCard)) {
            mIccFileHandler.setAid(getAid());
            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_READY, null);
            mIccRecords.onReady();
        }
    }
@@ -704,7 +714,6 @@ public class IccCard {
                    if (!is3gpp) {
                        handleCdmaSubscriptionSource();
                    }
                    mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
                    break;
                case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
                    handleCdmaSubscriptionSource();
@@ -725,30 +734,9 @@ public class IccCard {
                             obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
                     break;
                case EVENT_GET_ICC_STATUS_DONE:
                    ar = (AsyncResult)msg.obj;
                    IccCardStatus cs = (IccCardStatus)msg.obj;

                    getIccCardStatusDone(ar);
                    break;
                case EVENT_PINPUK_DONE:
                    // a PIN/PUK/PIN2/PUK2/Network Personalization
                    // request has completed. ar.userObj is the response Message
                    // Repoll before returning
                    ar = (AsyncResult)msg.obj;
                    // TODO should abstract these exceptions
                    AsyncResult.forMessage(((Message)ar.userObj)).exception
                                                        = ar.exception;
                    mPhone.mCM.getIccCardStatus(
                        obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj));
                    break;
                case EVENT_REPOLL_STATUS_DONE:
                    // Finished repolling status after PIN operation
                    // ar.userObj is the response messaeg
                    // ar.userObj.obj is already an AsyncResult with an
                    // appropriate exception filled in if applicable

                    ar = (AsyncResult)msg.obj;
                    getIccCardStatusDone(ar);
                    ((Message)ar.userObj).sendToTarget();
                    getIccCardStatusDone(cs);
                    break;
                case EVENT_QUERY_FACILITY_LOCK_DONE:
                    ar = (AsyncResult)msg.obj;
@@ -797,10 +785,6 @@ public class IccCard {
                                                        = ar.exception;
                    ((Message)ar.userObj).sendToTarget();
                    break;
                case EVENT_ICC_STATUS_CHANGED:
                    Log.d(mLogTag, "Received Event EVENT_ICC_STATUS_CHANGED");
                    mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
                    break;
                case EVENT_CARD_REMOVED:
                    onIccSwap(false);
                    break;
@@ -967,6 +951,10 @@ public class IccCard {
        Log.d(mLogTag, "[IccCard] " + msg);
    }

    private void loge(String msg) {
        Log.e(mLogTag, "[IccCard] " + msg);
    }

    protected int getCurrentApplicationIndex() {
        if (is3gpp) {
            return mIccCardStatus.getGsmUmtsSubscriptionAppIndex();
+12 −0
Original line number Diff line number Diff line
@@ -103,11 +103,23 @@ public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {

    public IccPhoneBookInterfaceManager(PhoneBase phone) {
        this.phone = phone;
        IccRecords r = phone.mIccRecords.get();
        if (r != null) {
            adnCache = r.getAdnCache();
        }
    }

    public void dispose() {
    }

    public void updateIccRecords(IccRecords iccRecords) {
        if (iccRecords != null) {
            adnCache = iccRecords.getAdnCache();
        } else {
            adnCache = null;
        }
    }

    protected void publish() {
        //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
        ServiceManager.addService("simphonebook", this);
+8 −10
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ import android.os.RegistrantList;
import com.android.internal.telephony.gsm.UsimServiceTable;
import com.android.internal.telephony.ims.IsimRecords;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * {@hide}
 */
@@ -33,7 +35,7 @@ public abstract class IccRecords extends Handler implements IccConstants {

    protected static final boolean DBG = true;
    // ***** Instance Variables
    protected boolean mDestroyed = false; // set to true once this object needs to be disposed of
    protected AtomicBoolean mDestroyed = new AtomicBoolean(false);
    protected Context mContext;
    protected CommandsInterface mCi;
    protected IccFileHandler mFh;
@@ -79,9 +81,9 @@ public abstract class IccRecords extends Handler implements IccConstants {

    // ***** Event Constants
    protected static final int EVENT_SET_MSISDN_DONE = 30;
    public static final int EVENT_MWI = 0;
    public static final int EVENT_CFI = 1;
    public static final int EVENT_SPN = 2;
    public static final int EVENT_MWI = 0; // Message Waiting indication
    public static final int EVENT_CFI = 1; // Call Forwarding indication
    public static final int EVENT_SPN = 2; // Service Provider Name

    public static final int EVENT_GET_ICC_RECORD_DONE = 100;

@@ -113,7 +115,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
     * Call when the IccRecords object is no longer going to be used.
     */
    public void dispose() {
        mDestroyed = true;
        mDestroyed.set(true);
        mParentCard = null;
        mFh = null;
        mCi = null;
@@ -128,12 +130,8 @@ public abstract class IccRecords extends Handler implements IccConstants {
        return adnCache;
    }

    public IccCard getIccCard() {
        return mParentCard;
    }

    public void registerForRecordsLoaded(Handler h, int what, Object obj) {
        if (mDestroyed) {
        if (mDestroyed.get()) {
            return;
        }

+30 −8
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.internal.R;
import com.android.internal.telephony.gsm.UsimServiceTable;
import com.android.internal.telephony.ims.IsimRecords;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.gsm.SIMRecords;

import java.io.FileDescriptor;
@@ -110,6 +111,7 @@ public abstract class PhoneBase extends Handler implements Phone {
    protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
    protected static final int EVENT_NEW_ICC_SMS                    = 29;
    protected static final int EVENT_ICC_RECORD_EVENTS              = 30;
    protected static final int EVENT_ICC_CHANGED                    = 31;

    // Key used to read/write current CLIR setting
    public static final String CLIR_KEY = "clir_key";
@@ -126,7 +128,8 @@ public abstract class PhoneBase extends Handler implements Phone {
    int mCallRingDelay;
    public boolean mIsTheCurrentActivePhone = true;
    boolean mIsVoiceCapable = true;
    public IccRecords mIccRecords;
    protected UiccController mUiccController = null;
    public AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
    protected AtomicReference<IccCard> mIccCard = new AtomicReference<IccCard>();
    public SmsStorageMonitor mSmsStorageMonitor;
    public SmsUsageMonitor mSmsUsageMonitor;
@@ -251,6 +254,8 @@ public abstract class PhoneBase extends Handler implements Phone {
        // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
        mSmsStorageMonitor = new SmsStorageMonitor(this);
        mSmsUsageMonitor = new SmsUsageMonitor(context);
        mUiccController = UiccController.getInstance(this);
        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
    }

    public void dispose() {
@@ -262,6 +267,7 @@ public abstract class PhoneBase extends Handler implements Phone {
            // Dispose the SMS usage and storage monitors
            mSmsStorageMonitor.dispose();
            mSmsUsageMonitor.dispose();
            mUiccController.unregisterForIccChanged(this);
        }
    }

@@ -269,9 +275,10 @@ public abstract class PhoneBase extends Handler implements Phone {
        mSmsStorageMonitor = null;
        mSmsUsageMonitor = null;
        mSMS = null;
        mIccRecords = null;
        mIccRecords.set(null);
        mIccCard.set(null);
        mDataConnectionTracker = null;
        mUiccController = null;
    }

    /**
@@ -308,6 +315,10 @@ public abstract class PhoneBase extends Handler implements Phone {
                }
                break;

            case EVENT_ICC_CHANGED:
                onUpdateIccAvailability();
                break;

            default:
                throw new RuntimeException("unexpected event not handled");
        }
@@ -318,6 +329,9 @@ public abstract class PhoneBase extends Handler implements Phone {
        return mContext;
    }

    // Will be called when icc changed
    protected abstract void onUpdateIccAvailability();

    /**
     * Disables the DNS check (i.e., allows "0.0.0.0").
     * Useful for lab testing environment.
@@ -666,22 +680,26 @@ public abstract class PhoneBase extends Handler implements Phone {

    @Override
    public String getIccSerialNumber() {
        return mIccRecords.iccid;
        IccRecords r = mIccRecords.get();
        return (r != null) ? r.iccid : "";
    }

    @Override
    public boolean getIccRecordsLoaded() {
        return mIccRecords.getRecordsLoaded();
        IccRecords r = mIccRecords.get();
        return (r != null) ? r.getRecordsLoaded() : false;
    }

    @Override
    public boolean getMessageWaitingIndicator() {
        return mIccRecords.getVoiceMessageWaiting();
        IccRecords r = mIccRecords.get();
        return (r != null) ? r.getVoiceMessageWaiting() : false;
    }

    @Override
    public boolean getCallForwardingIndicator() {
        return mIccRecords.getVoiceCallForwardingFlag();
        IccRecords r = mIccRecords.get();
        return (r != null) ? r.getVoiceCallForwardingFlag() : false;
    }

    /**
@@ -1135,7 +1153,10 @@ public abstract class PhoneBase extends Handler implements Phone {
     */
    @Override
    public void setVoiceMessageWaiting(int line, int countWaiting) {
        mIccRecords.setVoiceMessageWaiting(line, countWaiting);
        IccRecords r = mIccRecords.get();
        if (r != null) {
            r.setVoiceMessageWaiting(line, countWaiting);
        }
    }

    /**
@@ -1144,7 +1165,8 @@ public abstract class PhoneBase extends Handler implements Phone {
     */
    @Override
    public UsimServiceTable getUsimServiceTable() {
        return mIccRecords.getUsimServiceTable();
        IccRecords r = mIccRecords.get();
        return (r != null) ? r.getUsimServiceTable() : null;
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Loading