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

Commit f965bc9f authored by Sandeep Gutta's avatar Sandeep Gutta
Browse files

Clean up Icc Refresh handling

1. When a SIM refresh is received of type INIT,
don't immediately start re-fetching the records, because
the app might not be ready. In this case, we could end up
broadcasting that all records are loaded pre-maturely.

On a refresh of the above type, the app will move out of the
ready state and back into the PIN state, if PIN is enabled.
Start reading the records only after the PIN has been verified
and the app has moved to the READY state.

2. When UiccController receives refresh of type INIT, it will
propagate it to the Card. The card will dispose the apps if required.
UiccController will also request card status on receiving
refresh to get the latest state.

This avoids having to make assumptions on the ordering of the
Unsols for Sim Refresh and card state changes. This also
ensures that after a refresh, the app state will move to ready
when it is truly ready.

3. Moved common implementation for refresh into IccRecords
for better code reuse.

Test: runtest -path frameworks/opt/telephony/tests/telephonytests/
Test: Manual SIM refresh related cases
Bug: 35919855
Change-Id: Ib4149c94adc7845bfe8d07dacec6ff78a6b64c1e
parent 19a3b32b
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -2192,4 +2192,16 @@ public class SimulatedCommands extends BaseCommands
    public void setRadioPowerFailResponse(boolean fail) {
        mIsRadioPowerFailResponse = fail;
    }

    @Override
    public void registerForIccRefresh(Handler h, int what, Object obj) {
        super.registerForIccRefresh(h, what, obj);
        SimulatedCommandsVerifier.getInstance().registerForIccRefresh(h, what, obj);
    }

    @Override
    public void unregisterForIccRefresh(Handler h) {
        super.unregisterForIccRefresh(h);
        SimulatedCommandsVerifier.getInstance().unregisterForIccRefresh(h);
    }
}
+42 −15
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
    public static final int EVENT_SPN = 2; // Service Provider Name

    public static final int EVENT_GET_ICC_RECORD_DONE = 100;
    public static final int EVENT_REFRESH = 31; // ICC refresh occurred
    protected static final int EVENT_APP_READY = 1;
    private static final int EVENT_AKA_AUTHENTICATE_DONE          = 90;

@@ -219,6 +220,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
            mFakePnnHomeName = mCarrierTestOverride.getFakePnnHomeName();
            log("load mFakePnnHomeName: " + mFakePnnHomeName);
        }
        mCi.registerForIccRefresh(this, EVENT_REFRESH, null);
    }

    /**
@@ -234,10 +236,14 @@ public abstract class IccRecords extends Handler implements IccConstants {
            mLock.notifyAll();
        }

        mCi.unregisterForIccRefresh(this);
        mParentApp = null;
        mFh = null;
        mCi = null;
        mContext = null;
        if (mAdnCache != null) {
            mAdnCache.reset();
        }
    }

    public abstract void onReady();
@@ -571,21 +577,6 @@ public abstract class IccRecords extends Handler implements IccConstants {
     */
    public abstract void onRefresh(boolean fileChanged, int[] fileList);

    /**
     * Called by subclasses (SimRecords and RuimRecords) whenever
     * IccRefreshResponse.REFRESH_RESULT_INIT event received
     */
    protected void onIccRefreshInit() {
        mAdnCache.reset();
        mMncLength = UNINITIALIZED;
        UiccCardApplication parentApp = mParentApp;
        if ((parentApp != null) &&
                (parentApp.getState() == AppState.APPSTATE_READY)) {
            // This will cause files to be reread
            sendMessage(obtainMessage(EVENT_APP_READY));
        }
    }

    public boolean getRecordsLoaded() {
        return mRecordsToLoad == 0 && mRecordsRequested;
    }
@@ -620,6 +611,16 @@ public abstract class IccRecords extends Handler implements IccConstants {
                }
                break;

            case EVENT_REFRESH:
                ar = (AsyncResult)msg.obj;
                if (DBG) log("Card REFRESH occurred: ");
                if (ar.exception == null) {
                    handleRefresh((IccRefreshResponse)ar.result);
                } else {
                    loge("Icc refresh Exception: " + ar.exception);
                }
                break;

            case EVENT_AKA_AUTHENTICATE_DONE:
                ar = (AsyncResult)msg.obj;
                auth_rsp = null;
@@ -688,6 +689,32 @@ public abstract class IccRecords extends Handler implements IccConstants {
        return null;
    }

    protected abstract void handleFileUpdate(int efid);

    protected void handleRefresh(IccRefreshResponse refreshResponse){
        if (refreshResponse == null) {
            if (DBG) log("handleRefresh received without input");
            return;
        }

        if (!TextUtils.isEmpty(refreshResponse.aid) &&
                !refreshResponse.aid.equals(mParentApp.getAid())) {
            // This is for different app. Ignore.
            return;
        }

        switch (refreshResponse.refreshResult) {
            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
                if (DBG) log("handleRefresh with SIM_FILE_UPDATED");
                handleFileUpdate(refreshResponse.efId);
                break;
            default:
                // unknown refresh operation
                if (DBG) log("handleRefresh with unknown operation");
                break;
        }
    }

    protected abstract void onRecordLoaded();

    protected abstract void onAllRecordsLoaded();
+9 −48
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
    public static final String INTENT_ISIM_REFRESH = "com.android.intent.isim_refresh";

    private static final int EVENT_APP_READY = 1;
    private static final int EVENT_ISIM_REFRESH = 31;
    private static final int EVENT_ISIM_AUTHENTICATE_DONE          = 91;

    // ISIM EF records (see 3GPP TS 31.103)
@@ -90,7 +89,6 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
        mRecordsToLoad = 0;
        // Start off by setting empty state
        resetRecords();
        mCi.registerForIccRefresh(this, EVENT_ISIM_REFRESH, null);

        mParentApp.registerForReady(this, EVENT_APP_READY, null);
        if (DBG) log("IsimUiccRecords X ctor this=" + this);
@@ -123,15 +121,9 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
                    onReady();
                    break;

                case EVENT_ISIM_REFRESH:
                    ar = (AsyncResult)msg.obj;
                    loge("ISim REFRESH(EVENT_ISIM_REFRESH) with exception: " + ar.exception);
                    if (ar.exception == null) {
                        Intent intent = new Intent(INTENT_ISIM_REFRESH);
                        loge("send ISim REFRESH: " + INTENT_ISIM_REFRESH);
                        mContext.sendBroadcast(intent);
                        handleIsimRefresh((IccRefreshResponse)ar.result);
                    }
                case EVENT_REFRESH:
                    broadcastRefresh();
                    super.handleMessage(msg);
                    break;

                case EVENT_ISIM_AUTHENTICATE_DONE:
@@ -316,7 +308,8 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
        mRecordsLoadedRegistrants.notifyRegistrants(new AsyncResult(null, null, null));
    }

    private void handleFileUpdate(int efid) {
    @Override
    protected void handleFileUpdate(int efid) {
        switch (efid) {
            case EF_IMPI:
                mFh.loadEFTransparent(EF_IMPI, obtainMessage(
@@ -353,42 +346,10 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
        }
    }

    private void handleIsimRefresh(IccRefreshResponse refreshResponse) {
        if (refreshResponse == null) {
            if (DBG) log("handleIsimRefresh received without input");
            return;
        }

        if (!TextUtils.isEmpty(refreshResponse.aid)
                && !refreshResponse.aid.equals(mParentApp.getAid())) {
            // This is for different app. Ignore.
            if (DBG) log("handleIsimRefresh received different app");
            return;
        }

        switch (refreshResponse.refreshResult) {
            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
                if (DBG) log("handleIsimRefresh with REFRESH_RESULT_FILE_UPDATE");
                handleFileUpdate(refreshResponse.efId);
                break;

            case IccRefreshResponse.REFRESH_RESULT_INIT:
                if (DBG) log("handleIsimRefresh with REFRESH_RESULT_INIT");
                // need to reload all files (that we care about)
                // onIccRefreshInit();
                fetchIsimRecords();
                break;

            case IccRefreshResponse.REFRESH_RESULT_RESET:
                // Refresh reset is handled by the UiccCard object.
                if (DBG) log("handleIsimRefresh with REFRESH_RESULT_RESET");
                break;

            default:
                // unknown refresh operation
                if (DBG) log("handleIsimRefresh with unknown operation");
                break;
        }
    private void broadcastRefresh() {
        Intent intent = new Intent(INTENT_ISIM_REFRESH);
        log("send ISim REFRESH: " + INTENT_ISIM_REFRESH);
        mContext.sendBroadcast(intent);
    }

    /**
+4 −43
Original line number Diff line number Diff line
@@ -97,7 +97,6 @@ public class RuimRecords extends IccRecords {
    private static final int EVENT_SMS_ON_RUIM = 21;
    private static final int EVENT_GET_SMS_DONE = 22;

    private static final int EVENT_RUIM_REFRESH = 31;
    private static final int EVENT_APP_LOCKED = 32;

    public RuimRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
@@ -112,7 +111,6 @@ public class RuimRecords extends IccRecords {
        mRecordsToLoad = 0;

        // NOTE the EVENT_SMS_ON_RUIM is not registered
        mCi.registerForIccRefresh(this, EVENT_RUIM_REFRESH, null);

        // Start off by setting empty state
        resetRecords();
@@ -126,7 +124,6 @@ public class RuimRecords extends IccRecords {
    public void dispose() {
        if (DBG) log("Disposing RuimRecords " + this);
        //Unregister for all events
        mCi.unregisterForIccRefresh(this);
        mParentApp.unregisterForReady(this);
        resetRecords();
        super.dispose();
@@ -703,14 +700,6 @@ public class RuimRecords extends IccRecords {
                log("Event EVENT_GET_SST_DONE Received");
            break;

            case EVENT_RUIM_REFRESH:
                isRecordLoadResponse = false;
                ar = (AsyncResult)msg.obj;
                if (ar.exception == null) {
                    handleRuimRefresh((IccRefreshResponse)ar.result);
                }
                break;

            default:
                super.handleMessage(msg);   // IccRecords handles generic record load responses

@@ -933,38 +922,10 @@ public class RuimRecords extends IccRecords {
        return 0;
    }

    private void handleRuimRefresh(IccRefreshResponse refreshResponse) {
        if (refreshResponse == null) {
            if (DBG) log("handleRuimRefresh received without input");
            return;
        }

        if (!TextUtils.isEmpty(refreshResponse.aid)
                && !refreshResponse.aid.equals(mParentApp.getAid())) {
            // This is for different app. Ignore.
            return;
        }

        switch (refreshResponse.refreshResult) {
            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
                if (DBG) log("handleRuimRefresh with SIM_REFRESH_FILE_UPDATED");
    @Override
    protected void handleFileUpdate(int efid) {
        mAdnCache.reset();
        fetchRuimRecords();
                break;
            case IccRefreshResponse.REFRESH_RESULT_INIT:
                if (DBG) log("handleRuimRefresh with SIM_REFRESH_INIT");
                // need to reload all files (that we care about)
                onIccRefreshInit();
                break;
            case IccRefreshResponse.REFRESH_RESULT_RESET:
                // Refresh reset is handled by the UiccCard object.
                if (DBG) log("handleRuimRefresh with SIM_REFRESH_RESET");
                break;
            default:
                // unknown refresh operation
                if (DBG) log("handleRuimRefresh with unknown operation");
                break;
        }
    }

    public String getMdn() {
+3 −45
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ public class SIMRecords extends IccRecords {
    private static final int SYSTEM_EVENT_BASE = 0x100;
    private static final int EVENT_CARRIER_CONFIG_CHANGED = 1 + SYSTEM_EVENT_BASE;
    private static final int EVENT_APP_LOCKED = 2 + SYSTEM_EVENT_BASE;
    private static final int EVENT_SIM_REFRESH = 3 + SYSTEM_EVENT_BASE;


    // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.

@@ -217,7 +217,6 @@ public class SIMRecords extends IccRecords {
        mRecordsToLoad = 0;

        mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
        mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH, null);

        // Start off by setting empty state
        resetRecords();
@@ -243,7 +242,6 @@ public class SIMRecords extends IccRecords {
    public void dispose() {
        if (DBG) log("Disposing SIMRecords this=" + this);
        //Unregister for all events
        mCi.unregisterForIccRefresh(this);
        mCi.unSetOnSmsOnSim(this);
        mParentApp.unregisterForReady(this);
        mParentApp.unregisterForLocked(this);
@@ -1213,14 +1211,6 @@ public class SIMRecords extends IccRecords {
                        ((Message) ar.userObj).sendToTarget();
                    }
                    break;
                case EVENT_SIM_REFRESH:
                    isRecordLoadResponse = false;
                    ar = (AsyncResult) msg.obj;
                    if (DBG) log("Sim REFRESH with exception: " + ar.exception);
                    if (ar.exception == null) {
                        handleSimRefresh((IccRefreshResponse) ar.result);
                    }
                    break;
                case EVENT_GET_CFIS_DONE:
                    isRecordLoadResponse = true;

@@ -1410,7 +1400,8 @@ public class SIMRecords extends IccRecords {
        }
    }

    private void handleFileUpdate(int efid) {
    @Override
    protected void handleFileUpdate(int efid) {
        switch(efid) {
            case EF_MBDN:
                mRecordsToLoad++;
@@ -1454,39 +1445,6 @@ public class SIMRecords extends IccRecords {
        }
    }

    private void handleSimRefresh(IccRefreshResponse refreshResponse){
        if (refreshResponse == null) {
            if (DBG) log("handleSimRefresh received without input");
            return;
        }

        if (!TextUtils.isEmpty(refreshResponse.aid)
                && !refreshResponse.aid.equals(mParentApp.getAid())) {
            // This is for different app. Ignore.
            return;
        }

        switch (refreshResponse.refreshResult) {
            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
                if (DBG) log("handleSimRefresh with SIM_FILE_UPDATED");
                handleFileUpdate(refreshResponse.efId);
                break;
            case IccRefreshResponse.REFRESH_RESULT_INIT:
                if (DBG) log("handleSimRefresh with SIM_REFRESH_INIT");
                // need to reload all files (that we care about)
                onIccRefreshInit();
                break;
            case IccRefreshResponse.REFRESH_RESULT_RESET:
                // Refresh reset is handled by the UiccCard object.
                if (DBG) log("handleSimRefresh with SIM_REFRESH_RESET");
                break;
            default:
                // unknown refresh operation
                if (DBG) log("handleSimRefresh with unknown operation");
                break;
        }
    }

    /**
     * Dispatch 3GPP format message to registrant ({@code GsmCdmaPhone}) to pass to the 3GPP SMS
     * dispatcher for delivery.
Loading