Search in sources :

Example 1 with GetEuiccProfileInfoListResult

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;
}
Also used : ContentValues(android.content.ContentValues) ArrayList(java.util.ArrayList) SubscriptionInfo(android.telephony.SubscriptionInfo) ContentResolver(android.content.ContentResolver) EuiccProfileInfo(android.service.euicc.EuiccProfileInfo) GetEuiccProfileInfoListResult(android.service.euicc.GetEuiccProfileInfoListResult) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Example 2 with GetEuiccProfileInfoListResult

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);
            }
        });
    });
}
Also used : GetEuiccProfileInfoListResult(android.service.euicc.GetEuiccProfileInfoListResult) ArrayList(java.util.ArrayList) Pair(android.util.Pair) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Example 3 with GetEuiccProfileInfoListResult

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());
}
Also used : GetEuiccProfileInfoListResult(android.service.euicc.GetEuiccProfileInfoListResult) ArrayList(java.util.ArrayList) SubscriptionInfo(android.telephony.SubscriptionInfo) SmallTest(android.test.suitebuilder.annotation.SmallTest) Test(org.junit.Test) SmallTest(android.test.suitebuilder.annotation.SmallTest)

Example 4 with GetEuiccProfileInfoListResult

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();
}
Also used : GetEuiccProfileInfoListResult(android.service.euicc.GetEuiccProfileInfoListResult) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 5 with GetEuiccProfileInfoListResult

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();
}
Also used : GetEuiccProfileInfoListResult(android.service.euicc.GetEuiccProfileInfoListResult) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch)

Aggregations

GetEuiccProfileInfoListResult (android.service.euicc.GetEuiccProfileInfoListResult)7 ArrayList (java.util.ArrayList)5 SubscriptionInfo (android.telephony.SubscriptionInfo)4 SmallTest (android.test.suitebuilder.annotation.SmallTest)3 Test (org.junit.Test)3 ContentValues (android.content.ContentValues)2 EuiccProfileInfo (android.service.euicc.EuiccProfileInfo)2 VisibleForTesting (com.android.internal.annotations.VisibleForTesting)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 ContentResolver (android.content.ContentResolver)1 Pair (android.util.Pair)1