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

Commit 71637f55 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 10439448 from b512e0a3 to udc-qpr1-release

Change-Id: Ib99a7d6b254cf27eae1c6d1149d6d1327fb5397d
parents 2f3ec8e6 b512e0a3
Loading
Loading
Loading
Loading
+64 −18
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.stream.Stream;

/**
 * {@hide}
@@ -2539,10 +2540,6 @@ public class ImsPhone extends ImsPhoneBase {
    /** Sets the IMS phone number from IMS associated URIs, if any found. */
    @VisibleForTesting
    public void setPhoneNumberForSourceIms(Uri[] uris) {
        String phoneNumber = extractPhoneNumberFromAssociatedUris(uris);
        if (phoneNumber == null) {
            return;
        }
        int subId = getSubId();
        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
            // Defending b/219080264:
@@ -2551,16 +2548,33 @@ public class ImsPhone extends ImsPhoneBase {
            // IMS callbacks are sent back to telephony after SIM state changed.
            return;
        }

        SubscriptionInfoInternal subInfo = mSubscriptionManagerService
                .getSubscriptionInfoInternal(subId);
        if (subInfo != null) {
            phoneNumber = PhoneNumberUtils.formatNumberToE164(phoneNumber,
                    subInfo.getCountryIso());
        if (subInfo == null) {
            loge("trigger setPhoneNumberForSourceIms, but subInfo is null");
            return;
        }
        String subCountryIso = subInfo.getCountryIso();
        String phoneNumber = extractPhoneNumberFromAssociatedUris(uris, /*isGlobalFormat*/true);
        if (phoneNumber != null) {
            phoneNumber = PhoneNumberUtils.formatNumberToE164(phoneNumber, subCountryIso);
            if (phoneNumber == null) {
                loge("format to E164 failed");
                return;
            }
            mSubscriptionManagerService.setNumberFromIms(subId, phoneNumber);
        } else if (isAllowNonGlobalNumberFormat()) {
            // If carrier config has true for KEY_IGNORE_GLOBAL_PHONE_NUMBER_FORMAT_BOOL and
            // P-Associated-Uri does not have global number,
            // try to find phone number excluding '+' one more time.
            phoneNumber = extractPhoneNumberFromAssociatedUris(uris, /*isGlobalFormat*/false);
            if (phoneNumber == null) {
                loge("extract phone number without '+' failed");
                return;
            }
            mSubscriptionManagerService.setNumberFromIms(subId, phoneNumber);
        } else {
            logd("extract phone number failed");
        }
    }

@@ -2570,24 +2584,40 @@ public class ImsPhone extends ImsPhoneBase {
     * <p>Associated URIs are public user identities, and phone number could be used:
     * see 3GPP TS 24.229 5.4.1.2 and 3GPP TS 23.003 13.4. This algotihm look for the
     * possible "global number" in E.164 format.
     * <p>If true try finding phone number even if the P-Associated-Uri does not have global
     * number format.
     */
    private static String extractPhoneNumberFromAssociatedUris(Uri[] uris) {
    private static String extractPhoneNumberFromAssociatedUris(Uri[] uris, boolean isGlobalFormat) {
        if (uris == null) {
            return null;
        }
        return Arrays.stream(uris)

        Stream<String> intermediate = Arrays.stream(uris)
                // Phone number is an opaque URI "tel:<phone-number>" or "sip:<phone-number>@<...>"
                .filter(u -> u != null && u.isOpaque())
                .filter(u -> "tel".equalsIgnoreCase(u.getScheme())
                        || "sip".equalsIgnoreCase(u.getScheme()))
                .map(Uri::getSchemeSpecificPart)
                .map(Uri::getSchemeSpecificPart);

        if (isGlobalFormat) {
            // "Global number" should be in E.164 format starting with "+" e.g. "+447539447777"
                .filter(ssp -> ssp != null && ssp.startsWith("+"))
            return intermediate.filter(ssp -> ssp != null && ssp.startsWith("+"))
                    // Remove whatever after "@" for sip URI
                    .map(ssp -> ssp.split("@")[0])
                    // Returns the first winner
                    .findFirst()
                    .orElse(null);
        } else {
            // non global number format
            return intermediate.filter(ssp -> ssp != null)
                    // Remove whatever after "@" for sip URI
                    .map(ssp -> ssp.split("@")[0])
                    // regular expression, allow only number
                    .filter(ssp -> ssp.matches("^[0-9]+$"))
                    // Returns the first winner
                    .findFirst()
                    .orElse(null);
        }
    }

    public IccRecords getIccRecords() {
@@ -2790,6 +2820,22 @@ public class ImsPhone extends ImsPhoneBase {
        pw.flush();
    }

    private boolean isAllowNonGlobalNumberFormat() {
        PersistableBundle persistableBundle = null;
        CarrierConfigManager carrierConfigManager = (CarrierConfigManager) mContext
                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
        if (carrierConfigManager != null) {
            persistableBundle = carrierConfigManager.getConfigForSubId(getSubId(),
                    CarrierConfigManager.Ims.KEY_ALLOW_NON_GLOBAL_PHONE_NUMBER_FORMAT_BOOL);
        }
        if (persistableBundle != null) {
            return persistableBundle.getBoolean(
                    CarrierConfigManager.Ims.KEY_ALLOW_NON_GLOBAL_PHONE_NUMBER_FORMAT_BOOL, false);
        }

        return false;
    }

    private void logi(String s) {
        Rlog.i(LOG_TAG, "[" + mPhoneId + "] " + s);
    }
+62 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -1049,6 +1050,67 @@ public class ImsPhoneTest extends TelephonyTest {
        mContextFixture.addCallingOrSelfPermission("");
    }

    @Test
    @SmallTest
    public void testSetPhoneNumberForSourceIgnoreGlobalPhoneNumberFormat() {
        // In reality the method under test runs in phone process so has MODIFY_PHONE_STATE
        mContextFixture.addCallingOrSelfPermission(MODIFY_PHONE_STATE);
        int subId = 1;
        doReturn(subId).when(mPhone).getSubId();
        doReturn(new SubscriptionInfoInternal.Builder().setId(subId).setSimSlotIndex(0)
                .setCountryIso("gb").build()).when(mSubscriptionManagerService)
                .getSubscriptionInfoInternal(subId);
        // Set carrier config to ignore global phone number format
        PersistableBundle bundle = new PersistableBundle();
        bundle.putBoolean(
                CarrierConfigManager.Ims.KEY_ALLOW_NON_GLOBAL_PHONE_NUMBER_FORMAT_BOOL, true);
        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(eq(subId),
                eq(CarrierConfigManager.Ims.KEY_ALLOW_NON_GLOBAL_PHONE_NUMBER_FORMAT_BOOL));

        // 1. Two non-global phone number; 1st is set.
        Uri[] associatedUris = new Uri[] {
                Uri.parse("sip:01012345678@lte-uplus.co.kr"),
                Uri.parse("tel:01012345678")
        };
        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);

        verify(mSubscriptionManagerService).setNumberFromIms(subId, "01012345678");

        // 2. 1st non-global phone number and 2nd global number; 2nd is set.
        associatedUris = new Uri[] {
                Uri.parse("sip:01012345678@lte-uplus.co.kr"),
                Uri.parse("tel:+821012345678")
        };
        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);

        verify(mSubscriptionManagerService).setNumberFromIms(subId, "+821012345678");

        // 3. 1st sip-uri is not phone number and 2nd valid: 2nd is set.
        associatedUris = new Uri[] {
                Uri.parse("sip:john.doe@ims.x.com"),
                Uri.parse("sip:01022223333@lte-uplus.co.kr"),
                Uri.parse("tel:01022223333")
        };
        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);

        verify(mSubscriptionManagerService).setNumberFromIms(subId, "01022223333");

        clearInvocations(mSubscriptionManagerService);

        // 4. Invalid phone number : not set.
        associatedUris = new Uri[] {
                Uri.parse("sip:john.doe@ims.x.com"),
                Uri.parse("sip:hone3333@lte-uplus.co.kr"),
                Uri.parse("tel:abcd1234555")
        };
        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);

        verify(mSubscriptionManagerService, never()).setNumberFromIms(anyInt(), anyString());

        // Clean up
        mContextFixture.addCallingOrSelfPermission("");
    }

    /**
     * Verifies that valid radio technology is passed to RIL
     * when IMS registration state changes to registered.