Loading src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +21 −11 Original line number Original line Diff line number Diff line Loading @@ -724,20 +724,25 @@ public class SubscriptionInfoUpdater extends Handler { } } final EuiccProfileInfo[] embeddedProfiles; final EuiccProfileInfo[] embeddedProfiles; if (result.result == EuiccService.RESULT_OK) { if (result.getResult() == EuiccService.RESULT_OK) { embeddedProfiles = result.profiles; List<EuiccProfileInfo> list = result.getProfiles(); if (list == null || list.size() == 0) { embeddedProfiles = new EuiccProfileInfo[0]; } else { embeddedProfiles = list.toArray(new EuiccProfileInfo[list.size()]); } } else { } else { logd("updatedEmbeddedSubscriptions: error " + result.result + " listing profiles"); logd("updatedEmbeddedSubscriptions: error " + result.getResult() + " listing profiles"); // If there's an error listing profiles, treat it equivalently to a successful // If there's an error listing profiles, treat it equivalently to a successful // listing which returned no profiles under the assumption that none are currently // listing which returned no profiles under the assumption that none are currently // accessible. // accessible. embeddedProfiles = new EuiccProfileInfo[0]; embeddedProfiles = new EuiccProfileInfo[0]; } } final boolean isRemovable = result.isRemovable; final boolean isRemovable = result.getIsRemovable(); final String[] embeddedIccids = new String[embeddedProfiles.length]; final String[] embeddedIccids = new String[embeddedProfiles.length]; for (int i = 0; i < embeddedProfiles.length; i++) { for (int i = 0; i < embeddedProfiles.length; i++) { embeddedIccids[i] = embeddedProfiles[i].iccid; embeddedIccids[i] = embeddedProfiles[i].getIccid(); } } // Note that this only tracks whether we make any writes to the DB. It's possible this will // Note that this only tracks whether we make any writes to the DB. It's possible this will Loading @@ -755,25 +760,30 @@ public class SubscriptionInfoUpdater extends Handler { ContentResolver contentResolver = mContext.getContentResolver(); ContentResolver contentResolver = mContext.getContentResolver(); for (EuiccProfileInfo embeddedProfile : embeddedProfiles) { for (EuiccProfileInfo embeddedProfile : embeddedProfiles) { int index = int index = findSubscriptionInfoForIccid(existingSubscriptions, embeddedProfile.iccid); findSubscriptionInfoForIccid(existingSubscriptions, embeddedProfile.getIccid()); if (index < 0) { if (index < 0) { // No existing entry for this ICCID; create an empty one. // No existing entry for this ICCID; create an empty one. SubscriptionController.getInstance().insertEmptySubInfoRecord( SubscriptionController.getInstance().insertEmptySubInfoRecord( embeddedProfile.iccid, SubscriptionManager.SIM_NOT_INSERTED); embeddedProfile.getIccid(), SubscriptionManager.SIM_NOT_INSERTED); } else { } else { existingSubscriptions.remove(index); existingSubscriptions.remove(index); } } ContentValues values = new ContentValues(); ContentValues values = new ContentValues(); values.put(SubscriptionManager.IS_EMBEDDED, 1); values.put(SubscriptionManager.IS_EMBEDDED, 1); List<UiccAccessRule> ruleList = embeddedProfile.getUiccAccessRules(); boolean isRuleListEmpty = false; if (ruleList == null || ruleList.size() == 0) { isRuleListEmpty = true; } values.put(SubscriptionManager.ACCESS_RULES, values.put(SubscriptionManager.ACCESS_RULES, embeddedProfile.accessRules == null ? null : isRuleListEmpty ? null : UiccAccessRule.encodeRules( UiccAccessRule.encodeRules(embeddedProfile.accessRules)); ruleList.toArray(new UiccAccessRule[ruleList.size()]))); values.put(SubscriptionManager.IS_REMOVABLE, isRemovable); values.put(SubscriptionManager.IS_REMOVABLE, isRemovable); values.put(SubscriptionManager.DISPLAY_NAME, embeddedProfile.nickname); values.put(SubscriptionManager.DISPLAY_NAME, embeddedProfile.getNickname()); values.put(SubscriptionManager.NAME_SOURCE, SubscriptionManager.NAME_SOURCE_USER_INPUT); values.put(SubscriptionManager.NAME_SOURCE, SubscriptionManager.NAME_SOURCE_USER_INPUT); hasChanges = true; hasChanges = true; contentResolver.update(SubscriptionManager.CONTENT_URI, values, contentResolver.update(SubscriptionManager.CONTENT_URI, values, SubscriptionManager.ICC_ID + "=\"" + embeddedProfile.iccid + "\"", null); SubscriptionManager.ICC_ID + "=\"" + embeddedProfile.getIccid() + "\"", null); // refresh Cached Active Subscription Info List // refresh Cached Active Subscription Info List SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList(); SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList(); Loading src/java/com/android/internal/telephony/euicc/EuiccController.java +23 −14 Original line number Original line Diff line number Diff line Loading @@ -259,12 +259,12 @@ public class EuiccController extends IEuiccController.Stub { GetDownloadableSubscriptionMetadataResult result) { GetDownloadableSubscriptionMetadataResult result) { Intent extrasIntent = new Intent(); Intent extrasIntent = new Intent(); final int resultCode; final int resultCode; switch (result.result) { switch (result.getResult()) { case EuiccService.RESULT_OK: case EuiccService.RESULT_OK: resultCode = OK; resultCode = OK; extrasIntent.putExtra( extrasIntent.putExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION, EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION, result.subscription); result.getDownloadableSubscription()); break; break; case EuiccService.RESULT_MUST_DEACTIVATE_SIM: case EuiccService.RESULT_MUST_DEACTIVATE_SIM: resultCode = RESOLVABLE_ERROR; resultCode = RESOLVABLE_ERROR; Loading @@ -278,7 +278,7 @@ public class EuiccController extends IEuiccController.Stub { resultCode = ERROR; resultCode = ERROR; extrasIntent.putExtra( extrasIntent.putExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, result.result); result.getResult()); break; break; } } Loading Loading @@ -346,7 +346,7 @@ public class EuiccController extends IEuiccController.Stub { @Override @Override public void onGetMetadataComplete( public void onGetMetadataComplete( GetDownloadableSubscriptionMetadataResult result) { GetDownloadableSubscriptionMetadataResult result) { if (result.result == EuiccService.RESULT_MUST_DEACTIVATE_SIM) { if (result.getResult() == EuiccService.RESULT_MUST_DEACTIVATE_SIM) { // If we need to deactivate the current SIM to even check permissions, go ahead and // If we need to deactivate the current SIM to even check permissions, go ahead and // require that the user resolve the stronger permission dialog. // require that the user resolve the stronger permission dialog. Intent extrasIntent = new Intent(); Intent extrasIntent = new Intent(); Loading @@ -360,14 +360,18 @@ public class EuiccController extends IEuiccController.Stub { return; return; } } if (result.result != EuiccService.RESULT_OK) { if (result.getResult() != EuiccService.RESULT_OK) { // Just propagate the error as normal. // Just propagate the error as normal. super.onGetMetadataComplete(result); super.onGetMetadataComplete(result); return; return; } } DownloadableSubscription subscription = result.subscription; DownloadableSubscription subscription = result.getDownloadableSubscription(); UiccAccessRule[] rules = subscription.getAccessRules(); UiccAccessRule[] rules = null; List<UiccAccessRule> rulesList = subscription.getAccessRules(); if (rulesList != null) { rules = rulesList.toArray(new UiccAccessRule[rulesList.size()]); } if (rules == null) { if (rules == null) { Log.e(TAG, "No access rules but caller is unprivileged"); Log.e(TAG, "No access rules but caller is unprivileged"); sendResult(mCallbackIntent, ERROR, null /* extrasIntent */); sendResult(mCallbackIntent, ERROR, null /* extrasIntent */); Loading Loading @@ -562,12 +566,15 @@ public class EuiccController extends IEuiccController.Stub { public void onGetDefaultListComplete(GetDefaultDownloadableSubscriptionListResult result) { public void onGetDefaultListComplete(GetDefaultDownloadableSubscriptionListResult result) { Intent extrasIntent = new Intent(); Intent extrasIntent = new Intent(); final int resultCode; final int resultCode; switch (result.result) { switch (result.getResult()) { case EuiccService.RESULT_OK: case EuiccService.RESULT_OK: resultCode = OK; resultCode = OK; List<DownloadableSubscription> list = result.getDownloadableSubscriptions(); if (list != null && list.size() > 0) { extrasIntent.putExtra( extrasIntent.putExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS, EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS, result.subscriptions); list.toArray(new DownloadableSubscription[list.size()])); } break; break; case EuiccService.RESULT_MUST_DEACTIVATE_SIM: case EuiccService.RESULT_MUST_DEACTIVATE_SIM: resultCode = RESOLVABLE_ERROR; resultCode = RESOLVABLE_ERROR; Loading @@ -582,7 +589,7 @@ public class EuiccController extends IEuiccController.Stub { resultCode = ERROR; resultCode = ERROR; extrasIntent.putExtra( extrasIntent.putExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, result.result); result.getResult()); break; break; } } Loading Loading @@ -711,7 +718,7 @@ public class EuiccController extends IEuiccController.Stub { return; return; } } if (!callerCanWriteEmbeddedSubscriptions if (!callerCanWriteEmbeddedSubscriptions && !sub.canManageSubscription(mContext, callingPackage)) { && !mSubscriptionManager.canManageSubscription(sub, callingPackage)) { Log.e(TAG, "Not permitted to switch to subscription: " + subscriptionId); Log.e(TAG, "Not permitted to switch to subscription: " + subscriptionId); sendResult(callbackIntent, ERROR, null /* extrasIntent */); sendResult(callbackIntent, ERROR, null /* extrasIntent */); return; return; Loading Loading @@ -1063,7 +1070,9 @@ public class EuiccController extends IEuiccController.Stub { int size = subInfoList.size(); int size = subInfoList.size(); for (int subIndex = 0; subIndex < size; subIndex++) { for (int subIndex = 0; subIndex < size; subIndex++) { SubscriptionInfo subInfo = subInfoList.get(subIndex); SubscriptionInfo subInfo = subInfoList.get(subIndex); if (subInfo.isEmbedded() && subInfo.canManageSubscription(mContext, callingPackage)) { if (subInfo.isEmbedded() && mSubscriptionManager.canManageSubscription(subInfo, callingPackage)) { return true; return true; } } } } Loading src/java/com/android/internal/telephony/euicc/EuiccOperation.java +7 −7 Original line number Original line Diff line number Diff line Loading @@ -207,37 +207,37 @@ public class EuiccOperation implements Parcelable { switch (mAction) { switch (mAction) { case ACTION_GET_METADATA_DEACTIVATE_SIM: case ACTION_GET_METADATA_DEACTIVATE_SIM: resolvedGetMetadataDeactivateSim( resolvedGetMetadataDeactivateSim( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; case ACTION_DOWNLOAD_DEACTIVATE_SIM: case ACTION_DOWNLOAD_DEACTIVATE_SIM: resolvedDownloadDeactivateSim( resolvedDownloadDeactivateSim( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; case ACTION_DOWNLOAD_NO_PRIVILEGES: case ACTION_DOWNLOAD_NO_PRIVILEGES: resolvedDownloadNoPrivileges( resolvedDownloadNoPrivileges( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; case ACTION_DOWNLOAD_CONFIRMATION_CODE: case ACTION_DOWNLOAD_CONFIRMATION_CODE: resolvedDownloadConfirmationCode( resolvedDownloadConfirmationCode( resolutionExtras.getString(EuiccService.RESOLUTION_EXTRA_CONFIRMATION_CODE), resolutionExtras.getString(EuiccService.EXTRA_RESOLUTION_CONFIRMATION_CODE), callbackIntent); callbackIntent); break; break; case ACTION_GET_DEFAULT_LIST_DEACTIVATE_SIM: case ACTION_GET_DEFAULT_LIST_DEACTIVATE_SIM: resolvedGetDefaultListDeactivateSim( resolvedGetDefaultListDeactivateSim( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; case ACTION_SWITCH_DEACTIVATE_SIM: case ACTION_SWITCH_DEACTIVATE_SIM: resolvedSwitchDeactivateSim( resolvedSwitchDeactivateSim( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; case ACTION_SWITCH_NO_PRIVILEGES: case ACTION_SWITCH_NO_PRIVILEGES: resolvedSwitchNoPrivileges( resolvedSwitchNoPrivileges( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; default: default: Loading src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java +16 −8 Original line number Original line Diff line number Diff line Loading @@ -51,6 +51,7 @@ import com.android.internal.telephony.uicc.euicc.apdu.RequestProvider; import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback; import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback; import com.android.internal.telephony.uicc.euicc.async.AsyncResultHelper; import com.android.internal.telephony.uicc.euicc.async.AsyncResultHelper; import java.util.Arrays; import java.util.List; import java.util.List; /** /** Loading Loading @@ -189,7 +190,10 @@ public class EuiccCard extends UiccCard { loge("Profile must have an ICCID."); loge("Profile must have an ICCID."); continue; continue; } } EuiccProfileInfo.Builder profileBuilder = new EuiccProfileInfo.Builder(); String strippedIccIdString = stripTrailingFs(profileNode.getChild(Tags.TAG_ICCID).asBytes()); EuiccProfileInfo.Builder profileBuilder = new EuiccProfileInfo.Builder(strippedIccIdString); buildProfile(profileNode, profileBuilder); buildProfile(profileNode, profileBuilder); EuiccProfileInfo profile = profileBuilder.build(); EuiccProfileInfo profile = profileBuilder.build(); Loading Loading @@ -222,7 +226,10 @@ public class EuiccCard extends UiccCard { return null; return null; } } Asn1Node profileNode = profileNodes.get(0); Asn1Node profileNode = profileNodes.get(0); EuiccProfileInfo.Builder profileBuilder = new EuiccProfileInfo.Builder(); String strippedIccIdString = stripTrailingFs(profileNode.getChild(Tags.TAG_ICCID).asBytes()); EuiccProfileInfo.Builder profileBuilder = new EuiccProfileInfo.Builder(strippedIccIdString); buildProfile(profileNode, profileBuilder); buildProfile(profileNode, profileBuilder); return profileBuilder.build(); return profileBuilder.build(); }, }, Loading Loading @@ -512,7 +519,7 @@ public class EuiccCard extends UiccCard { for (int j = 0; j < opIdSize; j++) { for (int j = 0; j < opIdSize; j++) { opIds[j] = buildCarrierIdentifier(opIdNodes.get(j)); opIds[j] = buildCarrierIdentifier(opIdNodes.get(j)); } } builder.add(node.getChild(Tags.TAG_CTX_0).asBits(), opIds, builder.add(node.getChild(Tags.TAG_CTX_0).asBits(), Arrays.asList(opIds), node.getChild(Tags.TAG_CTX_2).asBits()); node.getChild(Tags.TAG_CTX_2).asBits()); } } return builder.build(); return builder.build(); Loading Loading @@ -977,10 +984,6 @@ public class EuiccCard extends UiccCard { private static void buildProfile(Asn1Node profileNode, EuiccProfileInfo.Builder profileBuilder) private static void buildProfile(Asn1Node profileNode, EuiccProfileInfo.Builder profileBuilder) throws TagNotFoundException, InvalidAsn1DataException { throws TagNotFoundException, InvalidAsn1DataException { String strippedIccIdString = stripTrailingFs(profileNode.getChild(Tags.TAG_ICCID).asBytes()); profileBuilder.setIccid(strippedIccIdString); if (profileNode.hasChild(Tags.TAG_NICKNAME)) { if (profileNode.hasChild(Tags.TAG_NICKNAME)) { profileBuilder.setNickname(profileNode.getChild(Tags.TAG_NICKNAME).asString()); profileBuilder.setNickname(profileNode.getChild(Tags.TAG_NICKNAME).asString()); } } Loading Loading @@ -1024,7 +1027,12 @@ public class EuiccCard extends UiccCard { if (profileNode.hasChild(Tags.TAG_CARRIER_PRIVILEGE_RULES)) { if (profileNode.hasChild(Tags.TAG_CARRIER_PRIVILEGE_RULES)) { List<Asn1Node> refArDoNodes = profileNode.getChild(Tags.TAG_CARRIER_PRIVILEGE_RULES) List<Asn1Node> refArDoNodes = profileNode.getChild(Tags.TAG_CARRIER_PRIVILEGE_RULES) .getChildren(Tags.TAG_REF_AR_DO); .getChildren(Tags.TAG_REF_AR_DO); profileBuilder.setUiccAccessRule(buildUiccAccessRule(refArDoNodes)); UiccAccessRule[] rules = buildUiccAccessRule(refArDoNodes); List<UiccAccessRule> rulesList = null; if (rules != null) { rulesList = Arrays.asList(rules); } profileBuilder.setUiccAccessRule(rulesList); } } } } Loading tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java +8 −2 Original line number Original line Diff line number Diff line Loading @@ -73,6 +73,7 @@ import org.mockito.stubbing.Stubber; import java.security.MessageDigest; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Collections; import java.util.Collections; @RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class) Loading Loading @@ -100,7 +101,8 @@ public class EuiccControllerTest extends TelephonyTest { DownloadableSubscription.forActivationCode("abcde"); DownloadableSubscription.forActivationCode("abcde"); static { static { SUBSCRIPTION_WITH_METADATA.setCarrierName("test name"); SUBSCRIPTION_WITH_METADATA.setCarrierName("test name"); SUBSCRIPTION_WITH_METADATA.setAccessRules(new UiccAccessRule[] { ACCESS_RULE }); SUBSCRIPTION_WITH_METADATA.setAccessRules( Arrays.asList(new UiccAccessRule[] { ACCESS_RULE })); } } private static final String OS_VERSION = "1.0"; private static final String OS_VERSION = "1.0"; Loading Loading @@ -264,7 +266,7 @@ public class EuiccControllerTest extends TelephonyTest { @Test @Test public void testGetEuiccInfo_success() { public void testGetEuiccInfo_success() { assertEquals(OS_VERSION, callGetEuiccInfo(true /* success */, EUICC_INFO).osVersion); assertEquals(OS_VERSION, callGetEuiccInfo(true /* success */, EUICC_INFO).getOsVersion()); } } @Test @Test Loading Loading @@ -837,6 +839,8 @@ public class EuiccControllerTest extends TelephonyTest { SubscriptionInfo subInfo = new SubscriptionInfo( SubscriptionInfo subInfo = new SubscriptionInfo( 0, "", 0, "", "", 0, 0, "", 0, null, 0, 0, "", true /* isEmbedded */, 0, "", 0, "", "", 0, 0, "", 0, null, 0, 0, "", true /* isEmbedded */, hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null); hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null); when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn( hasPrivileges); when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn( when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn( Collections.singletonList(subInfo)); Collections.singletonList(subInfo)); } } Loading @@ -845,6 +849,8 @@ public class EuiccControllerTest extends TelephonyTest { SubscriptionInfo subInfo = new SubscriptionInfo( SubscriptionInfo subInfo = new SubscriptionInfo( SUBSCRIPTION_ID, ICC_ID, 0, "", "", 0, 0, "", 0, null, 0, 0, "", SUBSCRIPTION_ID, ICC_ID, 0, "", "", 0, 0, "", 0, null, 0, 0, "", true /* isEmbedded */, hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null); true /* isEmbedded */, hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null); when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn( hasPrivileges); when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn( when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn( Collections.singletonList(subInfo)); Collections.singletonList(subInfo)); } } Loading Loading
src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +21 −11 Original line number Original line Diff line number Diff line Loading @@ -724,20 +724,25 @@ public class SubscriptionInfoUpdater extends Handler { } } final EuiccProfileInfo[] embeddedProfiles; final EuiccProfileInfo[] embeddedProfiles; if (result.result == EuiccService.RESULT_OK) { if (result.getResult() == EuiccService.RESULT_OK) { embeddedProfiles = result.profiles; List<EuiccProfileInfo> list = result.getProfiles(); if (list == null || list.size() == 0) { embeddedProfiles = new EuiccProfileInfo[0]; } else { embeddedProfiles = list.toArray(new EuiccProfileInfo[list.size()]); } } else { } else { logd("updatedEmbeddedSubscriptions: error " + result.result + " listing profiles"); logd("updatedEmbeddedSubscriptions: error " + result.getResult() + " listing profiles"); // If there's an error listing profiles, treat it equivalently to a successful // If there's an error listing profiles, treat it equivalently to a successful // listing which returned no profiles under the assumption that none are currently // listing which returned no profiles under the assumption that none are currently // accessible. // accessible. embeddedProfiles = new EuiccProfileInfo[0]; embeddedProfiles = new EuiccProfileInfo[0]; } } final boolean isRemovable = result.isRemovable; final boolean isRemovable = result.getIsRemovable(); final String[] embeddedIccids = new String[embeddedProfiles.length]; final String[] embeddedIccids = new String[embeddedProfiles.length]; for (int i = 0; i < embeddedProfiles.length; i++) { for (int i = 0; i < embeddedProfiles.length; i++) { embeddedIccids[i] = embeddedProfiles[i].iccid; embeddedIccids[i] = embeddedProfiles[i].getIccid(); } } // Note that this only tracks whether we make any writes to the DB. It's possible this will // Note that this only tracks whether we make any writes to the DB. It's possible this will Loading @@ -755,25 +760,30 @@ public class SubscriptionInfoUpdater extends Handler { ContentResolver contentResolver = mContext.getContentResolver(); ContentResolver contentResolver = mContext.getContentResolver(); for (EuiccProfileInfo embeddedProfile : embeddedProfiles) { for (EuiccProfileInfo embeddedProfile : embeddedProfiles) { int index = int index = findSubscriptionInfoForIccid(existingSubscriptions, embeddedProfile.iccid); findSubscriptionInfoForIccid(existingSubscriptions, embeddedProfile.getIccid()); if (index < 0) { if (index < 0) { // No existing entry for this ICCID; create an empty one. // No existing entry for this ICCID; create an empty one. SubscriptionController.getInstance().insertEmptySubInfoRecord( SubscriptionController.getInstance().insertEmptySubInfoRecord( embeddedProfile.iccid, SubscriptionManager.SIM_NOT_INSERTED); embeddedProfile.getIccid(), SubscriptionManager.SIM_NOT_INSERTED); } else { } else { existingSubscriptions.remove(index); existingSubscriptions.remove(index); } } ContentValues values = new ContentValues(); ContentValues values = new ContentValues(); values.put(SubscriptionManager.IS_EMBEDDED, 1); values.put(SubscriptionManager.IS_EMBEDDED, 1); List<UiccAccessRule> ruleList = embeddedProfile.getUiccAccessRules(); boolean isRuleListEmpty = false; if (ruleList == null || ruleList.size() == 0) { isRuleListEmpty = true; } values.put(SubscriptionManager.ACCESS_RULES, values.put(SubscriptionManager.ACCESS_RULES, embeddedProfile.accessRules == null ? null : isRuleListEmpty ? null : UiccAccessRule.encodeRules( UiccAccessRule.encodeRules(embeddedProfile.accessRules)); ruleList.toArray(new UiccAccessRule[ruleList.size()]))); values.put(SubscriptionManager.IS_REMOVABLE, isRemovable); values.put(SubscriptionManager.IS_REMOVABLE, isRemovable); values.put(SubscriptionManager.DISPLAY_NAME, embeddedProfile.nickname); values.put(SubscriptionManager.DISPLAY_NAME, embeddedProfile.getNickname()); values.put(SubscriptionManager.NAME_SOURCE, SubscriptionManager.NAME_SOURCE_USER_INPUT); values.put(SubscriptionManager.NAME_SOURCE, SubscriptionManager.NAME_SOURCE_USER_INPUT); hasChanges = true; hasChanges = true; contentResolver.update(SubscriptionManager.CONTENT_URI, values, contentResolver.update(SubscriptionManager.CONTENT_URI, values, SubscriptionManager.ICC_ID + "=\"" + embeddedProfile.iccid + "\"", null); SubscriptionManager.ICC_ID + "=\"" + embeddedProfile.getIccid() + "\"", null); // refresh Cached Active Subscription Info List // refresh Cached Active Subscription Info List SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList(); SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList(); Loading
src/java/com/android/internal/telephony/euicc/EuiccController.java +23 −14 Original line number Original line Diff line number Diff line Loading @@ -259,12 +259,12 @@ public class EuiccController extends IEuiccController.Stub { GetDownloadableSubscriptionMetadataResult result) { GetDownloadableSubscriptionMetadataResult result) { Intent extrasIntent = new Intent(); Intent extrasIntent = new Intent(); final int resultCode; final int resultCode; switch (result.result) { switch (result.getResult()) { case EuiccService.RESULT_OK: case EuiccService.RESULT_OK: resultCode = OK; resultCode = OK; extrasIntent.putExtra( extrasIntent.putExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION, EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION, result.subscription); result.getDownloadableSubscription()); break; break; case EuiccService.RESULT_MUST_DEACTIVATE_SIM: case EuiccService.RESULT_MUST_DEACTIVATE_SIM: resultCode = RESOLVABLE_ERROR; resultCode = RESOLVABLE_ERROR; Loading @@ -278,7 +278,7 @@ public class EuiccController extends IEuiccController.Stub { resultCode = ERROR; resultCode = ERROR; extrasIntent.putExtra( extrasIntent.putExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, result.result); result.getResult()); break; break; } } Loading Loading @@ -346,7 +346,7 @@ public class EuiccController extends IEuiccController.Stub { @Override @Override public void onGetMetadataComplete( public void onGetMetadataComplete( GetDownloadableSubscriptionMetadataResult result) { GetDownloadableSubscriptionMetadataResult result) { if (result.result == EuiccService.RESULT_MUST_DEACTIVATE_SIM) { if (result.getResult() == EuiccService.RESULT_MUST_DEACTIVATE_SIM) { // If we need to deactivate the current SIM to even check permissions, go ahead and // If we need to deactivate the current SIM to even check permissions, go ahead and // require that the user resolve the stronger permission dialog. // require that the user resolve the stronger permission dialog. Intent extrasIntent = new Intent(); Intent extrasIntent = new Intent(); Loading @@ -360,14 +360,18 @@ public class EuiccController extends IEuiccController.Stub { return; return; } } if (result.result != EuiccService.RESULT_OK) { if (result.getResult() != EuiccService.RESULT_OK) { // Just propagate the error as normal. // Just propagate the error as normal. super.onGetMetadataComplete(result); super.onGetMetadataComplete(result); return; return; } } DownloadableSubscription subscription = result.subscription; DownloadableSubscription subscription = result.getDownloadableSubscription(); UiccAccessRule[] rules = subscription.getAccessRules(); UiccAccessRule[] rules = null; List<UiccAccessRule> rulesList = subscription.getAccessRules(); if (rulesList != null) { rules = rulesList.toArray(new UiccAccessRule[rulesList.size()]); } if (rules == null) { if (rules == null) { Log.e(TAG, "No access rules but caller is unprivileged"); Log.e(TAG, "No access rules but caller is unprivileged"); sendResult(mCallbackIntent, ERROR, null /* extrasIntent */); sendResult(mCallbackIntent, ERROR, null /* extrasIntent */); Loading Loading @@ -562,12 +566,15 @@ public class EuiccController extends IEuiccController.Stub { public void onGetDefaultListComplete(GetDefaultDownloadableSubscriptionListResult result) { public void onGetDefaultListComplete(GetDefaultDownloadableSubscriptionListResult result) { Intent extrasIntent = new Intent(); Intent extrasIntent = new Intent(); final int resultCode; final int resultCode; switch (result.result) { switch (result.getResult()) { case EuiccService.RESULT_OK: case EuiccService.RESULT_OK: resultCode = OK; resultCode = OK; List<DownloadableSubscription> list = result.getDownloadableSubscriptions(); if (list != null && list.size() > 0) { extrasIntent.putExtra( extrasIntent.putExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS, EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS, result.subscriptions); list.toArray(new DownloadableSubscription[list.size()])); } break; break; case EuiccService.RESULT_MUST_DEACTIVATE_SIM: case EuiccService.RESULT_MUST_DEACTIVATE_SIM: resultCode = RESOLVABLE_ERROR; resultCode = RESOLVABLE_ERROR; Loading @@ -582,7 +589,7 @@ public class EuiccController extends IEuiccController.Stub { resultCode = ERROR; resultCode = ERROR; extrasIntent.putExtra( extrasIntent.putExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, result.result); result.getResult()); break; break; } } Loading Loading @@ -711,7 +718,7 @@ public class EuiccController extends IEuiccController.Stub { return; return; } } if (!callerCanWriteEmbeddedSubscriptions if (!callerCanWriteEmbeddedSubscriptions && !sub.canManageSubscription(mContext, callingPackage)) { && !mSubscriptionManager.canManageSubscription(sub, callingPackage)) { Log.e(TAG, "Not permitted to switch to subscription: " + subscriptionId); Log.e(TAG, "Not permitted to switch to subscription: " + subscriptionId); sendResult(callbackIntent, ERROR, null /* extrasIntent */); sendResult(callbackIntent, ERROR, null /* extrasIntent */); return; return; Loading Loading @@ -1063,7 +1070,9 @@ public class EuiccController extends IEuiccController.Stub { int size = subInfoList.size(); int size = subInfoList.size(); for (int subIndex = 0; subIndex < size; subIndex++) { for (int subIndex = 0; subIndex < size; subIndex++) { SubscriptionInfo subInfo = subInfoList.get(subIndex); SubscriptionInfo subInfo = subInfoList.get(subIndex); if (subInfo.isEmbedded() && subInfo.canManageSubscription(mContext, callingPackage)) { if (subInfo.isEmbedded() && mSubscriptionManager.canManageSubscription(subInfo, callingPackage)) { return true; return true; } } } } Loading
src/java/com/android/internal/telephony/euicc/EuiccOperation.java +7 −7 Original line number Original line Diff line number Diff line Loading @@ -207,37 +207,37 @@ public class EuiccOperation implements Parcelable { switch (mAction) { switch (mAction) { case ACTION_GET_METADATA_DEACTIVATE_SIM: case ACTION_GET_METADATA_DEACTIVATE_SIM: resolvedGetMetadataDeactivateSim( resolvedGetMetadataDeactivateSim( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; case ACTION_DOWNLOAD_DEACTIVATE_SIM: case ACTION_DOWNLOAD_DEACTIVATE_SIM: resolvedDownloadDeactivateSim( resolvedDownloadDeactivateSim( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; case ACTION_DOWNLOAD_NO_PRIVILEGES: case ACTION_DOWNLOAD_NO_PRIVILEGES: resolvedDownloadNoPrivileges( resolvedDownloadNoPrivileges( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; case ACTION_DOWNLOAD_CONFIRMATION_CODE: case ACTION_DOWNLOAD_CONFIRMATION_CODE: resolvedDownloadConfirmationCode( resolvedDownloadConfirmationCode( resolutionExtras.getString(EuiccService.RESOLUTION_EXTRA_CONFIRMATION_CODE), resolutionExtras.getString(EuiccService.EXTRA_RESOLUTION_CONFIRMATION_CODE), callbackIntent); callbackIntent); break; break; case ACTION_GET_DEFAULT_LIST_DEACTIVATE_SIM: case ACTION_GET_DEFAULT_LIST_DEACTIVATE_SIM: resolvedGetDefaultListDeactivateSim( resolvedGetDefaultListDeactivateSim( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; case ACTION_SWITCH_DEACTIVATE_SIM: case ACTION_SWITCH_DEACTIVATE_SIM: resolvedSwitchDeactivateSim( resolvedSwitchDeactivateSim( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; case ACTION_SWITCH_NO_PRIVILEGES: case ACTION_SWITCH_NO_PRIVILEGES: resolvedSwitchNoPrivileges( resolvedSwitchNoPrivileges( resolutionExtras.getBoolean(EuiccService.RESOLUTION_EXTRA_CONSENT), resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT), callbackIntent); callbackIntent); break; break; default: default: Loading
src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java +16 −8 Original line number Original line Diff line number Diff line Loading @@ -51,6 +51,7 @@ import com.android.internal.telephony.uicc.euicc.apdu.RequestProvider; import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback; import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback; import com.android.internal.telephony.uicc.euicc.async.AsyncResultHelper; import com.android.internal.telephony.uicc.euicc.async.AsyncResultHelper; import java.util.Arrays; import java.util.List; import java.util.List; /** /** Loading Loading @@ -189,7 +190,10 @@ public class EuiccCard extends UiccCard { loge("Profile must have an ICCID."); loge("Profile must have an ICCID."); continue; continue; } } EuiccProfileInfo.Builder profileBuilder = new EuiccProfileInfo.Builder(); String strippedIccIdString = stripTrailingFs(profileNode.getChild(Tags.TAG_ICCID).asBytes()); EuiccProfileInfo.Builder profileBuilder = new EuiccProfileInfo.Builder(strippedIccIdString); buildProfile(profileNode, profileBuilder); buildProfile(profileNode, profileBuilder); EuiccProfileInfo profile = profileBuilder.build(); EuiccProfileInfo profile = profileBuilder.build(); Loading Loading @@ -222,7 +226,10 @@ public class EuiccCard extends UiccCard { return null; return null; } } Asn1Node profileNode = profileNodes.get(0); Asn1Node profileNode = profileNodes.get(0); EuiccProfileInfo.Builder profileBuilder = new EuiccProfileInfo.Builder(); String strippedIccIdString = stripTrailingFs(profileNode.getChild(Tags.TAG_ICCID).asBytes()); EuiccProfileInfo.Builder profileBuilder = new EuiccProfileInfo.Builder(strippedIccIdString); buildProfile(profileNode, profileBuilder); buildProfile(profileNode, profileBuilder); return profileBuilder.build(); return profileBuilder.build(); }, }, Loading Loading @@ -512,7 +519,7 @@ public class EuiccCard extends UiccCard { for (int j = 0; j < opIdSize; j++) { for (int j = 0; j < opIdSize; j++) { opIds[j] = buildCarrierIdentifier(opIdNodes.get(j)); opIds[j] = buildCarrierIdentifier(opIdNodes.get(j)); } } builder.add(node.getChild(Tags.TAG_CTX_0).asBits(), opIds, builder.add(node.getChild(Tags.TAG_CTX_0).asBits(), Arrays.asList(opIds), node.getChild(Tags.TAG_CTX_2).asBits()); node.getChild(Tags.TAG_CTX_2).asBits()); } } return builder.build(); return builder.build(); Loading Loading @@ -977,10 +984,6 @@ public class EuiccCard extends UiccCard { private static void buildProfile(Asn1Node profileNode, EuiccProfileInfo.Builder profileBuilder) private static void buildProfile(Asn1Node profileNode, EuiccProfileInfo.Builder profileBuilder) throws TagNotFoundException, InvalidAsn1DataException { throws TagNotFoundException, InvalidAsn1DataException { String strippedIccIdString = stripTrailingFs(profileNode.getChild(Tags.TAG_ICCID).asBytes()); profileBuilder.setIccid(strippedIccIdString); if (profileNode.hasChild(Tags.TAG_NICKNAME)) { if (profileNode.hasChild(Tags.TAG_NICKNAME)) { profileBuilder.setNickname(profileNode.getChild(Tags.TAG_NICKNAME).asString()); profileBuilder.setNickname(profileNode.getChild(Tags.TAG_NICKNAME).asString()); } } Loading Loading @@ -1024,7 +1027,12 @@ public class EuiccCard extends UiccCard { if (profileNode.hasChild(Tags.TAG_CARRIER_PRIVILEGE_RULES)) { if (profileNode.hasChild(Tags.TAG_CARRIER_PRIVILEGE_RULES)) { List<Asn1Node> refArDoNodes = profileNode.getChild(Tags.TAG_CARRIER_PRIVILEGE_RULES) List<Asn1Node> refArDoNodes = profileNode.getChild(Tags.TAG_CARRIER_PRIVILEGE_RULES) .getChildren(Tags.TAG_REF_AR_DO); .getChildren(Tags.TAG_REF_AR_DO); profileBuilder.setUiccAccessRule(buildUiccAccessRule(refArDoNodes)); UiccAccessRule[] rules = buildUiccAccessRule(refArDoNodes); List<UiccAccessRule> rulesList = null; if (rules != null) { rulesList = Arrays.asList(rules); } profileBuilder.setUiccAccessRule(rulesList); } } } } Loading
tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java +8 −2 Original line number Original line Diff line number Diff line Loading @@ -73,6 +73,7 @@ import org.mockito.stubbing.Stubber; import java.security.MessageDigest; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Collections; import java.util.Collections; @RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class) Loading Loading @@ -100,7 +101,8 @@ public class EuiccControllerTest extends TelephonyTest { DownloadableSubscription.forActivationCode("abcde"); DownloadableSubscription.forActivationCode("abcde"); static { static { SUBSCRIPTION_WITH_METADATA.setCarrierName("test name"); SUBSCRIPTION_WITH_METADATA.setCarrierName("test name"); SUBSCRIPTION_WITH_METADATA.setAccessRules(new UiccAccessRule[] { ACCESS_RULE }); SUBSCRIPTION_WITH_METADATA.setAccessRules( Arrays.asList(new UiccAccessRule[] { ACCESS_RULE })); } } private static final String OS_VERSION = "1.0"; private static final String OS_VERSION = "1.0"; Loading Loading @@ -264,7 +266,7 @@ public class EuiccControllerTest extends TelephonyTest { @Test @Test public void testGetEuiccInfo_success() { public void testGetEuiccInfo_success() { assertEquals(OS_VERSION, callGetEuiccInfo(true /* success */, EUICC_INFO).osVersion); assertEquals(OS_VERSION, callGetEuiccInfo(true /* success */, EUICC_INFO).getOsVersion()); } } @Test @Test Loading Loading @@ -837,6 +839,8 @@ public class EuiccControllerTest extends TelephonyTest { SubscriptionInfo subInfo = new SubscriptionInfo( SubscriptionInfo subInfo = new SubscriptionInfo( 0, "", 0, "", "", 0, 0, "", 0, null, 0, 0, "", true /* isEmbedded */, 0, "", 0, "", "", 0, 0, "", 0, null, 0, 0, "", true /* isEmbedded */, hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null); hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null); when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn( hasPrivileges); when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn( when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn( Collections.singletonList(subInfo)); Collections.singletonList(subInfo)); } } Loading @@ -845,6 +849,8 @@ public class EuiccControllerTest extends TelephonyTest { SubscriptionInfo subInfo = new SubscriptionInfo( SubscriptionInfo subInfo = new SubscriptionInfo( SUBSCRIPTION_ID, ICC_ID, 0, "", "", 0, 0, "", 0, null, 0, 0, "", SUBSCRIPTION_ID, ICC_ID, 0, "", "", 0, 0, "", 0, null, 0, 0, "", true /* isEmbedded */, hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null); true /* isEmbedded */, hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null); when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn( hasPrivileges); when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn( when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn( Collections.singletonList(subInfo)); Collections.singletonList(subInfo)); } } Loading