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

Commit 8d825a11 authored by Meng Wang's avatar Meng Wang Committed by Automerger Merge Worker
Browse files

Merge changes from topic "phonenumber" am: b2c75c45 am: a30fc092

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/1920745

Change-Id: I45616a3a6ca8f9074942f55a9fd28f1c723e1877
parents 433c0c9b a30fc092
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.telephony.imsphone;

import static android.provider.Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS;
import static android.telephony.ims.ImsManager.EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE;
import static android.telephony.ims.ImsManager.EXTRA_WFC_REGISTRATION_FAILURE_TITLE;

@@ -70,6 +71,7 @@ import android.telephony.CarrierConfigManager;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.UssdResponse;
@@ -105,6 +107,7 @@ import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneNotifier;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.TelephonyComponentFactory;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.dataconnection.TransportManager;
@@ -122,6 +125,7 @@ import com.android.telephony.Rlog;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

@@ -2485,9 +2489,62 @@ public class ImsPhone extends ImsPhoneBase {
        public void handleImsSubscriberAssociatedUriChanged(Uri[] uris) {
            if (DBG) logd("handleImsSubscriberAssociatedUriChanged");
            setCurrentSubscriberUris(uris);
            setPhoneNumberForSourceIms(uris);
        }
    };

    /** 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;
        }
        SubscriptionController subController = SubscriptionController.getInstance();
        int subId = getSubId();
        String countryIso = getCountryIso(subController, subId);
        // Format the number as one more defense to reject garbage values:
        // phoneNumber will become null.
        phoneNumber = PhoneNumberUtils.formatNumberToE164(phoneNumber, countryIso);
        if (phoneNumber == null) {
            return;
        }
        subController.setSubscriptionProperty(subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, phoneNumber);
    }

    private static String getCountryIso(SubscriptionController subController, int subId) {
        SubscriptionInfo info = subController.getSubscriptionInfo(subId);
        String countryIso = info == null ? "" : info.getCountryIso();
        // info.getCountryIso() may return null
        return countryIso == null ? "" : countryIso;
    }

    /**
     * Finds the phone number from associated URIs.
     *
     * <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.
     */
    private static String extractPhoneNumberFromAssociatedUris(Uri[] uris) {
        if (uris == null) {
            return null;
        }
        return 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)
                // "Global number" should be in E.164 format starting with "+" e.g. "+447539447777"
                .filter(ssp -> ssp != null && ssp.startsWith("+"))
                // Remove whatever after "@" for sip URI
                .map(ssp -> ssp.split("@")[0])
                // Returns the first winner
                .findFirst()
                .orElse(null);
    }

    public IccRecords getIccRecords() {
        return mDefaultPhone.getIccRecords();
    }
+96 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.telephony.imsphone;

import static android.Manifest.permission.MODIFY_PHONE_STATE;
import static android.provider.Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS;
import static android.telephony.CarrierConfigManager.USSD_OVER_CS_ONLY;
import static android.telephony.CarrierConfigManager.USSD_OVER_CS_PREFERRED;
import static android.telephony.CarrierConfigManager.USSD_OVER_IMS_ONLY;
@@ -40,6 +42,7 @@ import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
@@ -49,6 +52,7 @@ import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
@@ -57,6 +61,7 @@ import android.os.PersistableBundle;
import android.sysprop.TelephonyProperties;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsReasonInfo;
@@ -976,6 +981,97 @@ public class ImsPhoneTest extends TelephonyTest {
        mImsPhoneUT.handleMessage(m);
    }

    @Test
    @SmallTest
    public void testSetPhoneNumberForSourceIms() {
        // 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();
        SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
        doReturn("gb").when(subInfo).getCountryIso();
        doReturn(subInfo).when(mSubscriptionController).getSubscriptionInfo(subId);

        // 1. Two valid phone number; 1st is set.
        Uri[] associatedUris = new Uri[] {
            Uri.parse("sip:+447539447777@ims.x.com"),
            Uri.parse("tel:+447539446666")
        };
        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);

        verify(mSubscriptionController).setSubscriptionProperty(
                subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, "+447539447777");

        // 2. 1st invalid and 2nd valid: 2nd is set.
        associatedUris = new Uri[] {
            Uri.parse("sip:447539447777@ims.x.com"),
            Uri.parse("tel:+447539446666")
        };
        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);

        verify(mSubscriptionController).setSubscriptionProperty(
                subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, "+447539446666");

        // 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("tel:+447539446677"),
            Uri.parse("sip:+447539447766@ims.x.com")
        };
        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);

        verify(mSubscriptionController).setSubscriptionProperty(
                subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, "+447539446677");

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

    @Test
    @SmallTest
    public void testSetPhoneNumberForSourceImsNegativeCases() {
        // 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();
        SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
        doReturn("gb").when(subInfo).getCountryIso();
        doReturn(subInfo).when(mSubscriptionController).getSubscriptionInfo(subId);

        // 1. No valid phone number; do not set
        Uri[] associatedUris = new Uri[] {
            Uri.parse("sip:447539447777@ims.x.com"),
            Uri.parse("tel:447539446666")
        };
        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);

        verify(mSubscriptionController, never()).setSubscriptionProperty(
                anyInt(), any(), any());

        // 2. no URI; do not set
        associatedUris = new Uri[] {};
        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);

        verify(mSubscriptionController, never()).setSubscriptionProperty(
                anyInt(), any(), any());

        // 3. null URI; do not set
        associatedUris = new Uri[] { null };
        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);

        verify(mSubscriptionController, never()).setSubscriptionProperty(
                anyInt(), any(), any());

        // 4. null pointer; do not set
        mImsPhoneUT.setPhoneNumberForSourceIms(null);

        verify(mSubscriptionController, never()).setSubscriptionProperty(
                anyInt(), any(), any());

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

    private ServiceState getServiceStateDataAndVoice(int rat, int regState, boolean isRoaming) {
        ServiceState ss = new ServiceState();
        ss.setStateOutOfService();