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

Commit b158b12c authored by Shuo Qian's avatar Shuo Qian Committed by Gerrit Code Review
Browse files

Merge "EmergencyNumber enhancement"

parents cfc6518c 46c0c303
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -42609,10 +42609,10 @@ package android.telephony {
    method public static java.lang.String getStrippedReversed(java.lang.String);
    method public static final boolean is12Key(char);
    method public static final boolean isDialable(char);
    method public static boolean isEmergencyNumber(java.lang.String);
    method public static deprecated boolean isEmergencyNumber(java.lang.String);
    method public static boolean isGlobalPhoneNumber(java.lang.String);
    method public static boolean isISODigit(char);
    method public static boolean isLocalEmergencyNumber(android.content.Context, java.lang.String);
    method public static deprecated boolean isLocalEmergencyNumber(android.content.Context, java.lang.String);
    method public static final boolean isNonSeparator(char);
    method public static final boolean isReallyDialable(char);
    method public static final boolean isStartsPostDial(char);
@@ -43328,11 +43328,13 @@ package android.telephony.emergency {
    method public java.util.List<java.lang.Integer> getEmergencyNumberSources();
    method public java.util.List<java.lang.Integer> getEmergencyServiceCategories();
    method public int getEmergencyServiceCategoryBitmask();
    method public java.lang.String getMnc();
    method public java.lang.String getNumber();
    method public boolean isFromSources(int);
    method public boolean isInEmergencyServiceCategories(int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.telephony.emergency.EmergencyNumber> CREATOR;
    field public static final int EMERGENCY_NUMBER_SOURCE_DATABASE = 16; // 0x10
    field public static final int EMERGENCY_NUMBER_SOURCE_DEFAULT = 8; // 0x8
    field public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG = 4; // 0x4
    field public static final int EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING = 1; // 0x1
+1 −0
Original line number Diff line number Diff line
@@ -5470,6 +5470,7 @@ package android.telephony {
    method public int getVoiceActivationState();
    method public boolean handlePinMmi(java.lang.String);
    method public boolean handlePinMmiForSubscriber(int, java.lang.String);
    method public boolean isCurrentPotentialEmergencyNumber(java.lang.String);
    method public boolean isDataConnectivityPossible();
    method public deprecated boolean isIdle();
    method public deprecated boolean isOffhook();
+40 −6
Original line number Diff line number Diff line
@@ -67,7 +67,9 @@ import com.android.server.am.BatteryStatsService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
@@ -196,6 +198,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {

    private ArrayList<List<PhysicalChannelConfig>> mPhysicalChannelConfigs;

    private Map<Integer, List<EmergencyNumber>> mEmergencyNumberList;

    private int[] mSrvccState;

    private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -233,8 +237,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
                    | PhoneStateListener.LISTEN_CELL_INFO;

    static final int ENFORCE_PHONE_STATE_PERMISSION_MASK =
                PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
                PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
                PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
                        | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
                        | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST;

    static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
                PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
@@ -361,6 +366,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
        mCellInfo = new ArrayList<List<CellInfo>>();
        mSrvccState = new int[numPhones];
        mPhysicalChannelConfigs = new ArrayList<List<PhysicalChannelConfig>>();
        mEmergencyNumberList = new HashMap<>();
        for (int i = 0; i < numPhones; i++) {
            mCallState[i] =  TelephonyManager.CALL_STATE_IDLE;
            mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
@@ -764,6 +770,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
                            remove(r.binder);
                        }
                    }
                    if ((events & PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST) != 0) {
                        try {
                            r.callback.onEmergencyNumberListChanged(mEmergencyNumberList);
                        } catch (RemoteException ex) {
                            remove(r.binder);
                        }
                    }
                    if ((events & PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE) != 0) {
                        try {
                            r.callback.onPhoneCapabilityChanged(mPhoneCapability);
@@ -1677,10 +1690,30 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {


    @Override
    public void notifyEmergencyNumberList(List<EmergencyNumber> emergencyNumberList) {
        // TODO checkPermission, modify Listener constent documentation
        // TODO implement multisim emergency number list update in listener
        // TODO implement PhoneStateListenerTest
    public void notifyEmergencyNumberList() {
        if (!checkNotifyPermission("notifyEmergencyNumberList()")) {
            return;
        }

        synchronized (mRecords) {
            mEmergencyNumberList = TelephonyManager.getDefault().getCurrentEmergencyNumberList();

            for (Record r : mRecords) {
                if (r.matchPhoneStateListenerEvent(
                        PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST)) {
                    try {
                        r.callback.onEmergencyNumberListChanged(mEmergencyNumberList);
                        if (VDBG) {
                            log("notifyEmergencyNumberList: emergencyNumberList= "
                                    + mEmergencyNumberList);
                        }
                    } catch (RemoteException ex) {
                        mRemoveList.add(r.binder);
                    }
                }
            }
            handleRemoveListLocked();
        }
    }


@@ -1724,6 +1757,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
            pw.println("mPhoneCapability=" + mPhoneCapability);
            pw.println("mPreferredDataSubId=" + mPreferredDataSubId);
            pw.println("mRadioPowerState=" + mRadioPowerState);
            pw.println("mEmergencyNumberList=" + mEmergencyNumberList);

            pw.decreaseIndent();

+149 −86
Original line number Diff line number Diff line
@@ -1738,7 +1738,10 @@ public class PhoneNumberUtils {
     * @param number the number to look up.
     * @return true if the number is in the list of emergency numbers
     *         listed in the RIL / SIM, otherwise return false.
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentEmergencyNumber(String)} instead.
     */
    @Deprecated
    public static boolean isEmergencyNumber(String number) {
        return isEmergencyNumber(getDefaultVoiceSubId(), number);
    }
@@ -1751,8 +1754,13 @@ public class PhoneNumberUtils {
     * @param number the number to look up.
     * @return true if the number is in the list of emergency numbers
     *         listed in the RIL / SIM, otherwise return false.
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentEmergencyNumber(String)}
     *             instead.
     *
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage
    public static boolean isEmergencyNumber(int subId, String number) {
        // Return true only if the specified number *exactly* matches
@@ -1778,8 +1786,12 @@ public class PhoneNumberUtils {
     *         listed in the RIL / SIM, *or* if the number starts with the
     *         same digits as any of those emergency numbers.
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentPotentialEmergencyNumber(String)}
     *             instead.
     *
     * @hide
     */
    @Deprecated
    public static boolean isPotentialEmergencyNumber(String number) {
        return isPotentialEmergencyNumber(getDefaultVoiceSubId(), number);
    }
@@ -1802,9 +1814,14 @@ public class PhoneNumberUtils {
     * @return true if the number is in the list of emergency numbers
     *         listed in the RIL / SIM, *or* if the number starts with the
     *         same digits as any of those emergency numbers.
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentPotentialEmergencyNumber(String)}
     *             instead.
     *
     * @hide
     */
    @UnsupportedAppUsage
    @Deprecated
    public static boolean isPotentialEmergencyNumber(int subId, String number) {
        // Check against the emergency numbers listed by the RIL / SIM,
        // and *don't* require an exact match.
@@ -1867,8 +1884,12 @@ public class PhoneNumberUtils {
     * @return if the number is an emergency number for the specific country, then return true,
     * otherwise false
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentEmergencyNumber(String)}
     *             instead.
     *
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage
    public static boolean isEmergencyNumber(String number, String defaultCountryIso) {
            return isEmergencyNumber(getDefaultVoiceSubId(), number, defaultCountryIso);
@@ -1882,8 +1903,13 @@ public class PhoneNumberUtils {
     * @param defaultCountryIso the specific country which the number should be checked against
     * @return if the number is an emergency number for the specific country, then return true,
     * otherwise false
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentEmergencyNumber(String)}
     *             instead.
     *
     * @hide
     */
    @Deprecated
    public static boolean isEmergencyNumber(int subId, String number, String defaultCountryIso) {
        return isEmergencyNumberInternal(subId, number,
                                         defaultCountryIso,
@@ -1909,8 +1935,12 @@ public class PhoneNumberUtils {
     *         country, *or* if the number starts with the same digits as
     *         any of those emergency numbers.
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentPotentialEmergencyNumber(String)}
     *             instead.
     *
     * @hide
     */
    @Deprecated
    public static boolean isPotentialEmergencyNumber(String number, String defaultCountryIso) {
        return isPotentialEmergencyNumber(getDefaultVoiceSubId(), number, defaultCountryIso);
    }
@@ -1934,8 +1964,13 @@ public class PhoneNumberUtils {
     * @return true if the number is an emergency number for the specific
     *         country, *or* if the number starts with the same digits as
     *         any of those emergency numbers.
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentPotentialEmergencyNumber(String)}
     *             instead.
     *
     * @hide
     */
    @Deprecated
    public static boolean isPotentialEmergencyNumber(int subId, String number,
            String defaultCountryIso) {
        return isEmergencyNumberInternal(subId, number,
@@ -1983,92 +2018,7 @@ public class PhoneNumberUtils {
    private static boolean isEmergencyNumberInternal(int subId, String number,
                                                     String defaultCountryIso,
                                                     boolean useExactMatch) {
        // If the number passed in is null, just return false:
        if (number == null) return false;

        // If the number passed in is a SIP address, return false, since the
        // concept of "emergency numbers" is only meaningful for calls placed
        // over the cell network.
        // (Be sure to do this check *before* calling extractNetworkPortionAlt(),
        // since the whole point of extractNetworkPortionAlt() is to filter out
        // any non-dialable characters (which would turn 'abc911def@example.com'
        // into '911', for example.))
        if (isUriNumber(number)) {
            return false;
        }

        // Strip the separators from the number before comparing it
        // to the list.
        number = extractNetworkPortionAlt(number);

        String emergencyNumbers = "";
        int slotId = SubscriptionManager.getSlotIndex(subId);

        // retrieve the list of emergency numbers
        // check read-write ecclist property first
        String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);

        emergencyNumbers = SystemProperties.get(ecclist, "");

        Rlog.d(LOG_TAG, "slotId:" + slotId + " subId:" + subId + " country:"
                + defaultCountryIso + " emergencyNumbers: " +  emergencyNumbers);

        if (TextUtils.isEmpty(emergencyNumbers)) {
            // then read-only ecclist property since old RIL only uses this
            emergencyNumbers = SystemProperties.get("ro.ril.ecclist");
        }

        if (!TextUtils.isEmpty(emergencyNumbers)) {
            // searches through the comma-separated list for a match,
            // return true if one is found.
            for (String emergencyNum : emergencyNumbers.split(",")) {
                // It is not possible to append additional digits to an emergency number to dial
                // the number in Brazil - it won't connect.
                if (useExactMatch || "BR".equalsIgnoreCase(defaultCountryIso)) {
                    if (number.equals(emergencyNum)) {
                        return true;
                    }
                } else {
                    if (number.startsWith(emergencyNum)) {
                        return true;
                    }
                }
            }
            // no matches found against the list!
            return false;
        }

        Rlog.d(LOG_TAG, "System property doesn't provide any emergency numbers."
                + " Use embedded logic for determining ones.");

        // If slot id is invalid, means that there is no sim card.
        // According spec 3GPP TS22.101, the following numbers should be
        // ECC numbers when SIM/USIM is not present.
        emergencyNumbers = ((slotId < 0) ? "112,911,000,08,110,118,119,999" : "112,911");

        for (String emergencyNum : emergencyNumbers.split(",")) {
            if (useExactMatch) {
                if (number.equals(emergencyNum)) {
                    return true;
                }
            } else {
                if (number.startsWith(emergencyNum)) {
                    return true;
                }
            }
        }

        // No ecclist system property, so use our own list.
        if (defaultCountryIso != null) {
            ShortNumberInfo info = ShortNumberInfo.getInstance();
            if (useExactMatch) {
                return info.isEmergencyNumber(number, defaultCountryIso);
            } else {
                return info.connectsToEmergencyNumber(number, defaultCountryIso);
            }
        }

        return false;
        return TelephonyManager.getDefault().isCurrentEmergencyNumber(number);
    }

    /**
@@ -2078,7 +2028,11 @@ public class PhoneNumberUtils {
     * @param context the specific context which the number should be checked against
     * @return true if the specified number is an emergency number for the country the user
     * is currently in.
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentEmergencyNumber(String)}
     *             instead.
     */
    @Deprecated
    public static boolean isLocalEmergencyNumber(Context context, String number) {
        return isLocalEmergencyNumber(context, getDefaultVoiceSubId(), number);
    }
@@ -2091,8 +2045,13 @@ public class PhoneNumberUtils {
     * @param context the specific context which the number should be checked against
     * @return true if the specified number is an emergency number for the country the user
     * is currently in.
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentEmergencyNumber(String)}
     *             instead.
     *
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage
    public static boolean isLocalEmergencyNumber(Context context, int subId, String number) {
        return isLocalEmergencyNumberInternal(subId, number,
@@ -2120,8 +2079,13 @@ public class PhoneNumberUtils {
     *              CountryDetector.
     *
     * @see android.location.CountryDetector
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentPotentialEmergencyNumber(String)}
     *             instead.
     *
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage
    public static boolean isPotentialLocalEmergencyNumber(Context context, String number) {
        return isPotentialLocalEmergencyNumber(context, getDefaultVoiceSubId(), number);
@@ -2147,9 +2111,13 @@ public class PhoneNumberUtils {
     * @return true if the specified number is an emergency number for a local country, based on the
     *              CountryDetector.
     *
     * @deprecated Please use {@link TelephonyManager#isCurrentPotentialEmergencyNumber(String)}
     *             instead.
     *
     * @hide
     */
    @UnsupportedAppUsage
    @Deprecated
    public static boolean isPotentialLocalEmergencyNumber(Context context, int subId,
            String number) {
        return isLocalEmergencyNumberInternal(subId, number,
@@ -2216,6 +2184,101 @@ public class PhoneNumberUtils {
        return isEmergencyNumberInternal(subId, number, countryIso, useExactMatch);
    }

    /**
     * Back-up old logics for {@link #isEmergencyNumberInternal} for legacy and deprecate purpose.
     *
     * @hide
     */
    public static boolean isEmergencyNumberInternal(String number, boolean useExactMatch,
                                                    String defaultCountryIso) {
        // If the number passed in is null, just return false:
        if (number == null) return false;

        // If the number passed in is a SIP address, return false, since the
        // concept of "emergency numbers" is only meaningful for calls placed
        // over the cell network.
        // (Be sure to do this check *before* calling extractNetworkPortionAlt(),
        // since the whole point of extractNetworkPortionAlt() is to filter out
        // any non-dialable characters (which would turn 'abc911def@example.com'
        // into '911', for example.))
        if (PhoneNumberUtils.isUriNumber(number)) {
            return false;
        }

        // Strip the separators from the number before comparing it
        // to the list.
        number = PhoneNumberUtils.extractNetworkPortionAlt(number);

        String emergencyNumbers = "";
        int slotId = SubscriptionManager.getSlotIndex(getDefaultVoiceSubId());

        // retrieve the list of emergency numbers
        // check read-write ecclist property first
        String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);

        emergencyNumbers = SystemProperties.get(ecclist, "");

        Rlog.d(LOG_TAG, "slotId:" + slotId + " country:"
                + defaultCountryIso + " emergencyNumbers: " +  emergencyNumbers);

        if (TextUtils.isEmpty(emergencyNumbers)) {
            // then read-only ecclist property since old RIL only uses this
            emergencyNumbers = SystemProperties.get("ro.ril.ecclist");
        }

        if (!TextUtils.isEmpty(emergencyNumbers)) {
            // searches through the comma-separated list for a match,
            // return true if one is found.
            for (String emergencyNum : emergencyNumbers.split(",")) {
                // It is not possible to append additional digits to an emergency number to dial
                // the number in Brazil - it won't connect.
                if (useExactMatch || "BR".equalsIgnoreCase(defaultCountryIso)) {
                    if (number.equals(emergencyNum)) {
                        return true;
                    }
                } else {
                    if (number.startsWith(emergencyNum)) {
                        return true;
                    }
                }
            }
            // no matches found against the list!
            return false;
        }

        Rlog.d(LOG_TAG, "System property doesn't provide any emergency numbers."
                + " Use embedded logic for determining ones.");

        // If slot id is invalid, means that there is no sim card.
        // According spec 3GPP TS22.101, the following numbers should be
        // ECC numbers when SIM/USIM is not present.
        emergencyNumbers = ((slotId < 0) ? "112,911,000,08,110,118,119,999" : "112,911");

        for (String emergencyNum : emergencyNumbers.split(",")) {
            if (useExactMatch) {
                if (number.equals(emergencyNum)) {
                    return true;
                }
            } else {
                if (number.startsWith(emergencyNum)) {
                    return true;
                }
            }
        }

        // No ecclist system property, so use our own list.
        if (defaultCountryIso != null) {
            ShortNumberInfo info = ShortNumberInfo.getInstance();
            if (useExactMatch) {
                return info.isEmergencyNumber(number, defaultCountryIso);
            } else {
                return info.connectsToEmergencyNumber(number, defaultCountryIso);
            }
        }

        return false;
    }

    /**
     * isVoiceMailNumber: checks a given number against the voicemail
     *   number provided by the RIL and SIM card. The caller must have
+29 −0
Original line number Diff line number Diff line
@@ -27,12 +27,14 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.telephony.emergency.EmergencyNumber;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IPhoneStateListener;

import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

/**
@@ -313,6 +315,8 @@ public class PhoneStateListener {
     *
     * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
     * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
     *
     * @see #onEmergencyNumberListChanged
     */
    public static final int LISTEN_EMERGENCY_NUMBER_LIST                   = 0x01000000;

@@ -626,6 +630,21 @@ public class PhoneStateListener {
        // default implementation empty
    }

    /**
     * Callback invoked when the current emergency number list has changed
     *
     * @param emergencyNumberList Map including the key as the active subscription ID
     *                           (Note: if there is no active subscription, the key is
     *                           {@link SubscriptionManager#getDefaultSubscriptionId})
     *                           and the value as the list of {@link EmergencyNumber};
     *                           null if this information is not available.
     * @hide
     */
    public void onEmergencyNumberListChanged(
            @NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList) {
        // default implementation empty
    }

    /**
     * Callback invoked when OEM hook raw event is received. Requires
     * the READ_PRIVILEGED_PHONE_STATE permission.
@@ -892,6 +911,16 @@ public class PhoneStateListener {
                            () -> psl.onPhysicalChannelConfigurationChanged(configs)));
        }

        @Override
        public void onEmergencyNumberListChanged(Map emergencyNumberList) {
            PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
            if (psl == null) return;

            Binder.withCleanCallingIdentity(
                    () -> mExecutor.execute(
                            () -> psl.onEmergencyNumberListChanged(emergencyNumberList)));
        }

        public void onPhoneCapabilityChanged(PhoneCapability capability) {
            PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
            if (psl == null) return;
Loading