EmergencyNumber enhancement
1) Add Database source for EmergencyNumber
2) add mergeEmergencyNumber for merging two emergency numbers
3) enable Listener.EmergencyNumber enhancement
4) no need to pass any parameter to PhoneNotifier
5) modify API documentation
6) deprecate PhoneNumberUtils.isEmergencyNumber
7) modify API documentation for security exception and backward
compatibility
9) introduce some utils in EmergencyNumber for merging number purposes
10) add mnc into EmergencyNumber
Bug: 112657134
Test: Treehugger
Change-Id: I0dcd01bdad7d9c37294cd8b87eda54b4ac9d0a0b
Merged-In: I0dcd01bdad7d9c37294cd8b87eda54b4ac9d0a0b
(cherry picked from commit 9f93a12e1f)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -9520,8 +9520,13 @@ public class TelephonyManager {
|
||||
/**
|
||||
* Get the emergency number list based on current locale, sim, default, modem and network.
|
||||
*
|
||||
* <p>The emergency number {@link EmergencyNumber} with higher display priority is located at
|
||||
* the smaller index in the returned list.
|
||||
* <p>In each returned list, the emergency number {@link EmergencyNumber} coming from higher
|
||||
* priority sources will be located at the smaller index; the priority order of sources are:
|
||||
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING} >
|
||||
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_SIM} >
|
||||
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_DATABASE} >
|
||||
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_DEFAULT} >
|
||||
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG}
|
||||
*
|
||||
* <p>The subscriptions which the returned list would be based on, are all the active
|
||||
* subscriptions, no matter which subscription could be used to create TelephonyManager.
|
||||
@@ -9530,8 +9535,9 @@ public class TelephonyManager {
|
||||
* app has carrier privileges (see {@link #hasCarrierPrivileges}).
|
||||
*
|
||||
* @return Map including the key as the active subscription ID (Note: if there is no active
|
||||
* subscription, the key is {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}) and the value
|
||||
* as the list of {@link EmergencyNumber}; null if this information is not available.
|
||||
* subscription, the key is {@link SubscriptionManager#getDefaultSubscriptionId}) and the value
|
||||
* as the list of {@link EmergencyNumber}; null if this information is not available; or throw
|
||||
* a SecurityException if the caller does not have the permission.
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
|
||||
@Nullable
|
||||
@@ -9552,8 +9558,13 @@ public class TelephonyManager {
|
||||
* Get the per-category emergency number list based on current locale, sim, default, modem
|
||||
* and network.
|
||||
*
|
||||
* <p>The emergency number {@link EmergencyNumber} with higher display priority is located at
|
||||
* the smaller index in the returned list.
|
||||
* <p>In each returned list, the emergency number {@link EmergencyNumber} coming from higher
|
||||
* priority sources will be located at the smaller index; the priority order of sources are:
|
||||
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING} >
|
||||
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_SIM} >
|
||||
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_DATABASE} >
|
||||
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_DEFAULT} >
|
||||
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG}
|
||||
*
|
||||
* <p>The subscriptions which the returned list would be based on, are all the active
|
||||
* subscriptions, no matter which subscription could be used to create TelephonyManager.
|
||||
@@ -9574,8 +9585,9 @@ public class TelephonyManager {
|
||||
* <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li>
|
||||
* </ol>
|
||||
* @return Map including the key as the active subscription ID (Note: if there is no active
|
||||
* subscription, the key is {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}) and the value
|
||||
* as the list of {@link EmergencyNumber}; null if this information is not available.
|
||||
* subscription, the key is {@link SubscriptionManager#getDefaultSubscriptionId}) and the value
|
||||
* as the list of {@link EmergencyNumber}; null if this information is not available; or throw
|
||||
* a SecurityException if the caller does not have the permission.
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
|
||||
@Nullable
|
||||
@@ -9622,7 +9634,44 @@ public class TelephonyManager {
|
||||
if (telephony == null) {
|
||||
return false;
|
||||
}
|
||||
return telephony.isCurrentEmergencyNumber(number);
|
||||
return telephony.isCurrentEmergencyNumber(number, true);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "isCurrentEmergencyNumber RemoteException", ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the supplied number is an emergency number based on current locale, sim, default,
|
||||
* modem and network.
|
||||
*
|
||||
* <p> Specifically, this method will return {@code true} if the specified number is an
|
||||
* emergency number, *or* if the number simply starts with the same digits as any current
|
||||
* emergency number.
|
||||
*
|
||||
* <p>The subscriptions which the identification would be based on, are all the active
|
||||
* subscriptions, no matter which subscription could be used to create TelephonyManager.
|
||||
*
|
||||
* <p>Requires permission: {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
|
||||
* that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
|
||||
*
|
||||
* @param number - the number to look up
|
||||
* @return {@code true} if the given number is an emergency number or it simply starts with
|
||||
* the same digits of any current emergency number based on current locale, sim, modem and
|
||||
* network; {@code false} if it is not; or throw an SecurityException if the caller does not
|
||||
* have the required permission/privileges
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
|
||||
public boolean isCurrentPotentialEmergencyNumber(@NonNull String number) {
|
||||
try {
|
||||
ITelephony telephony = getITelephony();
|
||||
if (telephony == null) {
|
||||
return false;
|
||||
}
|
||||
return telephony.isCurrentEmergencyNumber(number, false);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "isCurrentEmergencyNumber RemoteException", ex);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.hardware.radio.V1_4.EmergencyNumberSource;
|
||||
import android.hardware.radio.V1_4.EmergencyServiceCategory;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.telephony.Rlog;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -150,6 +151,7 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
|
||||
@IntDef(flag = true, prefix = { "EMERGENCY_NUMBER_SOURCE_" }, value = {
|
||||
EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
|
||||
EMERGENCY_NUMBER_SOURCE_SIM,
|
||||
EMERGENCY_NUMBER_SOURCE_DATABASE,
|
||||
EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG,
|
||||
EMERGENCY_NUMBER_SOURCE_DEFAULT
|
||||
})
|
||||
@@ -169,6 +171,10 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
|
||||
* Reference: 3gpp 22.101, Section 10 - Emergency Calls
|
||||
*/
|
||||
public static final int EMERGENCY_NUMBER_SOURCE_SIM = EmergencyNumberSource.SIM;
|
||||
/**
|
||||
* Bit-field which indicates the number is from the platform-maintained database.
|
||||
*/
|
||||
public static final int EMERGENCY_NUMBER_SOURCE_DATABASE = 1 << 4;
|
||||
/** Bit-field which indicates the number is from the modem config. */
|
||||
public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG =
|
||||
EmergencyNumberSource.MODEM_CONFIG;
|
||||
@@ -187,21 +193,24 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
|
||||
EMERGENCY_NUMBER_SOURCE_SET = new HashSet<Integer>();
|
||||
EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
|
||||
EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_SIM);
|
||||
EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_DATABASE);
|
||||
EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG);
|
||||
EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_DEFAULT);
|
||||
}
|
||||
|
||||
private final String mNumber;
|
||||
private final String mCountryIso;
|
||||
private final String mMnc;
|
||||
private final int mEmergencyServiceCategoryBitmask;
|
||||
private final int mEmergencyNumberSourceBitmask;
|
||||
|
||||
/** @hide */
|
||||
public EmergencyNumber(@NonNull String number, @NonNull String countryIso,
|
||||
int emergencyServiceCategories,
|
||||
@NonNull String mnc, int emergencyServiceCategories,
|
||||
int emergencyNumberSources) {
|
||||
this.mNumber = number;
|
||||
this.mCountryIso = countryIso;
|
||||
this.mMnc = mnc;
|
||||
this.mEmergencyServiceCategoryBitmask = emergencyServiceCategories;
|
||||
this.mEmergencyNumberSourceBitmask = emergencyNumberSources;
|
||||
}
|
||||
@@ -210,6 +219,7 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
|
||||
public EmergencyNumber(Parcel source) {
|
||||
mNumber = source.readString();
|
||||
mCountryIso = source.readString();
|
||||
mMnc = source.readString();
|
||||
mEmergencyServiceCategoryBitmask = source.readInt();
|
||||
mEmergencyNumberSourceBitmask = source.readInt();
|
||||
}
|
||||
@@ -235,6 +245,15 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
|
||||
return mCountryIso;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Mobile Network Code of the emergency number.
|
||||
*
|
||||
* @return the Mobile Network Code of the emergency number.
|
||||
*/
|
||||
public String getMnc() {
|
||||
return mMnc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitmask of emergency service categories of the emergency number.
|
||||
*
|
||||
@@ -338,6 +357,7 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(mNumber);
|
||||
dest.writeString(mCountryIso);
|
||||
dest.writeString(mMnc);
|
||||
dest.writeInt(mEmergencyServiceCategoryBitmask);
|
||||
dest.writeInt(mEmergencyNumberSourceBitmask);
|
||||
}
|
||||
@@ -350,10 +370,10 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EmergencyNumber = " + "[Number]" + mNumber + " / [CountryIso]" + mCountryIso
|
||||
+ " / [ServiceCategories]"
|
||||
+ Integer.toBinaryString(mEmergencyServiceCategoryBitmask)
|
||||
+ " / [Sources]" + Integer.toBinaryString(mEmergencyNumberSourceBitmask);
|
||||
return "EmergencyNumber:" + "Number-" + mNumber + "|CountryIso-" + mCountryIso
|
||||
+ "|Mnc-" + mMnc
|
||||
+ "|ServiceCategories-" + Integer.toBinaryString(mEmergencyServiceCategoryBitmask)
|
||||
+ "|Sources-" + Integer.toBinaryString(mEmergencyNumberSourceBitmask);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -373,6 +393,7 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
|
||||
* The priority of sources are defined as follows:
|
||||
* EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING >
|
||||
* EMERGENCY_NUMBER_SOURCE_SIM >
|
||||
* EMERGENCY_NUMBER_SOURCE_DATABASE >
|
||||
* EMERGENCY_NUMBER_SOURCE_DEFAULT >
|
||||
* EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG
|
||||
*
|
||||
@@ -385,7 +406,9 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
|
||||
if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_SIM)) {
|
||||
score += 1 << 3;
|
||||
}
|
||||
// TODO add a score if the number comes from Google's emergency number database
|
||||
if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_DATABASE)) {
|
||||
score += 1 << 2;
|
||||
}
|
||||
if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_DEFAULT)) {
|
||||
score += 1 << 1;
|
||||
}
|
||||
@@ -412,14 +435,104 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu
|
||||
< emergencyNumber.getDisplayPriorityScore()) {
|
||||
return 1;
|
||||
} else {
|
||||
/**
|
||||
* TODO if both numbers have the same display priority score, the number matches the
|
||||
* Google's emergency number database has a higher display priority.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In-place merge same emergency numbers in the emergency number list.
|
||||
*
|
||||
* A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’, 'mnc' and
|
||||
* 'categories' fields. Multiple Emergency Number Sources should be merged into one bitfield
|
||||
* for the same EmergencyNumber.
|
||||
*
|
||||
* @param emergencyNumberList the emergency number list to process
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static void mergeSameNumbersInEmergencyNumberList(
|
||||
List<EmergencyNumber> emergencyNumberList) {
|
||||
if (emergencyNumberList == null) {
|
||||
return;
|
||||
}
|
||||
Set<EmergencyNumber> mergedEmergencyNumber = new HashSet<>();
|
||||
for (int i = 0; i < emergencyNumberList.size(); i++) {
|
||||
// Skip the check because it was merged.
|
||||
if (mergedEmergencyNumber.contains(emergencyNumberList.get(i))) {
|
||||
continue;
|
||||
}
|
||||
for (int j = i + 1; j < emergencyNumberList.size(); j++) {
|
||||
if (isSameEmergencyNumber(
|
||||
emergencyNumberList.get(i), emergencyNumberList.get(j))) {
|
||||
Rlog.e(LOG_TAG, "Found unexpected duplicate numbers: "
|
||||
+ emergencyNumberList.get(i) + " vs " + emergencyNumberList.get(j));
|
||||
// Set the merged emergency number in the current position
|
||||
emergencyNumberList.set(i, mergeNumbers(
|
||||
emergencyNumberList.get(i), emergencyNumberList.get(j)));
|
||||
// Mark the emergency number has been merged
|
||||
mergedEmergencyNumber.add(emergencyNumberList.get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove the marked emergency number in the orignal list
|
||||
for (int i = 0; i < emergencyNumberList.size(); i++) {
|
||||
if (mergedEmergencyNumber.contains(emergencyNumberList.get(i))) {
|
||||
emergencyNumberList.remove(i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two emergency numbers are the same.
|
||||
*
|
||||
* A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’, 'mnc' and
|
||||
* 'categories' fields. Multiple Emergency Number Sources should be merged into one bitfield
|
||||
* for the same EmergencyNumber.
|
||||
*
|
||||
* @param first first EmergencyNumber to compare
|
||||
* @param second second EmergencyNumber to compare
|
||||
* @return true if they are the same EmergencyNumbers; false otherwise.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isSameEmergencyNumber(@NonNull EmergencyNumber first,
|
||||
@NonNull EmergencyNumber second) {
|
||||
if (!first.getNumber().equals(second.getNumber())) {
|
||||
return false;
|
||||
}
|
||||
if (!first.getCountryIso().equals(second.getCountryIso())) {
|
||||
return false;
|
||||
}
|
||||
if (!first.getMnc().equals(second.getMnc())) {
|
||||
return false;
|
||||
}
|
||||
if (first.getEmergencyServiceCategoryBitmask()
|
||||
!= second.getEmergencyServiceCategoryBitmask()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a merged EmergencyNumber for two numbers if they are the same.
|
||||
*
|
||||
* @param first first EmergencyNumber to compare
|
||||
* @param second second EmergencyNumber to compare
|
||||
* @return a merged EmergencyNumber or null if they are not the same EmergencyNumber
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static EmergencyNumber mergeNumbers(@NonNull EmergencyNumber first,
|
||||
@NonNull EmergencyNumber second) {
|
||||
if (isSameEmergencyNumber(first, second)) {
|
||||
return new EmergencyNumber(first.getNumber(), first.getCountryIso(), first.getMnc(),
|
||||
first.getEmergencyServiceCategoryBitmask(),
|
||||
first.getEmergencyNumberSourceBitmask()
|
||||
| second.getEmergencyNumberSourceBitmask());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<EmergencyNumber> CREATOR =
|
||||
new Parcelable.Creator<EmergencyNumber>() {
|
||||
@Override
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.telephony.PhoneCapability;
|
||||
import android.telephony.PhysicalChannelConfig;
|
||||
import android.telephony.PreciseCallState;
|
||||
import android.telephony.PreciseDataConnectionState;
|
||||
import android.telephony.emergency.EmergencyNumber;
|
||||
|
||||
oneway interface IPhoneStateListener {
|
||||
void onServiceStateChanged(in ServiceState serviceState);
|
||||
@@ -51,8 +52,9 @@ oneway interface IPhoneStateListener {
|
||||
void onCarrierNetworkChange(in boolean active);
|
||||
void onUserMobileDataStateChanged(in boolean enabled);
|
||||
void onPhoneCapabilityChanged(in PhoneCapability capability);
|
||||
void onRadioPowerStateChanged(in int state);
|
||||
void onPreferredDataSubIdChanged(in int subId);
|
||||
void onRadioPowerStateChanged(in int state);
|
||||
void onEmergencyNumberListChanged(in Map emergencyNumberList);
|
||||
void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause);
|
||||
}
|
||||
|
||||
|
||||
@@ -1732,7 +1732,7 @@ interface ITelephony {
|
||||
/**
|
||||
* Identify if the number is emergency number, based on all the active subscriptions.
|
||||
*/
|
||||
boolean isCurrentEmergencyNumber(String number);
|
||||
boolean isCurrentEmergencyNumber(String number, boolean exactMatch);
|
||||
|
||||
/**
|
||||
* Return a list of certs in hex string from loaded carrier privileges access rules.
|
||||
|
||||
@@ -81,5 +81,5 @@ interface ITelephonyRegistry {
|
||||
void notifyPhoneCapabilityChanged(in PhoneCapability capability);
|
||||
void notifyPreferredDataSubIdChanged(int preferredSubId);
|
||||
void notifyRadioPowerStateChanged(in int state);
|
||||
void notifyEmergencyNumberList(in List<EmergencyNumber> emergencyNumberList);
|
||||
void notifyEmergencyNumberList();
|
||||
}
|
||||
|
||||
@@ -483,4 +483,5 @@ public interface RILConstants {
|
||||
int RIL_UNSOL_HAL_NON_RIL_BASE = 1100;
|
||||
int RIL_UNSOL_ICC_SLOT_STATUS = 1100;
|
||||
int RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG = 1101;
|
||||
int RIL_UNSOL_EMERGENCY_NUMBER_LIST = 1102;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user