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

Commit 54dbe329 authored by Jordan Liu's avatar Jordan Liu Committed by android-build-merger
Browse files

Merge "Add cardIds" am: be4d2cd2 am: 74d2ae88

am: e5116d73

Change-Id: Iac93546fda5367bef733e8035d8a9366a876a57c
parents 289d995c e5116d73
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");