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

Commit 97402b0c authored by Jack Yu's avatar Jack Yu Committed by Gerrit Code Review
Browse files

Merge changes I3a7cbcda,If99f0873,I8567714c,I35510311 into main

* changes:
  Fixed crash when LPA is not available
  Fixed phone number showed in bugreport
  Fixed port index not updated on inactive eSIM
  Migrated unit test to the new subscription manager
parents 4d167cc5 d0e8f88a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -839,6 +839,7 @@ public class MultiSimSettingController extends Handler {
        @TelephonyManager.DefaultSubscriptionSelectType
        int simSelectDialogType = getSimSelectDialogType(
                change, dataSelected, voiceSelected, smsSelected);
        log("sendSubChangeNotificationIfNeeded: simSelectDialogType=" + simSelectDialogType);
        SimCombinationWarningParams simCombinationParams = getSimCombinationWarningParams(change);

        if (simSelectDialogType != EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE
+11 −7
Original line number Diff line number Diff line
@@ -1815,13 +1815,14 @@ public class SubscriptionDatabaseManager extends Handler {
     * Load the database from content provider to the cache.
     */
    private void loadDatabaseInternal() {
        logl("loadDatabaseInternal");
        log("loadDatabaseInternal");
        try (Cursor cursor = mContext.getContentResolver().query(
                SimInfo.CONTENT_URI, null, null, null, null)) {
            mReadWriteLock.writeLock().lock();
            try {
                Map<Integer, SubscriptionInfoInternal> newAllSubscriptionInfoInternalCache =
                        new HashMap<>();
                boolean changed = false;
                while (cursor != null && cursor.moveToNext()) {
                    SubscriptionInfoInternal subInfo = createSubscriptionInfoFromCursor(cursor);
                    newAllSubscriptionInfoInternalCache.put(subInfo.getSubscriptionId(), subInfo);
@@ -1829,9 +1830,11 @@ public class SubscriptionDatabaseManager extends Handler {
                            .get(subInfo.getSubscriptionId()), subInfo)) {
                        mCallback.invokeFromExecutor(() -> mCallback.onSubscriptionChanged(
                                subInfo.getSubscriptionId()));
                        changed = true;
                    }
                }

                if (changed) {
                    mAllSubscriptionInfoInternalCache.clear();
                    mAllSubscriptionInfoInternalCache.putAll(newAllSubscriptionInfoInternalCache);

@@ -1839,6 +1842,7 @@ public class SubscriptionDatabaseManager extends Handler {
                            + " records from the subscription database.");
                    mAllSubscriptionInfoInternalCache.forEach(
                            (subId, subInfo) -> log("  " + subInfo.toString()));
                }
            } finally {
                mReadWriteLock.writeLock().unlock();
            }
+2 −2
Original line number Diff line number Diff line
@@ -1113,8 +1113,8 @@ public class SubscriptionInfoInternal {
                + " deviceToDeviceStatusSharingPreference=" + mDeviceToDeviceStatusSharingPreference
                + " isVoImsOptInEnabled=" + mIsVoImsOptInEnabled
                + " deviceToDeviceStatusSharingContacts=" + mDeviceToDeviceStatusSharingContacts
                + " numberFromCarrier=" + mNumberFromCarrier
                + " numberFromIms=" + mNumberFromIms
                + " numberFromCarrier=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mNumberFromCarrier)
                + " numberFromIms=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mNumberFromIms)
                + " userId=" + mUserId
                + " isSatelliteEnabled=" + mIsSatelliteEnabled
                + " isGroupDisabled=" + mIsGroupDisabled
+79 −50
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccPort;
import com.android.internal.telephony.uicc.UiccSlot;
import com.android.internal.telephony.util.ArrayUtils;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.telephony.Rlog;

import java.io.FileDescriptor;
@@ -387,6 +388,7 @@ public class SubscriptionManagerService extends ISub.Stub {
     * @param looper The looper for the handler.
     */
    public SubscriptionManagerService(@NonNull Context context, @NonNull Looper looper) {
        logl("Created SubscriptionManagerService");
        sInstance = this;
        mContext = context;
        mTelephonyManager = context.getSystemService(TelephonyManager.class);
@@ -537,16 +539,16 @@ public class SubscriptionManagerService extends ISub.Stub {
            }
        });

        SubscriptionManager.invalidateSubscriptionManagerServiceCaches();
        SubscriptionManager.invalidateSubscriptionManagerServiceEnabledCaches();

        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                updateEmbeddedSubscriptions();
            }
        }, new IntentFilter(Intent.ACTION_USER_UNLOCKED));

        SubscriptionManager.invalidateSubscriptionManagerServiceCaches();
        SubscriptionManager.invalidateSubscriptionManagerServiceEnabledCaches();
        logl("created");
        logl("Registered iSub service");
    }

    /**
@@ -899,9 +901,11 @@ public class SubscriptionManagerService extends ISub.Stub {
                .forEach(subInfo -> {
                    mSubscriptionDatabaseManager.setSimSlotIndex(subInfo.getSubscriptionId(),
                            SubscriptionManager.INVALID_SIM_SLOT_INDEX);
                    mSubscriptionDatabaseManager.setPortIndex(subInfo.getSubscriptionId(),
                            TelephonyManager.INVALID_PORT_INDEX);
                });
        updateGroupDisabled();
        logl("markSubscriptionsInactive: " + slotMappingToString());
        logl("markSubscriptionsInactive: current mapping " + slotMappingToString());
    }

    /**
@@ -937,17 +941,19 @@ public class SubscriptionManagerService extends ISub.Stub {
    }

    /**
     * Get the embedded profile port index by ICCID.
     * Get the port index by ICCID.
     *
     * @param iccId The ICCID.
     * @return The port index.
     */
    private int getEmbeddedProfilePortIndex(String iccId) {
        UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
    private int getPortIndex(@NonNull String iccId) {
        UiccSlot[] slots = mUiccController.getUiccSlots();
        for (UiccSlot slot : slots) {
            if (slot != null && slot.isEuicc()
                    && slot.getPortIndexFromIccId(iccId) != TelephonyManager.INVALID_PORT_INDEX) {
                return slot.getPortIndexFromIccId(iccId);
            if (slot != null) {
                int portIndex = slot.getPortIndexFromIccId(iccId);
                if (portIndex != TelephonyManager.INVALID_PORT_INDEX) {
                    return portIndex;
                }
            }
        }
        return TelephonyManager.INVALID_PORT_INDEX;
@@ -995,7 +1001,7 @@ public class SubscriptionManagerService extends ISub.Stub {
        mBackgroundHandler.post(() -> {
            // Do nothing if eUICCs are disabled. (Previous entries may remain in the cache, but
            // they are filtered out of list calls as long as EuiccManager.isEnabled returns false).
            if (mEuiccManager == null || !mEuiccManager.isEnabled()) {
            if (mEuiccManager == null || !mEuiccManager.isEnabled() || mEuiccController == null) {
                loge("updateEmbeddedSubscriptions: eUICC not enabled");
                if (callback != null) {
                    callback.run();
@@ -1005,10 +1011,22 @@ public class SubscriptionManagerService extends ISub.Stub {

            Set<Integer> embeddedSubs = new ArraySet<>();
            log("updateEmbeddedSubscriptions: start to get euicc profiles.");

            for (UiccSlot slot : mUiccController.getUiccSlots()) {
                if (slot != null) {
                    log("  " + slot);
                }
            }

            for (int cardId : cardIds) {
                GetEuiccProfileInfoListResult result = mEuiccController
                        .blockingGetEuiccProfileInfoList(cardId);
                logl("updateEmbeddedSubscriptions: cardId=" + cardId + ", result=" + result);
                if (result == null) {
                    //TODO: Add back-off retry in the future if needed.
                    loge("Failed to get euicc profiles.");
                    continue;
                }

                if (result.getResult() != EuiccService.RESULT_OK) {
                    loge("Failed to get euicc profile info. result="
@@ -1056,7 +1074,7 @@ public class SubscriptionManagerService extends ISub.Stub {
                        builder.setDisplayNameSource(SubscriptionManager.NAME_SOURCE_CARRIER);
                    }
                    builder.setProfileClass(embeddedProfile.getProfileClass());
                    builder.setPortIndex(getEmbeddedProfilePortIndex(embeddedProfile.getIccid()));
                    builder.setPortIndex(getPortIndex(embeddedProfile.getIccid()));

                    CarrierIdentifier cid = embeddedProfile.getCarrierIdentifier();
                    if (cid != null) {
@@ -1197,7 +1215,7 @@ public class SubscriptionManagerService extends ISub.Stub {
            }

            if (mSimState[phoneId] == TelephonyManager.SIM_STATE_UNKNOWN) {
                log("areAllSubscriptionsLoaded: SIM state is still unknown.");
                log("areAllSubscriptionsLoaded: SIM " + phoneId + " state is still unknown.");
                return false;
            }
        }
@@ -1206,20 +1224,26 @@ public class SubscriptionManagerService extends ISub.Stub {
    }

    /**
     * Update the subscriptions on the logical SIM slot index (i.e. phone id).
     * Update the subscription on the logical SIM slot index (i.e. phone id).
     *
     * @param phoneId The phone id (i.e. Logical SIM slot index)
     */
    private void updateSubscriptions(int phoneId) {
    private void updateSubscription(int phoneId) {
        int simState = mSimState[phoneId];
        log("updateSubscriptions: phoneId=" + phoneId + ", simState="
        log("updateSubscription: phoneId=" + phoneId + ", simState="
                + TelephonyManager.simStateToString(simState));
        for (UiccSlot slot : mUiccController.getUiccSlots()) {
            if (slot != null) {
                log("  " + slot.toString());
            }
        }

        if (simState == TelephonyManager.SIM_STATE_ABSENT) {
            if (mSlotIndexToSubId.containsKey(phoneId)) {
                int subId = mSlotIndexToSubId.get(phoneId);
                // Re-enable the SIM when it's removed, so it will be in enabled state when it gets
                // re-inserted again. (pre-U behavior)
                log("updateSubscriptions: Re-enable Uicc application on sub " + subId);
                log("updateSubscription: Re-enable Uicc application on sub " + subId);
                mSubscriptionDatabaseManager.setUiccApplicationsEnabled(subId, true);
                // When sim is absent, set the port index to invalid port index. (pre-U behavior)
                mSubscriptionDatabaseManager.setPortIndex(subId,
@@ -1231,45 +1255,49 @@ public class SubscriptionManagerService extends ISub.Stub {
            // final state.
            IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
            if (!iccCard.isEmptyProfile() && areUiccAppsEnabledOnCard(phoneId)) {
                log("updateSubscriptions: SIM_STATE_NOT_READY is not a final state. Will update "
                log("updateSubscription: SIM_STATE_NOT_READY is not a final state. Will update "
                        + "subscription later.");
                return;
            }

            if (!areUiccAppsEnabledOnCard(phoneId)) {
                logl("updateSubscriptions: UICC app disabled on slot " + phoneId);
                logl("updateSubscription: UICC app disabled on slot " + phoneId);
                markSubscriptionsInactive(phoneId);
            }
        }

        String iccId = getIccId(phoneId);
        log("updateSubscriptions: Found iccId=" + SubscriptionInfo.givePrintableIccid(iccId)
        log("updateSubscription: Found iccId=" + SubscriptionInfo.givePrintableIccid(iccId)
                + " on phone " + phoneId);

        // For eSIM switching, SIM absent will not happen. Below is to exam if we find ICCID
        // mismatch on the SIM slot, we need to mark all subscriptions on that logical slot invalid
        // first. The correct subscription will be assigned the correct slot later.
        if (mSubscriptionDatabaseManager.getAllSubscriptions().stream()
                .anyMatch(subInfo -> subInfo.getSimSlotIndex() == phoneId
                        && !iccId.equals(subInfo.getIccId()))) {
            log("updateSubscriptions: iccId changed for phone " + phoneId);
        // mismatch on the SIM slot. If that's the case, we need to mark all subscriptions on that
        // logical slot invalid first. The correct subscription will be assigned the correct slot
        // later.
        SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager.getAllSubscriptions()
                .stream()
                .filter(sub -> sub.getSimSlotIndex() == phoneId && !iccId.equals(sub.getIccId()))
                .findFirst()
                .orElse(null);
        if (subInfo != null) {
            log("updateSubscription: Found previous active sub " + subInfo.getSubscriptionId()
                    + " that doesn't match current iccid on slot " + phoneId + ".");
            markSubscriptionsInactive(phoneId);
        }

        if (!TextUtils.isEmpty(iccId)) {
            // Check if the subscription already existed.
            SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager
                    .getSubscriptionInfoInternalByIccId(iccId);
            subInfo = mSubscriptionDatabaseManager.getSubscriptionInfoInternalByIccId(iccId);
            int subId;
            if (subInfo == null) {
                // This is a new SIM card. Insert a new record.
                subId = insertSubscriptionInfo(iccId, phoneId, null,
                        SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
                logl("updateSubscriptions: Inserted a new subscription. subId=" + subId
                logl("updateSubscription: Inserted a new subscription. subId=" + subId
                        + ", phoneId=" + phoneId);
            } else {
                subId = subInfo.getSubscriptionId();
                log("updateSubscriptions: Found existing subscription. subId= " + subId
                log("updateSubscription: Found existing subscription. subId= " + subId
                        + ", phoneId=" + phoneId);
            }

@@ -1278,7 +1306,7 @@ public class SubscriptionManagerService extends ISub.Stub {
                mSlotIndexToSubId.put(phoneId, subId);
                // Update the SIM slot index. This will make the subscription active.
                mSubscriptionDatabaseManager.setSimSlotIndex(subId, phoneId);
                logl("updateSubscriptions: " + slotMappingToString());
                logl("updateSubscription: current mapping " + slotMappingToString());
            }

            // Update the card id.
@@ -1291,11 +1319,7 @@ public class SubscriptionManagerService extends ISub.Stub {
            }

            // Update the port index.
            UiccSlot slot = mUiccController.getUiccSlotForPhone(phoneId);
            if (slot != null && !slot.isEuicc()) {
                int portIndex = slot.getPortIndexFromIccId(iccId);
                mSubscriptionDatabaseManager.setPortIndex(subId, portIndex);
            }
            mSubscriptionDatabaseManager.setPortIndex(subId, getPortIndex(iccId));

            if (simState == TelephonyManager.SIM_STATE_LOADED) {
                String mccMnc = mTelephonyManager.getSimOperatorNumeric(subId);
@@ -1305,7 +1329,7 @@ public class SubscriptionManagerService extends ISub.Stub {
                    }
                    setMccMnc(subId, mccMnc);
                } else {
                    loge("updateSubscriptions: mcc/mnc is empty");
                    loge("updateSubscription: mcc/mnc is empty");
                }

                String iso = TelephonyManager.getSimCountryIsoForPhone(phoneId);
@@ -1313,7 +1337,7 @@ public class SubscriptionManagerService extends ISub.Stub {
                if (!TextUtils.isEmpty(iso)) {
                    setCountryIso(subId, iso);
                } else {
                    loge("updateSubscriptions: sim country iso is null");
                    loge("updateSubscription: sim country iso is null");
                }

                String msisdn = mTelephonyManager.getLine1Number(subId);
@@ -1339,10 +1363,10 @@ public class SubscriptionManagerService extends ISub.Stub {
                            mSubscriptionDatabaseManager.setHplmns(subId, hplmns);
                        }
                    } else {
                        loge("updateSubscriptions: ICC records are not available.");
                        loge("updateSubscription: ICC records are not available.");
                    }
                } else {
                    loge("updateSubscriptions: ICC card is not available.");
                    loge("updateSubscription: ICC card is not available.");
                }

                // Attempt to restore SIM specific settings when SIM is loaded.
@@ -1350,12 +1374,16 @@ public class SubscriptionManagerService extends ISub.Stub {
                        SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
                        SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
                        iccId, null);
                log("Reload the database.");
                mSubscriptionDatabaseManager.reloadDatabase();
            }

            log("updateSubscription: " + mSubscriptionDatabaseManager
                    .getSubscriptionInfoInternal(subId));
        } else {
            log("updateSubscriptions: No ICCID available for phone " + phoneId);
            log("updateSubscription: No ICCID available for phone " + phoneId);
            mSlotIndexToSubId.remove(phoneId);
            logl("updateSubscriptions: " + slotMappingToString());
            logl("updateSubscription: current mapping " + slotMappingToString());
        }

        if (areAllSubscriptionsLoaded()) {
@@ -1922,7 +1950,7 @@ public class SubscriptionManagerService extends ISub.Stub {
                int subId = insertSubscriptionInfo(iccId, slotIndex, displayName, subscriptionType);
                updateGroupDisabled();
                mSlotIndexToSubId.put(slotIndex, subId);
                logl("addSubInfo: " + slotMappingToString());
                logl("addSubInfo: current mapping " + slotMappingToString());
            } else {
                // Record already exists.
                loge("Subscription record already existed.");
@@ -2109,7 +2137,8 @@ public class SubscriptionManagerService extends ISub.Stub {
    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
    public int setDisplayNumber(@NonNull String number, int subId) {
        enforcePermissions("setDisplayNumber", Manifest.permission.MODIFY_PHONE_STATE);
        logl("setDisplayNumber: subId=" + subId + ", number=" + number
        logl("setDisplayNumber: subId=" + subId + ", number="
                + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, number)
                + ", calling package=" + getCallingPackage());
        // Now that all security checks passes, perform the operation as ourselves.
        final long identity = Binder.clearCallingIdentity();
@@ -3728,7 +3757,7 @@ public class SubscriptionManagerService extends ISub.Stub {
                // active again. (pre-U behavior)
                mSubscriptionDatabaseManager.setUiccApplicationsEnabled(
                        mSlotIndexToSubId.get(slotIndex), true);
                updateSubscriptions(slotIndex);
                updateSubscription(slotIndex);
            }
        });
    }
@@ -3760,7 +3789,7 @@ public class SubscriptionManagerService extends ISub.Stub {
                case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
                case TelephonyManager.SIM_STATE_LOADED:
                case TelephonyManager.SIM_STATE_NOT_READY:
                    updateSubscriptions(slotIndex);
                    updateSubscription(slotIndex);
                    break;
                case TelephonyManager.SIM_STATE_CARD_RESTRICTED:
                default:
@@ -3816,9 +3845,9 @@ public class SubscriptionManagerService extends ISub.Stub {
     */
    @NonNull
    private String slotMappingToString() {
        return mSlotIndexToSubId.entrySet().stream()
                .map(e -> "Slot " + e.getKey() + ": subId=" + e.getValue())
                .collect(Collectors.joining(", "));
        return "[" + mSlotIndexToSubId.entrySet().stream()
                .map(e -> "slot " + e.getKey() + ": subId=" + e.getValue())
                .collect(Collectors.joining(", ")) + "]";
    }

    /**
+11 −7
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager.SimState;
import android.util.Base64;
import android.util.IndentingPrintWriter;
import android.util.SparseArray;

import com.android.internal.R;
@@ -1205,8 +1206,10 @@ public class PinStorage extends Handler {
        Rlog.e(TAG, msg, tr);
    }

    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
        pw.println("PinStorage:");
        pw.increaseIndent();
        pw.println("mIsDeviceSecure=" + mIsDeviceSecure);
        pw.println("mIsDeviceLocked=" + mIsDeviceLocked);
        pw.println("isLongTermSecretKey=" + (boolean) (mLongTermSecretKey != null));
@@ -1222,5 +1225,6 @@ public class PinStorage extends Handler {
                pw.println(" pin=" + storedPins.valueAt(i).toString());
            }
        }
        pw.decreaseIndent();
    }
}
Loading