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

Commit be4d2cd2 authored by Jordan Liu's avatar Jordan Liu Committed by Gerrit Code Review
Browse files

Merge "Add cardIds"

parents fd3fcf65 7d137b50
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -121,8 +121,12 @@ public class IccCardStatus {

        StringBuilder sb = new StringBuilder();
        sb.append("IccCardState {").append(mCardState).append(",")
        .append(mUniversalPinState)
        .append(",num_apps=").append(mApplications.length);
        .append(mUniversalPinState);
        if (mApplications != null) {
            sb.append(",num_apps=").append(mApplications.length);
        } else {
            sb.append(",mApplications=null");
        }

        sb.append(",gsm_id=").append(mGsmUmtsSubscriptionAppIndex);
        if (mApplications != null
+66 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.telephony.uicc;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.AsyncResult;
import android.os.Handler;
@@ -25,11 +26,14 @@ import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.storage.StorageManager;
import android.preference.PreferenceManager;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.LocalLog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCardConstants;
@@ -37,6 +41,7 @@ import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.RadioConfig;
import com.android.internal.telephony.SubscriptionInfoUpdater;
import com.android.internal.telephony.uicc.IccCardStatus.CardState;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -112,15 +117,26 @@ public class UiccController extends Handler {

    // this needs to be here, because on bootup we dont know which index maps to which UiccSlot
    private CommandsInterface[] mCis;
    private UiccSlot[] mUiccSlots;
    @VisibleForTesting
    public UiccSlot[] mUiccSlots;
    private int[] mPhoneIdToSlotId;
    private boolean mIsSlotStatusSupported = true;

    // This maps the externally exposed card ID (int) to the internal card ID string (ICCID/EID).
    // The array index is the card ID (int).
    // This mapping exists to expose card-based functionality without exposing the EID, which is
    // considered sensetive information.
    private ArrayList<String> mCardStrings;

    // SharedPreference key for saving the known card strings (ICCIDs and EIDs) ordered by card ID
    private static final String CARD_STRINGS = "card_strings";

    private static final Object mLock = new Object();
    private static UiccController mInstance;
    private static ArrayList<IccSlotStatus> sLastSlotStatus;

    private Context mContext;
    @VisibleForTesting
    public Context mContext;

    protected RegistrantList mIccChangedRegistrants = new RegistrantList();

@@ -182,6 +198,7 @@ public class UiccController extends Handler {
        }

        mLauncher = new UiccStateChangedLauncher(c, this);
        mCardStrings = loadCardStrings();
    }

    private int getSlotIdFromPhoneId(int phoneId) {
@@ -530,10 +547,52 @@ public class UiccController extends Handler {

        mUiccSlots[slotId].update(mCis[index], status, index);

        UiccCard card = mUiccSlots[slotId].getUiccCard();
        if (card != null && (card.getCardState() == CardState.CARDSTATE_PRESENT)) {
            // Card.getCardId returns the cardString, not the public card ID int
            String cardString = card.getCardId();
            addCardId(cardString);
        }

        if (DBG) log("Notifying IccChangedRegistrants");
        mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null));
    }

    private void addCardId(String cardString) {
        if (TextUtils.isEmpty(cardString)) {
            return;
        }
        if (!mCardStrings.contains(cardString)) {
            mCardStrings.add(cardString);
            saveCardStrings();
        }
    }

    /**
     * Converts the card string (the ICCID/EID, formerly named card ID) to the public int cardId.
     * Returns -1 if the card string does not map to a cardId.
     */
    public int convertToPublicCardId(String cardString) {
        return mCardStrings.indexOf(cardString);
    }

    private ArrayList<String> loadCardStrings() {
        String cardStrings =
                PreferenceManager.getDefaultSharedPreferences(mContext).getString(CARD_STRINGS, "");
        if (TextUtils.isEmpty(cardStrings)) {
            // just return an empty list, since String.split would return the list { "" }
            return new ArrayList<String>();
        }
        return new ArrayList<String>(Arrays.asList(cardStrings.split(",")));
    }

    private void saveCardStrings() {
        SharedPreferences.Editor editor =
                PreferenceManager.getDefaultSharedPreferences(mContext).edit();
        editor.putString(CARD_STRINGS, TextUtils.join(",", mCardStrings));
        editor.commit();
    }

    private synchronized void onGetSlotStatusDone(AsyncResult ar) {
        if (!mIsSlotStatusSupported) {
            if (VDBG) log("onGetSlotStatusDone: ignoring since mIsSlotStatusSupported is false");
@@ -592,6 +651,11 @@ public class UiccController extends Handler {
            }

            mUiccSlots[i].update(isActive ? mCis[iss.logicalSlotIndex] : null, iss);

            if (mUiccSlots[i].isEuicc()) {
                String eid = iss.eid;
                addCardId(eid);
            }
        }

        if (VDBG) logPhoneIdToSlotIdMapping();
+61 −2
Original line number Diff line number Diff line
@@ -26,9 +26,11 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.os.AsyncResult;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.telephony.TelephonyManager;

@@ -41,15 +43,23 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;

import java.util.ArrayList;

public class UiccControllerTest extends TelephonyTest {
    private UiccController mUiccControllerUT;
    private UiccControllerHandlerThread mUiccControllerHandlerThread;
    private static final int PHONE_COUNT = 1;
    private static int ICC_CHANGED_EVENT = 0;
    private static final int ICC_CHANGED_EVENT = 0;
    private static final int EVENT_GET_ICC_STATUS_DONE = 3;
    private static final int EVENT_GET_SLOT_STATUS_DONE = 4;
    @Mock
    private Handler mMockedHandler;
    @Mock
    private IccCardStatus mIccCardStatus;
    @Mock
    private UiccSlot mMockSlot;
    @Mock
    private UiccCard mMockCard;

    private class UiccControllerHandlerThread extends HandlerThread {

@@ -200,4 +210,53 @@ public class UiccControllerTest extends TelephonyTest {
                mCaptorLong.capture());
        assertEquals(ICC_CHANGED_EVENT, mCaptorMessage.getValue().what);
    }

    @Test
    public void testCardIdFromIccStatus() {
        // Give UiccController a real context so it can use shared preferences
        mUiccControllerUT.mContext = InstrumentationRegistry.getContext();

        // Mock out UiccSlots
        mUiccControllerUT.mUiccSlots[0] = mMockSlot;
        doReturn(mMockCard).when(mMockSlot).getUiccCard();
        doReturn("A1B2C3D4").when(mMockCard).getCardId();
        doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mMockCard).getCardState();

        // simulate card status loaded
        IccCardStatus ics = new IccCardStatus();
        ics.setCardState(1 /* present */);
        ics.setUniversalPinState(3 /* disabled */);
        ics.atr = "abcdef0123456789abcdef";
        ics.iccid = "123451234567890";
        ics.eid = "A1B2C3D4";
        AsyncResult ar = new AsyncResult(null, ics, null);
        Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
        mUiccControllerUT.handleMessage(msg);

        // assert that the card ID was created
        assertEquals(0, mUiccControllerUT.convertToPublicCardId(ics.eid));
    }

    @Test
    public void testCardIdFromSlotStatus() {
        // Give UiccController a real context so it can use shared preferences
        mUiccControllerUT.mContext = InstrumentationRegistry.getContext();

        // Mock out UiccSlots
        mUiccControllerUT.mUiccSlots[0] = mMockSlot;
        doReturn(true).when(mMockSlot).isEuicc();

        // simulate slot status loaded
        IccSlotStatus iss = new IccSlotStatus();
        iss.setSlotState(1 /* active */);
        iss.eid = "ABADACB";
        ArrayList<IccSlotStatus> status = new ArrayList<IccSlotStatus>();
        status.add(iss);
        AsyncResult ar = new AsyncResult(null, status, null);
        Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_SLOT_STATUS_DONE, ar);
        mUiccControllerUT.handleMessage(msg);

        // assert that the card ID was created
        assertEquals(0, mUiccControllerUT.convertToPublicCardId(iss.eid));
    }
}
+22 −0
Original line number Diff line number Diff line
@@ -165,6 +165,28 @@ public class EuiccCardTest extends TelephonyTest {
        }
    }

    @Test
    public void testPassEidInContructor() throws InterruptedException {
        mMockIccCardStatus.eid = "1A2B3C4D";
        mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi,
                mMockIccCardStatus, 0 /* phoneId */, new Object());

        final int eventEidReady = 0;
        final CountDownLatch latch = new CountDownLatch(1);
        Handler handler = new Handler(mTestHandlerThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == eventEidReady) {
                    assertEquals("1A2B3C4D", mEuiccCard.getEid());
                    latch.countDown();
                }
            }
        };
        // This will instantly return, since EID is already set
        mEuiccCard.registerForEidReady(handler, eventEidReady, null /* obj */);
        assertTrue(latch.await(WAIT_TIMEOUT_MLLIS, TimeUnit.MILLISECONDS));
    }

    @Test
    public void testLoadEidAndNotifyRegistrants() throws InterruptedException {
        int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000");