use of android.service.euicc.GetEuiccProfileInfoListResult in project android_frameworks_opt_telephony by LineageOS.
the class SubscriptionInfoUpdater method updateEmbeddedSubscriptions.
/**
* Update the cached list of embedded subscriptions.
*
* @return true if changes may have been made. This is not a guarantee that changes were made,
* but notifications about subscription changes may be skipped if this returns false as an
* optimization to avoid spurious notifications.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
public boolean updateEmbeddedSubscriptions() {
// are filtered out of list calls as long as EuiccManager.isEnabled returns false).
if (!mEuiccManager.isEnabled()) {
return false;
}
GetEuiccProfileInfoListResult result = EuiccController.get().blockingGetEuiccProfileInfoList();
if (result == null) {
// IPC to the eUICC controller failed.
return false;
}
final EuiccProfileInfo[] embeddedProfiles;
if (result.result == EuiccService.RESULT_OK) {
embeddedProfiles = result.profiles;
} else {
logd("updatedEmbeddedSubscriptions: error " + result.result + " listing profiles");
// 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
// accessible.
embeddedProfiles = new EuiccProfileInfo[0];
}
final boolean isRemovable = result.isRemovable;
final String[] embeddedIccids = new String[embeddedProfiles.length];
for (int i = 0; i < embeddedProfiles.length; i++) {
embeddedIccids[i] = embeddedProfiles[i].iccid;
}
// Note that this only tracks whether we make any writes to the DB. It's possible this will
// be set to true for an update even when the row contents remain exactly unchanged from
// before, since we don't compare against the previous value. Since this is only intended to
// avoid some spurious broadcasts (particularly for users who don't use eSIM at all), this
// is fine.
boolean hasChanges = false;
// Update or insert records for all embedded subscriptions (except non-removable ones if the
// current eUICC is non-removable, since we assume these are still accessible though not
// returned by the eUICC controller).
List<SubscriptionInfo> existingSubscriptions = SubscriptionController.getInstance().getSubscriptionInfoListForEmbeddedSubscriptionUpdate(embeddedIccids, isRemovable);
ContentResolver contentResolver = mContext.getContentResolver();
for (EuiccProfileInfo embeddedProfile : embeddedProfiles) {
int index = findSubscriptionInfoForIccid(existingSubscriptions, embeddedProfile.iccid);
if (index < 0) {
// No existing entry for this ICCID; create an empty one.
SubscriptionController.getInstance().insertEmptySubInfoRecord(embeddedProfile.iccid, SubscriptionManager.SIM_NOT_INSERTED);
} else {
existingSubscriptions.remove(index);
}
ContentValues values = new ContentValues();
values.put(SubscriptionManager.IS_EMBEDDED, 1);
values.put(SubscriptionManager.ACCESS_RULES, embeddedProfile.accessRules == null ? null : UiccAccessRule.encodeRules(embeddedProfile.accessRules));
values.put(SubscriptionManager.IS_REMOVABLE, isRemovable);
values.put(SubscriptionManager.DISPLAY_NAME, embeddedProfile.nickname);
values.put(SubscriptionManager.NAME_SOURCE, SubscriptionManager.NAME_SOURCE_USER_INPUT);
hasChanges = true;
contentResolver.update(SubscriptionManager.CONTENT_URI, values, SubscriptionManager.ICC_ID + "=\"" + embeddedProfile.iccid + "\"", null);
// refresh Cached Active Subscription Info List
SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList();
}
// SIM being removed and reinserted).
if (!existingSubscriptions.isEmpty()) {
List<String> iccidsToRemove = new ArrayList<>();
for (int i = 0; i < existingSubscriptions.size(); i++) {
SubscriptionInfo info = existingSubscriptions.get(i);
if (info.isEmbedded()) {
iccidsToRemove.add("\"" + info.getIccId() + "\"");
}
}
String whereClause = SubscriptionManager.ICC_ID + " IN (" + TextUtils.join(",", iccidsToRemove) + ")";
ContentValues values = new ContentValues();
values.put(SubscriptionManager.IS_EMBEDDED, 0);
hasChanges = true;
contentResolver.update(SubscriptionManager.CONTENT_URI, values, whereClause, null);
// refresh Cached Active Subscription Info List
SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList();
}
return hasChanges;
}
use of android.service.euicc.GetEuiccProfileInfoListResult in project android_frameworks_opt_telephony by LineageOS.
the class SubscriptionInfoUpdater method updateEmbeddedSubscriptions.
/**
* Updates the cached list of embedded subscription for the eUICC with the given list of card
* IDs {@code cardIds}. The step of reading the embedded subscription list from eUICC card is
* executed in background thread. The callback {@code callback} is executed after the cache is
* refreshed. The callback is executed in main thread.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
public void updateEmbeddedSubscriptions(List<Integer> cardIds, @Nullable UpdateEmbeddedSubsCallback callback) {
// are filtered out of list calls as long as EuiccManager.isEnabled returns false).
if (!mEuiccManager.isEnabled()) {
callback.run(false);
return;
}
mBackgroundHandler.post(() -> {
List<Pair<Integer, GetEuiccProfileInfoListResult>> results = new ArrayList<>();
for (int cardId : cardIds) {
GetEuiccProfileInfoListResult result = EuiccController.get().blockingGetEuiccProfileInfoList(cardId);
if (DBG)
logd("blockingGetEuiccProfileInfoList cardId " + cardId);
results.add(Pair.create(cardId, result));
}
// The runnable will be executed in the main thread.
this.post(() -> {
boolean hasChanges = false;
for (Pair<Integer, GetEuiccProfileInfoListResult> cardIdAndResult : results) {
if (updateEmbeddedSubscriptionsCache(cardIdAndResult.first, cardIdAndResult.second)) {
hasChanges = true;
}
}
// triggered.
if (callback != null) {
callback.run(hasChanges);
}
});
});
}
use of android.service.euicc.GetEuiccProfileInfoListResult in project android_frameworks_opt_telephony by LineageOS.
the class SubscriptionInfoUpdaterTest method testUpdateEmbeddedSubscriptions_listFailure.
@Test
@SmallTest
public void testUpdateEmbeddedSubscriptions_listFailure() throws Exception {
when(mEuiccManager.isEnabled()).thenReturn(true);
when(mEuiccController.blockingGetEuiccProfileInfoList(FAKE_CARD_ID)).thenReturn(new GetEuiccProfileInfoListResult(42, null, /* subscriptions */
false));
List<SubscriptionInfo> subInfoList = new ArrayList<>();
// 1: not embedded, but has matching iccid with an embedded subscription.
subInfoList.add(new SubscriptionInfo(0, "1", 0, "", "", 0, 0, "", 0, null, "0", "0", "", false, /* isEmbedded */
null, /* accessRules */
null));
// 2: embedded.
subInfoList.add(new SubscriptionInfo(0, "2", 0, "", "", 0, 0, "", 0, null, "0", "0", "", true, /* isEmbedded */
null, /* accessRules */
null));
when(mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate(new String[0], false)).thenReturn(subInfoList);
ArrayList<Integer> cardIds = new ArrayList<>(1);
cardIds.add(FAKE_CARD_ID);
mUpdater.updateEmbeddedSubscriptions(cardIds, null);
// No new entries should be created.
verify(mSubscriptionController, times(0)).clearSubInfo();
verify(mSubscriptionController, never()).insertEmptySubInfoRecord(anyString(), anyInt());
// No existing entries should have been updated.
verify(mContentProvider, never()).update(eq(SubscriptionManager.CONTENT_URI), any(), any(), isNull());
}
use of android.service.euicc.GetEuiccProfileInfoListResult in project android_frameworks_opt_telephony by LineageOS.
the class EuiccController method blockingGetEuiccProfileInfoList.
/**
* Blocking call to {@link EuiccService#onGetEuiccProfileInfoList}.
*
* <p>Does not perform permission checks as this is not an exposed API and is only used within
* the phone process.
*/
public GetEuiccProfileInfoListResult blockingGetEuiccProfileInfoList() {
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<GetEuiccProfileInfoListResult> resultRef = new AtomicReference<>();
mConnector.getEuiccProfileInfoList(new EuiccConnector.GetEuiccProfileInfoListCommandCallback() {
@Override
public void onListComplete(GetEuiccProfileInfoListResult result) {
resultRef.set(result);
latch.countDown();
}
@Override
public void onEuiccServiceUnavailable() {
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return resultRef.get();
}
use of android.service.euicc.GetEuiccProfileInfoListResult in project android_frameworks_opt_telephony by LineageOS.
the class EuiccController method blockingGetEuiccProfileInfoList.
/**
* Blocking call to {@link EuiccService#onGetEuiccProfileInfoList} of the eUICC with card ID
* {@code cardId}.
*
* <p>Does not perform permission checks as this is not an exposed API and is only used within
* the phone process.
*/
public GetEuiccProfileInfoListResult blockingGetEuiccProfileInfoList(int cardId) {
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<GetEuiccProfileInfoListResult> resultRef = new AtomicReference<>();
mConnector.getEuiccProfileInfoList(cardId, new EuiccConnector.GetEuiccProfileInfoListCommandCallback() {
@Override
public void onListComplete(GetEuiccProfileInfoListResult result) {
resultRef.set(result);
latch.countDown();
}
@Override
public void onEuiccServiceUnavailable() {
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
Log.e(TAG, "blockingGetEuiccInfoFromEuiccService got InterruptedException e: " + e);
Thread.currentThread().interrupt();
}
return resultRef.get();
}
Aggregations