Loading src/java/com/android/internal/telephony/uicc/UiccProfile.java +19 −2 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import com.android.internal.telephony.cat.CatService; import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; import com.android.internal.telephony.uicc.IccCardStatus.CardState; import com.android.internal.telephony.uicc.IccCardStatus.PinState; import com.android.internal.telephony.uicc.euicc.EuiccCard; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -122,6 +123,7 @@ public class UiccProfile extends Handler implements IccCard { private static final int EVENT_APP_READY = 6; private static final int EVENT_RECORDS_LOADED = 7; private static final int EVENT_NETWORK_LOCKED = 9; private static final int EVENT_EID_READY = 10; private static final int EVENT_ICC_RECORD_EVENTS = 500; Loading Loading @@ -152,6 +154,11 @@ public class UiccProfile extends Handler implements IccCard { setCurrentAppType(phone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM); } } if (mUiccCard instanceof EuiccCard) { ((EuiccCard) mUiccCard).registerForEidReady(this, EVENT_EID_READY, null); } update(c, ci, ics); if (ICC_CARD_PROXY_REMOVED) { Loading @@ -171,6 +178,10 @@ public class UiccProfile extends Handler implements IccCard { unregisterAllAppEvents(); unregisterCurrAppEvents(); if (mUiccCard instanceof EuiccCard) { ((EuiccCard) mUiccCard).unregisterForEidReady(this); } if (ICC_CARD_PROXY_REMOVED) { mCi.unregisterForOffOrNotAvailable(this); } Loading Loading @@ -229,6 +240,7 @@ public class UiccProfile extends Handler implements IccCard { case EVENT_ICC_LOCKED: case EVENT_APP_READY: case EVENT_RECORDS_LOADED: case EVENT_EID_READY: if (VDBG) log("handleMessage: Received " + msg.what); updateExternalState(); break; Loading Loading @@ -316,6 +328,11 @@ public class UiccProfile extends Handler implements IccCard { return; } if (mUiccCard instanceof EuiccCard && ((EuiccCard) mUiccCard).getEid() == null) { if (DBG) log("EID is not ready yet."); return; } // By process of elimination, the UICC Card State = PRESENT and state needs to be decided // based on apps if (mUiccApplication == null) { Loading src/java/com/android/internal/telephony/uicc/UiccSlot.java +2 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.CommandsInterface.RadioState; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.uicc.IccCardStatus.CardState; import com.android.internal.telephony.uicc.euicc.EuiccCard; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -119,8 +120,7 @@ public class UiccSlot extends Handler { if (!mIsEuicc) { mUiccCard = new UiccCard(mContext, mCi, ics, mPhoneId); } else { // todo: initialize new EuiccCard object here //mUiccCard = new EuiccCard(); mUiccCard = new EuiccCard(mContext, mCi, ics, phoneId); } } else { if (mUiccCard != null) { Loading src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java +55 −2 Original line number Diff line number Diff line Loading @@ -18,7 +18,10 @@ package com.android.internal.telephony.uicc.euicc; import android.annotation.Nullable; import android.content.Context; import android.os.AsyncResult; import android.os.Handler; import android.os.Registrant; import android.os.RegistrantList; import android.service.carrier.CarrierIdentifier; import android.service.euicc.EuiccProfileInfo; import android.telephony.Rlog; Loading Loading @@ -97,13 +100,54 @@ public class EuiccCard extends UiccCard { private final ApduSender mApduSender; private final Object mLock = new Object(); private final RegistrantList mEidReadyRegistrants = new RegistrantList(); private EuiccSpecVersion mSpecVersion; private String mEid; private volatile String mEid; public EuiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) { super(c, ci, ics, phoneId); // TODO: Set supportExtendedApdu based on ATR. mApduSender = new ApduSender(ci, ISD_R_AID, false /* supportExtendedApdu */); loadEidAndNotifyRegistrants(); } /** * Registers to be notified when EID is ready. If the EID is ready when this method is called, * the registrant will be notified immediately. */ public void registerForEidReady(Handler h, int what, Object obj) { Registrant r = new Registrant(h, what, obj); if (mEid != null) { r.notifyRegistrant(new AsyncResult(null, null, null)); } else { mEidReadyRegistrants.add(r); } } /** * Unregisters to be notified when EID is ready. */ public void unregisterForEidReady(Handler h) { mEidReadyRegistrants.remove(h); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected void loadEidAndNotifyRegistrants() { Handler euiccMainThreadHandler = new Handler(); AsyncResultCallback<String> cardCb = new AsyncResultCallback<String>() { @Override public void onResult(String result) { mEidReadyRegistrants.notifyRegistrants(new AsyncResult(null, null, null)); } @Override public void onException(Throwable e) { // Not notifying registrants if getting eid fails. Rlog.e(LOG_TAG, "Failed loading eid", e); } }; getEid(cardCb, euiccMainThreadHandler); } /** Loading Loading @@ -263,7 +307,15 @@ public class EuiccCard extends UiccCard { } /** * Gets the EID of the eUICC. * Gets the EID synchronously. * @return The EID string. Returns null if it is not ready yet. */ public String getEid() { return mEid; } /** * Gets the EID of the eUICC and overwrites mCardId in UiccCard. * * @param callback The callback to get the result. * @param handler The handler to run the callback. Loading @@ -284,6 +336,7 @@ public class EuiccCard extends UiccCard { .getChild(Tags.TAG_EID).asBytes()); synchronized (mLock) { mEid = eid; mCardId = eid; } return eid; }, Loading tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java +36 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static org.mockito.Mockito.verify; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.service.carrier.CarrierIdentifier; import android.service.euicc.EuiccProfileInfo; import android.telephony.UiccAccessRule; Loading Loading @@ -102,6 +103,9 @@ public class EuiccCardTest extends TelephonyTest { protected byte[] getDeviceId() { return IccUtils.bcdToBytes("987654321012345"); } @Override protected void loadEidAndNotifyRegistrants() {} }; mHandler = new Handler(mTestHandlerThread.getLooper()); setReady(true); Loading Loading @@ -147,6 +151,38 @@ public class EuiccCardTest extends TelephonyTest { } } @Test public void testLoadEidAndNotifyRegistrants() throws InterruptedException { int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000"); { final CountDownLatch latch = new CountDownLatch(1); mHandler.post(() -> { mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi, mMockIccCardStatus, 0 /* phoneId */); latch.countDown(); }); assertTrue(latch.await(WAIT_TIMEOUT_MLLIS, TimeUnit.MILLISECONDS)); } 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(); } } }; mEuiccCard.registerForEidReady(handler, eventEidReady, null /* obj */); assertTrue(latch.await(WAIT_TIMEOUT_MLLIS, TimeUnit.MILLISECONDS)); verifyStoreData(channel, "BF3E035C015A"); } @Test public void testGetAllProfiles() { int channel = mockLogicalChannelResponses( Loading Loading
src/java/com/android/internal/telephony/uicc/UiccProfile.java +19 −2 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import com.android.internal.telephony.cat.CatService; import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; import com.android.internal.telephony.uicc.IccCardStatus.CardState; import com.android.internal.telephony.uicc.IccCardStatus.PinState; import com.android.internal.telephony.uicc.euicc.EuiccCard; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -122,6 +123,7 @@ public class UiccProfile extends Handler implements IccCard { private static final int EVENT_APP_READY = 6; private static final int EVENT_RECORDS_LOADED = 7; private static final int EVENT_NETWORK_LOCKED = 9; private static final int EVENT_EID_READY = 10; private static final int EVENT_ICC_RECORD_EVENTS = 500; Loading Loading @@ -152,6 +154,11 @@ public class UiccProfile extends Handler implements IccCard { setCurrentAppType(phone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM); } } if (mUiccCard instanceof EuiccCard) { ((EuiccCard) mUiccCard).registerForEidReady(this, EVENT_EID_READY, null); } update(c, ci, ics); if (ICC_CARD_PROXY_REMOVED) { Loading @@ -171,6 +178,10 @@ public class UiccProfile extends Handler implements IccCard { unregisterAllAppEvents(); unregisterCurrAppEvents(); if (mUiccCard instanceof EuiccCard) { ((EuiccCard) mUiccCard).unregisterForEidReady(this); } if (ICC_CARD_PROXY_REMOVED) { mCi.unregisterForOffOrNotAvailable(this); } Loading Loading @@ -229,6 +240,7 @@ public class UiccProfile extends Handler implements IccCard { case EVENT_ICC_LOCKED: case EVENT_APP_READY: case EVENT_RECORDS_LOADED: case EVENT_EID_READY: if (VDBG) log("handleMessage: Received " + msg.what); updateExternalState(); break; Loading Loading @@ -316,6 +328,11 @@ public class UiccProfile extends Handler implements IccCard { return; } if (mUiccCard instanceof EuiccCard && ((EuiccCard) mUiccCard).getEid() == null) { if (DBG) log("EID is not ready yet."); return; } // By process of elimination, the UICC Card State = PRESENT and state needs to be decided // based on apps if (mUiccApplication == null) { Loading
src/java/com/android/internal/telephony/uicc/UiccSlot.java +2 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.CommandsInterface.RadioState; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.uicc.IccCardStatus.CardState; import com.android.internal.telephony.uicc.euicc.EuiccCard; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -119,8 +120,7 @@ public class UiccSlot extends Handler { if (!mIsEuicc) { mUiccCard = new UiccCard(mContext, mCi, ics, mPhoneId); } else { // todo: initialize new EuiccCard object here //mUiccCard = new EuiccCard(); mUiccCard = new EuiccCard(mContext, mCi, ics, phoneId); } } else { if (mUiccCard != null) { Loading
src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java +55 −2 Original line number Diff line number Diff line Loading @@ -18,7 +18,10 @@ package com.android.internal.telephony.uicc.euicc; import android.annotation.Nullable; import android.content.Context; import android.os.AsyncResult; import android.os.Handler; import android.os.Registrant; import android.os.RegistrantList; import android.service.carrier.CarrierIdentifier; import android.service.euicc.EuiccProfileInfo; import android.telephony.Rlog; Loading Loading @@ -97,13 +100,54 @@ public class EuiccCard extends UiccCard { private final ApduSender mApduSender; private final Object mLock = new Object(); private final RegistrantList mEidReadyRegistrants = new RegistrantList(); private EuiccSpecVersion mSpecVersion; private String mEid; private volatile String mEid; public EuiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) { super(c, ci, ics, phoneId); // TODO: Set supportExtendedApdu based on ATR. mApduSender = new ApduSender(ci, ISD_R_AID, false /* supportExtendedApdu */); loadEidAndNotifyRegistrants(); } /** * Registers to be notified when EID is ready. If the EID is ready when this method is called, * the registrant will be notified immediately. */ public void registerForEidReady(Handler h, int what, Object obj) { Registrant r = new Registrant(h, what, obj); if (mEid != null) { r.notifyRegistrant(new AsyncResult(null, null, null)); } else { mEidReadyRegistrants.add(r); } } /** * Unregisters to be notified when EID is ready. */ public void unregisterForEidReady(Handler h) { mEidReadyRegistrants.remove(h); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected void loadEidAndNotifyRegistrants() { Handler euiccMainThreadHandler = new Handler(); AsyncResultCallback<String> cardCb = new AsyncResultCallback<String>() { @Override public void onResult(String result) { mEidReadyRegistrants.notifyRegistrants(new AsyncResult(null, null, null)); } @Override public void onException(Throwable e) { // Not notifying registrants if getting eid fails. Rlog.e(LOG_TAG, "Failed loading eid", e); } }; getEid(cardCb, euiccMainThreadHandler); } /** Loading Loading @@ -263,7 +307,15 @@ public class EuiccCard extends UiccCard { } /** * Gets the EID of the eUICC. * Gets the EID synchronously. * @return The EID string. Returns null if it is not ready yet. */ public String getEid() { return mEid; } /** * Gets the EID of the eUICC and overwrites mCardId in UiccCard. * * @param callback The callback to get the result. * @param handler The handler to run the callback. Loading @@ -284,6 +336,7 @@ public class EuiccCard extends UiccCard { .getChild(Tags.TAG_EID).asBytes()); synchronized (mLock) { mEid = eid; mCardId = eid; } return eid; }, Loading
tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java +36 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static org.mockito.Mockito.verify; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.service.carrier.CarrierIdentifier; import android.service.euicc.EuiccProfileInfo; import android.telephony.UiccAccessRule; Loading Loading @@ -102,6 +103,9 @@ public class EuiccCardTest extends TelephonyTest { protected byte[] getDeviceId() { return IccUtils.bcdToBytes("987654321012345"); } @Override protected void loadEidAndNotifyRegistrants() {} }; mHandler = new Handler(mTestHandlerThread.getLooper()); setReady(true); Loading Loading @@ -147,6 +151,38 @@ public class EuiccCardTest extends TelephonyTest { } } @Test public void testLoadEidAndNotifyRegistrants() throws InterruptedException { int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000"); { final CountDownLatch latch = new CountDownLatch(1); mHandler.post(() -> { mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi, mMockIccCardStatus, 0 /* phoneId */); latch.countDown(); }); assertTrue(latch.await(WAIT_TIMEOUT_MLLIS, TimeUnit.MILLISECONDS)); } 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(); } } }; mEuiccCard.registerForEidReady(handler, eventEidReady, null /* obj */); assertTrue(latch.await(WAIT_TIMEOUT_MLLIS, TimeUnit.MILLISECONDS)); verifyStoreData(channel, "BF3E035C015A"); } @Test public void testGetAllProfiles() { int channel = mockLogicalChannelResponses( Loading