diff options
Diffstat (limited to 'telephony')
57 files changed, 7064 insertions, 606 deletions
diff --git a/telephony/java/android/telephony/CallStateListener.java b/telephony/java/android/telephony/CallStateListener.java deleted file mode 100644 index e2ffbfa..0000000 --- a/telephony/java/android/telephony/CallStateListener.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony; - -import android.annotation.PrivateApi; - -/** @hide */ -@PrivateApi -public interface CallStateListener { - /** - * Notify of a new or updated call. - * Any time the state of a call is updated, it will alert any listeners. This includes changes - * of state such as when a call is put on hold or conferenced. - * - * @param callId a unique ideCntifier for a given call that can be used to track state changes - * @param state the new state of the call. - * {@see com.android.services.telephony.common.Call$State} - * @param number the phone number of the call. For some states, this may be blank. However, it - * will be populated for any initial state. - */ - public void onCallStateChanged(int callId, int state, String number); -} diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java index bfa0942..b5e4eef 100644 --- a/telephony/java/android/telephony/CellInfo.java +++ b/telephony/java/android/telephony/CellInfo.java @@ -76,7 +76,7 @@ public abstract class CellInfo implements Parcelable { return mRegistered; } /** @hide */ - public void setRegisterd(boolean registered) { + public void setRegistered(boolean registered) { mRegistered = registered; } diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java index 42c2aff..f9a222f 100644 --- a/telephony/java/android/telephony/CellLocation.java +++ b/telephony/java/android/telephony/CellLocation.java @@ -19,9 +19,6 @@ package android.telephony; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.SystemProperties; -import android.provider.Settings; - import android.telephony.cdma.CdmaCellLocation; import android.telephony.gsm.GsmCellLocation; diff --git a/telephony/java/android/telephony/CellSignalStrength.java b/telephony/java/android/telephony/CellSignalStrength.java index 3b470fc..9c23f78 100644 --- a/telephony/java/android/telephony/CellSignalStrength.java +++ b/telephony/java/android/telephony/CellSignalStrength.java @@ -16,9 +16,6 @@ package android.telephony; -import android.os.Parcel; -import android.os.Parcelable; - /** * Abstract base class for cell phone signal strength related information. */ diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java index 46d09f6..be13acc 100644 --- a/telephony/java/android/telephony/CellSignalStrengthCdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java @@ -137,7 +137,6 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements /** * Get the signal level as an asu value between 0..97, 99 is unknown - * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 */ @Override public int getAsuLevel() { @@ -342,7 +341,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements /** * Construct a SignalStrength object from the given parcel - * where the TYPE_LTE token is already been processed. + * where the TYPE_CDMA token is already been processed. */ private CellSignalStrengthCdma(Parcel in) { // CdmaDbm, CdmaEcio, EvdoDbm and EvdoEcio are written into diff --git a/telephony/java/android/telephony/DataConnectionRealTimeInfo.aidl b/telephony/java/android/telephony/DataConnectionRealTimeInfo.aidl new file mode 100644 index 0000000..70fbb11 --- /dev/null +++ b/telephony/java/android/telephony/DataConnectionRealTimeInfo.aidl @@ -0,0 +1,20 @@ +/* +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.telephony; + +parcelable DataConnectionRealTimeInfo; diff --git a/telephony/java/android/telephony/DataConnectionRealTimeInfo.java b/telephony/java/android/telephony/DataConnectionRealTimeInfo.java new file mode 100644 index 0000000..96069213 --- /dev/null +++ b/telephony/java/android/telephony/DataConnectionRealTimeInfo.java @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Data connection real time information + * + * TODO: How to handle multiple subscriptions? + * @hide + */ +public class DataConnectionRealTimeInfo implements Parcelable { + private long mTime; // Time the info was collected since boot in nanos; + + public static int DC_POWER_STATE_LOW = 1; + public static int DC_POWER_STATE_MEDIUM = 2; + public static int DC_POWER_STATE_HIGH = 3; + public static int DC_POWER_STATE_UNKNOWN = Integer.MAX_VALUE; + + private int mDcPowerState; // DC_POWER_STATE_[LOW | MEDIUM | HIGH | UNKNOWN] + + /** + * Constructor + * + * @hide + */ + public DataConnectionRealTimeInfo(long time, int dcPowerState) { + mTime = time; + mDcPowerState = dcPowerState; + } + + /** + * Constructor + * + * @hide + */ + public DataConnectionRealTimeInfo() { + mTime = Long.MAX_VALUE; + mDcPowerState = DC_POWER_STATE_UNKNOWN; + } + + /** + * Construct a PreciseCallState object from the given parcel. + */ + private DataConnectionRealTimeInfo(Parcel in) { + mTime = in.readLong(); + mDcPowerState = in.readInt(); + } + + /** + * @return time the information was collected or Long.MAX_VALUE if unknown + */ + public long getTime() { + return mTime; + } + + /** + * @return DC_POWER_STATE_[LOW | MEDIUM | HIGH | UNKNOWN] + */ + public int getDcPowerState() { + return mDcPowerState; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeLong(mTime); + out.writeInt(mDcPowerState); + } + + public static final Parcelable.Creator<DataConnectionRealTimeInfo> CREATOR + = new Parcelable.Creator<DataConnectionRealTimeInfo>() { + + @Override + public DataConnectionRealTimeInfo createFromParcel(Parcel in) { + return new DataConnectionRealTimeInfo(in); + } + + @Override + public DataConnectionRealTimeInfo[] newArray(int size) { + return new DataConnectionRealTimeInfo[size]; + } + }; + + @Override + public int hashCode() { + final long prime = 17; + long result = 1; + result = (prime * result) + mTime; + result += (prime * result) + mDcPowerState; + return (int)result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + DataConnectionRealTimeInfo other = (DataConnectionRealTimeInfo) obj; + return (mTime == other.mTime) + && (mDcPowerState == other.mDcPowerState); + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + + sb.append("mTime=").append(mTime); + sb.append(" mDcPowerState=").append(mDcPowerState); + + return sb.toString(); + } +} diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java index 1c75658..aa6c47c 100644 --- a/telephony/java/android/telephony/DisconnectCause.java +++ b/telephony/java/android/telephony/DisconnectCause.java @@ -17,10 +17,7 @@ package android.telephony; /** - * Contains disconnect call causes generated by the - * framework and the RIL. - * - * @hide + * Contains disconnect call causes generated by the framework and the RIL. */ public class DisconnectCause { @@ -100,11 +97,73 @@ public class DisconnectCause { public static final int CDMA_ACCESS_BLOCKED = 35; /** Unknown error or not specified */ public static final int ERROR_UNSPECIFIED = 36; + /** + * Only emergency numbers are allowed, but we tried to dial + * a non-emergency number. + */ + // TODO: This should be the same as NOT_EMERGENCY + public static final int EMERGENCY_ONLY = 37; + /** + * The supplied CALL Intent didn't contain a valid phone number. + */ + public static final int NO_PHONE_NUMBER_SUPPLIED = 38; + /** + * Our initial phone number was actually an MMI sequence. + */ + public static final int DIALED_MMI = 39; + /** + * We tried to call a voicemail: URI but the device has no + * voicemail number configured. + */ + public static final int VOICEMAIL_NUMBER_MISSING = 40; + /** + * This status indicates that InCallScreen should display the + * CDMA-specific "call lost" dialog. (If an outgoing call fails, + * and the CDMA "auto-retry" feature is enabled, *and* the retried + * call fails too, we display this specific dialog.) + * + * TODO: this is currently unused, since the "call lost" dialog + * needs to be triggered by a *disconnect* event, rather than when + * the InCallScreen first comes to the foreground. For now we use + * the needToShowCallLostDialog field for this (see below.) + */ + public static final int CDMA_CALL_LOST = 41; + /** + * This status indicates that the call was placed successfully, + * but additionally, the InCallScreen needs to display the + * "Exiting ECM" dialog. + * + * (Details: "Emergency callback mode" is a CDMA-specific concept + * where the phone disallows data connections over the cell + * network for some period of time after you make an emergency + * call. If the phone is in ECM and you dial a non-emergency + * number, that automatically *cancels* ECM, but we additionally + * need to warn the user that ECM has been canceled (see bug + * 4207607.)) + * + * TODO: Rethink where the best place to put this is. It is not a notification + * of a failure of the connection -- it is an additional message that accompanies + * a successful connection giving the user important information about what happened. + * + * {@hide} + */ + public static final int EXITED_ECM = 42; + + /** + * The outgoing call failed with an unknown cause. + */ + public static final int OUTGOING_FAILURE = 43; + + /** + * The outgoing call was canceled by the {@link android.telecomm.ConnectionService}. + */ + public static final int OUTGOING_CANCELED = 44; /** Smallest valid value for call disconnect codes. */ public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED; + /** Largest valid value for call disconnect codes. */ - public static final int MAXIMUM_VALID_VALUE = ERROR_UNSPECIFIED; + public static final int MAXIMUM_VALID_VALUE = OUTGOING_CANCELED; /** Private constructor to avoid class instantiation. */ private DisconnectCause() { @@ -184,8 +243,24 @@ public class DisconnectCause { return "CDMA_NOT_EMERGENCY"; case CDMA_ACCESS_BLOCKED: return "CDMA_ACCESS_BLOCKED"; + case EMERGENCY_ONLY: + return "EMERGENCY_ONLY"; + case NO_PHONE_NUMBER_SUPPLIED: + return "NO_PHONE_NUMBER_SUPPLIED"; + case DIALED_MMI: + return "DIALED_MMI"; + case VOICEMAIL_NUMBER_MISSING: + return "VOICEMAIL_NUMBER_MISSING"; + case CDMA_CALL_LOST: + return "CDMA_CALL_LOST"; + case EXITED_ECM: + return "EXITED_ECM"; case ERROR_UNSPECIFIED: return "ERROR_UNSPECIFIED"; + case OUTGOING_FAILURE: + return "OUTGOING_FAILURE"; + case OUTGOING_CANCELED: + return "OUTGOING_CANCELED"; default: return "INVALID"; } diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java index 983c349..438b572 100644 --- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java +++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java @@ -65,8 +65,6 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher { * * @param countryCode the ISO 3166-1 two-letter country code that indicates the country/region * where the phone number is being entered. - * - * @hide */ public PhoneNumberFormattingTextWatcher(String countryCode) { if (countryCode == null) throw new IllegalArgumentException(); diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index e3a1aa6..b935d2a 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -36,6 +36,7 @@ import android.text.TextUtils; import android.telephony.Rlog; import android.util.SparseIntArray; +import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY; import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY; import static com.android.internal.telephony.TelephonyProperties.PROPERTY_IDP_STRING; import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY; @@ -166,7 +167,9 @@ public class PhoneNumberUtils // TODO: We don't check for SecurityException here (requires // CALL_PRIVILEGED permission). if (scheme.equals("voicemail")) { - return TelephonyManager.getDefault().getCompleteVoiceMailNumber(); + long subId = intent.getLongExtra(SUBSCRIPTION_KEY, + SubscriptionManager.getDefaultVoiceSubId()); + return TelephonyManager.getDefault().getCompleteVoiceMailNumber(subId); } if (context == null) { @@ -1143,6 +1146,8 @@ public class PhoneNumberUtils * @param source The phone number to format * @return A locally acceptable formatting of the input, or the raw input if * formatting rules aren't known for the number + * + * @deprecated Use link #formatNumber(String phoneNumber, String defaultCountryIso) instead */ public static String formatNumber(String source) { SpannableStringBuilder text = new SpannableStringBuilder(source); @@ -1159,7 +1164,8 @@ public class PhoneNumberUtils * not begin with +[country_code] * @return The phone number formatted with the given formatting type. * - * @hide TODO: Should be unhidden. + * @hide + * @deprecated Use link #formatNumber(String phoneNumber, String defaultCountryIso) instead */ public static String formatNumber(String source, int defaultFormattingType) { SpannableStringBuilder text = new SpannableStringBuilder(source); @@ -1173,6 +1179,8 @@ public class PhoneNumberUtils * @param locale The locale of interest, usually {@link Locale#getDefault()} * @return The formatting type for the given locale, or FORMAT_UNKNOWN if the formatting * rules are not known for the given locale + * + * @deprecated Use link #formatNumber(String phoneNumber, String defaultCountryIso) instead */ public static int getFormatTypeForLocale(Locale locale) { String country = locale.getCountry(); @@ -1187,6 +1195,8 @@ public class PhoneNumberUtils * @param text The number to be formatted, will be modified with the formatting * @param defaultFormattingType The default formatting rules to apply if the number does * not begin with +[country_code] + * + * @deprecated Use link #formatNumber(String phoneNumber, String defaultCountryIso) instead */ public static void formatNumber(Editable text, int defaultFormattingType) { int formatType = defaultFormattingType; @@ -1233,6 +1243,8 @@ public class PhoneNumberUtils * </code></p> * * @param text the number to be formatted, will be modified with the formatting + * + * @deprecated Use link #formatNumber(String phoneNumber, String defaultCountryIso) instead */ public static void formatNanpNumber(Editable text) { int length = text.length(); @@ -1346,6 +1358,8 @@ public class PhoneNumberUtils * * @param text the number to be formatted, will be modified with * the formatting + * + * @deprecated Use link #formatNumber(String phoneNumber, String defaultCountryIso) instead */ public static void formatJapaneseNumber(Editable text) { JapanesePhoneNumberFormatter.format(text); @@ -1382,8 +1396,6 @@ public class PhoneNumberUtils * the ISO 3166-1 two letters country code * @return the E.164 representation, or null if the given phone number is * not valid. - * - * @hide */ public static String formatNumberToE164(String phoneNumber, String defaultCountryIso) { PhoneNumberUtil util = PhoneNumberUtil.getInstance(); @@ -1410,8 +1422,6 @@ public class PhoneNumberUtils * the ISO 3166-1 two letters country code whose convention will * be used if the given number doesn't have the country code. * @return the formatted number, or null if the given number is not valid. - * - * @hide */ public static String formatNumber(String phoneNumber, String defaultCountryIso) { // Do not attempt to format numbers that start with a hash or star symbol. @@ -1446,8 +1456,6 @@ public class PhoneNumberUtils * contains IDD. * @return the formatted number if the given number has been formatted, * otherwise, return the given number. - * - * @hide */ public static String formatNumber( String phoneNumber, String phoneNumberE164, String defaultCountryIso) { @@ -1483,13 +1491,14 @@ public class PhoneNumberUtils * the given number has keypad letters, the letters will be converted to * digits first. * - * @param phoneNumber - * the number to be normalized. + * @param phoneNumber the number to be normalized. * @return the normalized number. - * - * @hide */ public static String normalizeNumber(String phoneNumber) { + if (TextUtils.isEmpty(phoneNumber)) { + return ""; + } + StringBuilder sb = new StringBuilder(); int len = phoneNumber.length(); for (int i = 0; i < len; i++) { @@ -1508,12 +1517,10 @@ public class PhoneNumberUtils } /** - * Replace arabic/unicode digits with decimal digits. - * @param number - * the number to be normalized. - * @return the replaced number. + * Replaces all unicode(e.g. Arabic, Persian) digits with their decimal digit equivalents. * - * @hide + * @param number the number to perform the replacement on. + * @return the replaced number. */ public static String replaceUnicodeDigits(String number) { StringBuilder normalizedDigits = new StringBuilder(number.length()); @@ -1556,9 +1563,23 @@ public class PhoneNumberUtils * listed in the RIL / SIM, otherwise return false. */ public static boolean isEmergencyNumber(String number) { + return isEmergencyNumber(getDefaultVoiceSubId(), number); + } + + /** + * Checks a given number against the list of + * emergency numbers provided by the RIL and SIM card. + * + * @param subId the subscription id of the SIM. + * @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. + * @hide + */ + public static boolean isEmergencyNumber(long subId, String number) { // Return true only if the specified number *exactly* matches // one of the emergency numbers listed by the RIL / SIM. - return isEmergencyNumberInternal(number, true /* useExactMatch */); + return isEmergencyNumberInternal(subId, number, true /* useExactMatch */); } /** @@ -1582,9 +1603,33 @@ public class PhoneNumberUtils * @hide */ public static boolean isPotentialEmergencyNumber(String number) { + return isPotentialEmergencyNumber(getDefaultVoiceSubId(), number); + } + + /** + * Checks if given number might *potentially* result in + * a call to an emergency service on the current network. + * + * Specifically, this method will return true if the specified number + * is an emergency number according to the list managed by the RIL or + * SIM, *or* if the specified number simply starts with the same + * digits as any of the emergency numbers listed in the RIL / SIM. + * + * This method is intended for internal use by the phone app when + * deciding whether to allow ACTION_CALL intents from 3rd party apps + * (where we're required to *not* allow emergency calls to be placed.) + * + * @param subId the subscription id of the SIM. + * @param number the number to look up. + * @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. + * @hide + */ + public static boolean isPotentialEmergencyNumber(long subId, String number) { // Check against the emergency numbers listed by the RIL / SIM, // and *don't* require an exact match. - return isEmergencyNumberInternal(number, false /* useExactMatch */); + return isEmergencyNumberInternal(subId, number, false /* useExactMatch */); } /** @@ -1607,7 +1652,32 @@ public class PhoneNumberUtils * listed in the RIL / sim, otherwise return false. */ private static boolean isEmergencyNumberInternal(String number, boolean useExactMatch) { - return isEmergencyNumberInternal(number, null, useExactMatch); + return isEmergencyNumberInternal(getDefaultVoiceSubId(), number, useExactMatch); + } + + /** + * Helper function for isEmergencyNumber(String) and + * isPotentialEmergencyNumber(String). + * + * @param subId the subscription id of the SIM. + * @param number the number to look up. + * + * @param useExactMatch if true, consider a number to be an emergency + * number only if it *exactly* matches a number listed in + * the RIL / SIM. If false, a number is considered to be an + * emergency number if it simply starts with the same digits + * as any of the emergency numbers listed in the RIL / SIM. + * (Setting useExactMatch to false allows you to identify + * number that could *potentially* result in emergency calls + * since many networks will actually ignore trailing digits + * after a valid emergency number.) + * + * @return true if the number is in the list of emergency numbers + * listed in the RIL / sim, otherwise return false. + */ + private static boolean isEmergencyNumberInternal(long subId, String number, + boolean useExactMatch) { + return isEmergencyNumberInternal(subId, number, null, useExactMatch); } /** @@ -1621,7 +1691,21 @@ public class PhoneNumberUtils * @hide */ public static boolean isEmergencyNumber(String number, String defaultCountryIso) { - return isEmergencyNumberInternal(number, + return isEmergencyNumber(getDefaultVoiceSubId(), number, defaultCountryIso); + } + + /** + * Checks if a given number is an emergency number for a specific country. + * + * @param subId the subscription id of the SIM. + * @param number the number to look up. + * @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 + * @hide + */ + public static boolean isEmergencyNumber(long subId, String number, String defaultCountryIso) { + return isEmergencyNumberInternal(subId, number, defaultCountryIso, true /* useExactMatch */); } @@ -1648,7 +1732,33 @@ public class PhoneNumberUtils * @hide */ public static boolean isPotentialEmergencyNumber(String number, String defaultCountryIso) { - return isEmergencyNumberInternal(number, + return isPotentialEmergencyNumber(getDefaultVoiceSubId(), number, defaultCountryIso); + } + + /** + * Checks if a given number might *potentially* result in a call to an + * emergency service, for a specific country. + * + * Specifically, this method will return true if the specified number + * is an emergency number in the specified country, *or* if the number + * simply starts with the same digits as any emergency number for that + * country. + * + * This method is intended for internal use by the phone app when + * deciding whether to allow ACTION_CALL intents from 3rd party apps + * (where we're required to *not* allow emergency calls to be placed.) + * + * @param subId the subscription id of the SIM. + * @param number the number to look up. + * @param defaultCountryIso the specific country which the number should be checked against + * @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. + * @hide + */ + public static boolean isPotentialEmergencyNumber(long subId, String number, + String defaultCountryIso) { + return isEmergencyNumberInternal(subId, number, defaultCountryIso, false /* useExactMatch */); } @@ -1670,6 +1780,29 @@ public class PhoneNumberUtils private static boolean isEmergencyNumberInternal(String number, String defaultCountryIso, boolean useExactMatch) { + return isEmergencyNumberInternal(getDefaultVoiceSubId(), number, defaultCountryIso, + useExactMatch); + } + + /** + * Helper function for isEmergencyNumber(String, String) and + * isPotentialEmergencyNumber(String, String). + * + * @param subId the subscription id of the SIM. + * @param number the number to look up. + * @param defaultCountryIso the specific country which the number should be checked against + * @param useExactMatch if true, consider a number to be an emergency + * number only if it *exactly* matches a number listed in + * the RIL / SIM. If false, a number is considered to be an + * emergency number if it simply starts with the same digits + * as any of the emergency numbers listed in the RIL / SIM. + * + * @return true if the number is an emergency number for the specified country. + * @hide + */ + private static boolean isEmergencyNumberInternal(long subId, String number, + String defaultCountryIso, + boolean useExactMatch) { // If the number passed in is null, just return false: if (number == null) return false; @@ -1688,9 +1821,14 @@ public class PhoneNumberUtils // to the list. number = extractNetworkPortionAlt(number); + String numbers = ""; + int slotId = SubscriptionManager.getSlotId(subId); // retrieve the list of emergency numbers // check read-write ecclist property first - String numbers = SystemProperties.get("ril.ecclist"); + String ecclist = (slotId == 0) ? "ril.ecclist" : ("ril.ecclist" + slotId); + + numbers = SystemProperties.get(ecclist); + if (TextUtils.isEmpty(numbers)) { // then read-only ecclist property since old RIL only uses this numbers = SystemProperties.get("ro.ril.ecclist"); @@ -1737,19 +1875,29 @@ public class PhoneNumberUtils } /** - * Checks if a given number is an emergency number for the country that the user is in. The - * current country is determined using the CountryDetector. + * Checks if a given number is an emergency number for the country that the user is in. * * @param number the number to look up. * @param context the specific context which the number should be checked against - * @return true if the specified number is an emergency number for a local country, based on the - * CountryDetector. + * @return true if the specified number is an emergency number for the country the user + * is currently in. + */ + public static boolean isLocalEmergencyNumber(Context context, String number) { + return isLocalEmergencyNumber(context, getDefaultVoiceSubId(), number); + } + + /** + * Checks if a given number is an emergency number for the country that the user is in. * - * @see android.location.CountryDetector + * @param subId the subscription id of the SIM. + * @param number the number to look up. + * @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. * @hide */ - public static boolean isLocalEmergencyNumber(String number, Context context) { - return isLocalEmergencyNumberInternal(number, + public static boolean isLocalEmergencyNumber(Context context, long subId, String number) { + return isLocalEmergencyNumberInternal(subId, number, context, true /* useExactMatch */); } @@ -1776,8 +1924,35 @@ public class PhoneNumberUtils * @see android.location.CountryDetector * @hide */ - public static boolean isPotentialLocalEmergencyNumber(String number, Context context) { - return isLocalEmergencyNumberInternal(number, + public static boolean isPotentialLocalEmergencyNumber(Context context, String number) { + return isPotentialLocalEmergencyNumber(context, getDefaultVoiceSubId(), number); + } + + /** + * Checks if a given number might *potentially* result in a call to an + * emergency service, for the country that the user is in. The current + * country is determined using the CountryDetector. + * + * Specifically, this method will return true if the specified number + * is an emergency number in the current country, *or* if the number + * simply starts with the same digits as any emergency number for the + * current country. + * + * This method is intended for internal use by the phone app when + * deciding whether to allow ACTION_CALL intents from 3rd party apps + * (where we're required to *not* allow emergency calls to be placed.) + * + * @param subId the subscription id of the SIM. + * @param number the number to look up. + * @param context the specific context which the number should be checked against + * @return true if the specified number is an emergency number for a local country, based on the + * CountryDetector. + * + * @hide + */ + public static boolean isPotentialLocalEmergencyNumber(Context context, long subId, + String number) { + return isLocalEmergencyNumberInternal(subId, number, context, false /* useExactMatch */); } @@ -1798,10 +1973,35 @@ public class PhoneNumberUtils * local country, based on the CountryDetector. * * @see android.location.CountryDetector + * @hide */ private static boolean isLocalEmergencyNumberInternal(String number, Context context, boolean useExactMatch) { + return isLocalEmergencyNumberInternal(getDefaultVoiceSubId(), number, context, + useExactMatch); + } + + /** + * Helper function for isLocalEmergencyNumber() and + * isPotentialLocalEmergencyNumber(). + * + * @param subId the subscription id of the SIM. + * @param number the number to look up. + * @param context the specific context which the number should be checked against + * @param useExactMatch if true, consider a number to be an emergency + * number only if it *exactly* matches a number listed in + * the RIL / SIM. If false, a number is considered to be an + * emergency number if it simply starts with the same digits + * as any of the emergency numbers listed in the RIL / SIM. + * + * @return true if the specified number is an emergency number for a + * local country, based on the CountryDetector. + * @hide + */ + private static boolean isLocalEmergencyNumberInternal(long subId, String number, + Context context, + boolean useExactMatch) { String countryIso; CountryDetector detector = (CountryDetector) context.getSystemService( Context.COUNTRY_DETECTOR); @@ -1813,7 +2013,7 @@ public class PhoneNumberUtils Rlog.w(LOG_TAG, "No CountryDetector; falling back to countryIso based on locale: " + countryIso); } - return isEmergencyNumberInternal(number, countryIso, useExactMatch); + return isEmergencyNumberInternal(subId, number, countryIso, useExactMatch); } /** @@ -1825,13 +2025,28 @@ public class PhoneNumberUtils * @return true if the number is in the list of voicemail. False * otherwise, including if the caller does not have the permission * to read the VM number. - * @hide TODO: pending API Council approval */ public static boolean isVoiceMailNumber(String number) { + return isVoiceMailNumber(SubscriptionManager.getDefaultSubId(), number); + } + + /** + * isVoiceMailNumber: checks a given number against the voicemail + * number provided by the RIL and SIM card. The caller must have + * the READ_PHONE_STATE credential. + * + * @param subId the subscription id of the SIM. + * @param number the number to look up. + * @return true if the number is in the list of voicemail. False + * otherwise, including if the caller does not have the permission + * to read the VM number. + * @hide + */ + public static boolean isVoiceMailNumber(long subId, String number) { String vmNumber; try { - vmNumber = TelephonyManager.getDefault().getVoiceMailNumber(); + vmNumber = TelephonyManager.getDefault().getVoiceMailNumber(subId); } catch (SecurityException ex) { return false; } @@ -2563,5 +2778,11 @@ public class PhoneNumberUtils return true; } + /** + * Returns Default voice subscription Id. + */ + private static long getDefaultVoiceSubId() { + return SubscriptionManager.getDefaultVoiceSubId(); + } //==== End of utility methods used only in compareStrictly() ===== } diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 538548d..c8c3063 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -18,12 +18,15 @@ package android.telephony; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; import android.os.Message; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; import android.telephony.CellLocation; import android.telephony.CellInfo; +import android.telephony.VoLteServiceState; import android.telephony.Rlog; +import android.telephony.ServiceState; +import android.telephony.SignalStrength; +import android.telephony.SubscriptionManager; import android.telephony.PreciseCallState; import android.telephony.PreciseDataConnectionState; @@ -47,6 +50,7 @@ import java.util.List; * appropriate LISTEN_ flags. */ public class PhoneStateListener { + private static final String TAG = "PhoneStateListener"; /** * Stop listening for updates. @@ -188,7 +192,105 @@ public class PhoneStateListener { */ public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 0x00001000; + /** + * Listen for real time info for all data connections (cellular)). + * {@more} + * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE + * READ_PRECISE_PHONE_STATE} + * + * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo) + * @hide + */ + public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO = 0x00002000; + + /** + * Listen for changes to LTE network state + * + * @see #onLteNetworkStateChanged + * @hide + */ + public static final int LISTEN_VOLTE_STATE = 0x00004000; + + /* + * Subscription used to listen to the phone state changes + * @hide + */ + /** @hide */ + protected long mSubId = 0; + + private final Handler mHandler; + public PhoneStateListener() { + this(SubscriptionManager.DEFAULT_SUB_ID, Looper.myLooper()); + } + + /** + * @hide + */ + public PhoneStateListener(long subId) { + this(subId, Looper.myLooper()); + } + + /** @hide */ + public PhoneStateListener(long subId, Looper looper) { + Rlog.d(TAG, "ctor: subId=" + subId + " looper=" + looper); + mSubId = subId; + mHandler = new Handler(looper) { + public void handleMessage(Message msg) { + Rlog.d(TAG, "mSubId=" + mSubId + " what=0x" + Integer.toHexString(msg.what) + + " msg=" + msg); + switch (msg.what) { + case LISTEN_SERVICE_STATE: + PhoneStateListener.this.onServiceStateChanged((ServiceState)msg.obj); + break; + case LISTEN_SIGNAL_STRENGTH: + PhoneStateListener.this.onSignalStrengthChanged(msg.arg1); + break; + case LISTEN_MESSAGE_WAITING_INDICATOR: + PhoneStateListener.this.onMessageWaitingIndicatorChanged(msg.arg1 != 0); + break; + case LISTEN_CALL_FORWARDING_INDICATOR: + PhoneStateListener.this.onCallForwardingIndicatorChanged(msg.arg1 != 0); + break; + case LISTEN_CELL_LOCATION: + PhoneStateListener.this.onCellLocationChanged((CellLocation)msg.obj); + break; + case LISTEN_CALL_STATE: + PhoneStateListener.this.onCallStateChanged(msg.arg1, (String)msg.obj); + break; + case LISTEN_DATA_CONNECTION_STATE: + PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1, msg.arg2); + PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1); + break; + case LISTEN_DATA_ACTIVITY: + PhoneStateListener.this.onDataActivity(msg.arg1); + break; + case LISTEN_SIGNAL_STRENGTHS: + PhoneStateListener.this.onSignalStrengthsChanged((SignalStrength)msg.obj); + break; + case LISTEN_OTASP_CHANGED: + PhoneStateListener.this.onOtaspChanged(msg.arg1); + break; + case LISTEN_CELL_INFO: + PhoneStateListener.this.onCellInfoChanged((List<CellInfo>)msg.obj); + break; + case LISTEN_PRECISE_CALL_STATE: + PhoneStateListener.this.onPreciseCallStateChanged((PreciseCallState)msg.obj); + break; + case LISTEN_PRECISE_DATA_CONNECTION_STATE: + PhoneStateListener.this.onPreciseDataConnectionStateChanged( + (PreciseDataConnectionState)msg.obj); + break; + case LISTEN_DATA_CONNECTION_REAL_TIME_INFO: + PhoneStateListener.this.onDataConnectionRealTimeInfoChanged( + (DataConnectionRealTimeInfo)msg.obj); + break; + case LISTEN_VOLTE_STATE: + PhoneStateListener.this.onVoLteServiceStateChanged((VoLteServiceState)msg.obj); + break; + } + } + }; } /** @@ -299,7 +401,7 @@ public class PhoneStateListener { * @param otaspMode is integer <code>OTASP_UNKNOWN=1<code> * means the value is currently unknown and the system should wait until * <code>OTASP_NEEDED=2<code> or <code>OTASP_NOT_NEEDED=3<code> is received before - * making the decisision to perform OTASP or not. + * making the decision to perform OTASP or not. * * @hide */ @@ -335,6 +437,25 @@ public class PhoneStateListener { } /** + * Callback invoked when data connection state changes with precise information. + * + * @hide + */ + public void onDataConnectionRealTimeInfoChanged( + DataConnectionRealTimeInfo dcRtInfo) { + // default implementation empty + } + + /** + * Callback invoked when the service state of LTE network + * related to the VoLTE service has changed. + * @param stateInfo is the current LTE network information + * @hide + */ + public void onVoLteServiceStateChanged(VoLteServiceState stateInfo) { + } + + /** * The callback methods need to be called on the handler thread where * this object was created. If the binder did that for us it'd be nice. */ @@ -396,52 +517,15 @@ public class PhoneStateListener { Message.obtain(mHandler, LISTEN_PRECISE_DATA_CONNECTION_STATE, 0, 0, dataConnectionState).sendToTarget(); } - }; - Handler mHandler = new Handler() { - public void handleMessage(Message msg) { - //Rlog.d("TelephonyRegistry", "what=0x" + Integer.toHexString(msg.what) + " msg=" + msg); - switch (msg.what) { - case LISTEN_SERVICE_STATE: - PhoneStateListener.this.onServiceStateChanged((ServiceState)msg.obj); - break; - case LISTEN_SIGNAL_STRENGTH: - PhoneStateListener.this.onSignalStrengthChanged(msg.arg1); - break; - case LISTEN_MESSAGE_WAITING_INDICATOR: - PhoneStateListener.this.onMessageWaitingIndicatorChanged(msg.arg1 != 0); - break; - case LISTEN_CALL_FORWARDING_INDICATOR: - PhoneStateListener.this.onCallForwardingIndicatorChanged(msg.arg1 != 0); - break; - case LISTEN_CELL_LOCATION: - PhoneStateListener.this.onCellLocationChanged((CellLocation)msg.obj); - break; - case LISTEN_CALL_STATE: - PhoneStateListener.this.onCallStateChanged(msg.arg1, (String)msg.obj); - break; - case LISTEN_DATA_CONNECTION_STATE: - PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1, msg.arg2); - PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1); - break; - case LISTEN_DATA_ACTIVITY: - PhoneStateListener.this.onDataActivity(msg.arg1); - break; - case LISTEN_SIGNAL_STRENGTHS: - PhoneStateListener.this.onSignalStrengthsChanged((SignalStrength)msg.obj); - break; - case LISTEN_OTASP_CHANGED: - PhoneStateListener.this.onOtaspChanged(msg.arg1); - break; - case LISTEN_CELL_INFO: - PhoneStateListener.this.onCellInfoChanged((List<CellInfo>)msg.obj); - break; - case LISTEN_PRECISE_CALL_STATE: - PhoneStateListener.this.onPreciseCallStateChanged((PreciseCallState)msg.obj); - break; - case LISTEN_PRECISE_DATA_CONNECTION_STATE: - PhoneStateListener.this.onPreciseDataConnectionStateChanged((PreciseDataConnectionState)msg.obj); - } + public void onDataConnectionRealTimeInfoChanged( + DataConnectionRealTimeInfo dcRtInfo) { + Message.obtain(mHandler, LISTEN_DATA_CONNECTION_REAL_TIME_INFO, 0, 0, + dcRtInfo).sendToTarget(); + } + + public void onVoLteServiceStateChanged(VoLteServiceState lteState) { + Message.obtain(mHandler, LISTEN_VOLTE_STATE, 0, 0, lteState).sendToTarget(); } }; } diff --git a/telephony/java/android/telephony/Rlog.java b/telephony/java/android/telephony/Rlog.java index 9ac7bda..2a7f7af 100644 --- a/telephony/java/android/telephony/Rlog.java +++ b/telephony/java/android/telephony/Rlog.java @@ -16,13 +16,8 @@ package android.telephony; -import com.android.internal.os.RuntimeInit; - import android.util.Log; -import java.io.PrintWriter; -import java.io.StringWriter; - /** * A class to log strings to the RADIO LOG. * diff --git a/telephony/java/android/telephony/SubInfoRecord.aidl b/telephony/java/android/telephony/SubInfoRecord.aidl new file mode 100755 index 0000000..a2de676 --- /dev/null +++ b/telephony/java/android/telephony/SubInfoRecord.aidl @@ -0,0 +1,19 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package android.telephony; + +parcelable SubInfoRecord; diff --git a/telephony/java/android/telephony/SubInfoRecord.java b/telephony/java/android/telephony/SubInfoRecord.java new file mode 100644 index 0000000..ced8e2f --- /dev/null +++ b/telephony/java/android/telephony/SubInfoRecord.java @@ -0,0 +1,115 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package android.telephony; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A parcelable holder class of byte[] for ISms aidl implementation + * @hide + */ + +public class SubInfoRecord implements Parcelable { + + public long mSubId; + public String mIccId; + public int mSlotId; + public String mDisplayName; + public int mNameSource; + public int mColor; + public String mNumber; + public int mDispalyNumberFormat; + public int mDataRoaming; + public int[] mSimIconRes; + + public SubInfoRecord() { + this.mSubId = -1; + this.mIccId = ""; + this.mSlotId = -1; + this.mDisplayName = ""; + this.mNameSource = 0; + this.mColor = 0; + this.mNumber = ""; + this.mDispalyNumberFormat = 0; + this.mDataRoaming = 0; + this.mSimIconRes = new int[2]; + } + + + public SubInfoRecord(long subId, String iccId, int slotId, String displayname, int nameSource, + int mColor, String mNumber, int displayFormat, int roaming, int[] iconRes) { + this.mSubId = subId; + this.mIccId = iccId; + this.mSlotId = slotId; + this.mDisplayName = displayname; + this.mNameSource = nameSource; + this.mColor = mColor; + this.mNumber = mNumber; + this.mDispalyNumberFormat = displayFormat; + this.mDataRoaming = roaming; + this.mSimIconRes = iconRes; + } + + public static final Parcelable.Creator<SubInfoRecord> CREATOR = new Parcelable.Creator<SubInfoRecord>() { + public SubInfoRecord createFromParcel(Parcel source) { + long mSubId = source.readLong(); + String mIccId = source.readString(); + int mSlotId = source.readInt(); + String mDisplayName = source.readString(); + int mNameSource = source.readInt(); + int mColor = source.readInt(); + String mNumber = source.readString(); + int mDispalyNumberFormat = source.readInt(); + int mDataRoaming = source.readInt(); + int[] iconRes = new int[2]; + source.readIntArray(iconRes); + + return new SubInfoRecord(mSubId, mIccId, mSlotId, mDisplayName, mNameSource, mColor, mNumber, + mDispalyNumberFormat, mDataRoaming, iconRes); + } + + public SubInfoRecord[] newArray(int size) { + return new SubInfoRecord[size]; + } + }; + + public void writeToParcel(Parcel dest, int flags) { + dest.writeLong(mSubId); + dest.writeString(mIccId); + dest.writeInt(mSlotId); + dest.writeString(mDisplayName); + dest.writeInt(mNameSource); + dest.writeInt(mColor); + dest.writeString(mNumber); + dest.writeInt(mDispalyNumberFormat); + dest.writeInt(mDataRoaming); + dest.writeIntArray(mSimIconRes); + } + + public int describeContents() { + return 0; + } + + public String toString() { + return "{mSubId=" + mSubId + ", mIccId=" + mIccId + " mSlotId=" + mSlotId + + " mDisplayName=" + mDisplayName + " mNameSource=" + mNameSource + + " mColor=" + mColor + " mNumber=" + mNumber + + " mDispalyNumberFormat=" + mDispalyNumberFormat + " mDataRoaming=" + mDataRoaming + + " mSimIconRes=" + mSimIconRes + "}"; + } +} diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java new file mode 100644 index 0000000..79e9fd5 --- /dev/null +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -0,0 +1,712 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package android.telephony; + +import static android.Manifest.permission.READ_PHONE_STATE; + +import android.app.ActivityManagerNative; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.os.UserHandle; +import android.net.Uri; +import android.provider.BaseColumns; +import android.telephony.Rlog; +import android.os.ServiceManager; +import android.os.RemoteException; + +import com.android.internal.telephony.ISub; +import com.android.internal.telephony.PhoneConstants; +import com.android.internal.telephony.TelephonyIntents; + +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +/** + *@hide + */ +public class SubscriptionManager implements BaseColumns { + private static final String LOG_TAG = "SUB"; + private static final boolean DBG = true; + private static final boolean VDBG = false; + + // An invalid subscription identifier + public static final long INVALID_SUB_ID = Long.MAX_VALUE; + + // The default subscription identifier + public static final long DEFAULT_SUB_ID = Long.MAX_VALUE - 1; + + public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo"); + + public static final int DEFAULT_INT_VALUE = -100; + + public static final String DEFAULT_STRING_VALUE = "N/A"; + + public static final int EXTRA_VALUE_NEW_SIM = 1; + public static final int EXTRA_VALUE_REMOVE_SIM = 2; + public static final int EXTRA_VALUE_REPOSITION_SIM = 3; + public static final int EXTRA_VALUE_NOCHANGE = 4; + + public static final String INTENT_KEY_DETECT_STATUS = "simDetectStatus"; + public static final String INTENT_KEY_SIM_COUNT = "simCount"; + public static final String INTENT_KEY_NEW_SIM_SLOT = "newSIMSlot"; + public static final String INTENT_KEY_NEW_SIM_STATUS = "newSIMStatus"; + + /** + * The ICC ID of a SIM. + * <P>Type: TEXT (String)</P> + */ + public static final String ICC_ID = "icc_id"; + + /** + * <P>Type: INTEGER (int)</P> + */ + public static final String SIM_ID = "sim_id"; + + public static final int SIM_NOT_INSERTED = -1; + + /** + * The display name of a SIM. + * <P>Type: TEXT (String)</P> + */ + public static final String DISPLAY_NAME = "display_name"; + + public static final int DEFAULT_NAME_RES = com.android.internal.R.string.unknownName; + + /** + * The display name source of a SIM. + * <P>Type: INT (int)</P> + */ + public static final String NAME_SOURCE = "name_source"; + + public static final int DEFAULT_SOURCE = 0; + + public static final int SIM_SOURCE = 1; + + public static final int USER_INPUT = 2; + + /** + * The color of a SIM. + * <P>Type: INTEGER (int)</P> + */ + public static final String COLOR = "color"; + + public static final int COLOR_1 = 0; + + public static final int COLOR_2 = 1; + + public static final int COLOR_3 = 2; + + public static final int COLOR_4 = 3; + + public static final int COLOR_DEFAULT = COLOR_1; + + /** + * The phone number of a SIM. + * <P>Type: TEXT (String)</P> + */ + public static final String NUMBER = "number"; + + /** + * The number display format of a SIM. + * <P>Type: INTEGER (int)</P> + */ + public static final String DISPLAY_NUMBER_FORMAT = "display_number_format"; + + public static final int DISPALY_NUMBER_NONE = 0; + + public static final int DISPLAY_NUMBER_FIRST = 1; + + public static final int DISPLAY_NUMBER_LAST = 2; + + public static final int DISLPAY_NUMBER_DEFAULT = DISPLAY_NUMBER_FIRST; + + /** + * Permission for data roaming of a SIM. + * <P>Type: INTEGER (int)</P> + */ + public static final String DATA_ROAMING = "data_roaming"; + + public static final int DATA_ROAMING_ENABLE = 1; + + public static final int DATA_ROAMING_DISABLE = 0; + + public static final int DATA_ROAMING_DEFAULT = DATA_ROAMING_DISABLE; + + private static final int RES_TYPE_BACKGROUND_DARK = 0; + + private static final int RES_TYPE_BACKGROUND_LIGHT = 1; + + private static final int[] sSimBackgroundDarkRes = setSimResource(RES_TYPE_BACKGROUND_DARK); + + private static final int[] sSimBackgroundLightRes = setSimResource(RES_TYPE_BACKGROUND_LIGHT); + + private static HashMap<Integer, Long> mSimInfo = new HashMap<Integer, Long>(); + + public SubscriptionManager() { + if (DBG) logd("SubscriptionManager created"); + } + + /** + * Get the SubInfoRecord according to an index + * @param context Context provided by caller + * @param subId The unique SubInfoRecord index in database + * @return SubInfoRecord, maybe null + */ + public static SubInfoRecord getSubInfoUsingSubId(Context context, long subId) { + if (VDBG) logd("[getSubInfoUsingSubIdx]+ subId:" + subId); + if (subId <= 0) { + if (VDBG) logd("[getSubInfoUsingSubIdx]- subId <= 0"); + return null; + } + + SubInfoRecord subInfo = null; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + subInfo = iSub.getSubInfoUsingSubId(subId); + } + } catch (RemoteException ex) { + // ignore it + } + + return subInfo; + + } + + /** + * Get the SubInfoRecord according to an IccId + * @param context Context provided by caller + * @param iccId the IccId of SIM card + * @return SubInfoRecord, maybe null + */ + public static List<SubInfoRecord> getSubInfoUsingIccId(Context context, String iccId) { + if (VDBG) logd("[getSubInfoUsingIccId]+ iccId=" + iccId); + if (iccId == null) { + logd("[getSubInfoUsingIccId]- null iccid"); + return null; + } + + List<SubInfoRecord> result = null; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.getSubInfoUsingIccId(iccId); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + } + + /** + * Get the SubInfoRecord according to slotId + * @param context Context provided by caller + * @param slotId the slot which the SIM is inserted + * @return SubInfoRecord, maybe null + */ + public static List<SubInfoRecord> getSubInfoUsingSlotId(Context context, int slotId) { + if (VDBG) logd("[getSubInfoUsingSlotId]- slotId=" + slotId); + if (slotId < 0) { + logd("[getSubInfoUsingSlotId]- return null, slotId < 0"); + return null; + } + + List<SubInfoRecord> result = null; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.getSubInfoUsingSlotId(slotId); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + } + + /** + * Get all the SubInfoRecord(s) in subinfo database + * @param context Context provided by caller + * @return Array list of all SubInfoRecords in database, include thsoe that were inserted before + */ + public static List<SubInfoRecord> getAllSubInfoList(Context context) { + if (VDBG) logd("[getAllSubInfoList]+"); + + List<SubInfoRecord> result = null; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.getAllSubInfoList(); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + } + + /** + * Get the SubInfoRecord(s) of the currently inserted SIM(s) + * @param context Context provided by caller + * @return Array list of currently inserted SubInfoRecord(s) + */ + public static List<SubInfoRecord> getActivatedSubInfoList(Context context) { + if (VDBG) logd("[getActivatedSubInfoList]+"); + + List<SubInfoRecord> result = null; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.getActivatedSubInfoList(); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + } + + /** + * Get the SUB count of all SUB(s) in subinfo database + * @param context Context provided by caller + * @return all SIM count in database, include what was inserted before + */ + public static int getAllSubInfoCount(Context context) { + if (VDBG) logd("[getAllSubInfoCount]+"); + + int result = 0; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.getAllSubInfoCount(); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + } + + /** + * Add a new SubInfoRecord to subinfo database if needed + * @param context Context provided by caller + * @param iccId the IccId of the SIM card + * @param slotId the slot which the SIM is inserted + * @return the URL of the newly created row or the updated row + */ + public static Uri addSubInfoRecord(Context context, String iccId, int slotId) { + if (VDBG) logd("[addSubInfoRecord]+ iccId:" + iccId + " slotId:" + slotId); + if (iccId == null) { + logd("[addSubInfoRecord]- null iccId"); + } + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + // FIXME: This returns 1 on success, 0 on error should should we return it? + iSub.addSubInfoRecord(iccId, slotId); + } + } catch (RemoteException ex) { + // ignore it + } + + // FIXME: Always returns null? + return null; + + } + + /** + * Set SIM color by simInfo index + * @param context Context provided by caller + * @param color the color of the SIM + * @param subId the unique SubInfoRecord index in database + * @return the number of records updated + */ + public static int setColor(Context context, int color, long subId) { + if (VDBG) logd("[setColor]+ color:" + color + " subId:" + subId); + int size = sSimBackgroundDarkRes.length; + if (subId <= 0 || color < 0 || color >= size) { + logd("[setColor]- fail"); + return -1; + } + + int result = 0; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.setColor(color, subId); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + + } + + /** + * Set display name by simInfo index + * @param context Context provided by caller + * @param displayName the display name of SIM card + * @param subId the unique SubInfoRecord index in database + * @return the number of records updated + */ + public static int setDisplayName(Context context, String displayName, long subId) { + return setDisplayName(context, displayName, subId, -1); + } + + /** + * Set display name by simInfo index with name source + * @param context Context provided by caller + * @param displayName the display name of SIM card + * @param subId the unique SubInfoRecord index in database + * @param nameSource, 0: DEFAULT_SOURCE, 1: SIM_SOURCE, 2: USER_INPUT + * @return the number of records updated + */ + public static int setDisplayName(Context context, String displayName, long subId, long nameSource) { + if (VDBG) logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId + " nameSource:" + nameSource); + if (subId <= 0) { + logd("[setDisplayName]- fail"); + return -1; + } + + int result = 0; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.setDisplayNameUsingSrc(displayName, subId, nameSource); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + + } + + /** + * Set phone number by subId + * @param context Context provided by caller + * @param number the phone number of the SIM + * @param subId the unique SubInfoRecord index in database + * @return the number of records updated + */ + public static int setDispalyNumber(Context context, String number, long subId) { + if (VDBG) logd("[setDispalyNumber]+ number:" + number + " subId:" + subId); + if (number == null || subId <= 0) { + logd("[setDispalyNumber]- fail"); + return -1; + } + + int result = 0; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.setDispalyNumber(number, subId); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + + } + + /** + * Set number display format. 0: none, 1: the first four digits, 2: the last four digits + * @param context Context provided by caller + * @param format the display format of phone number + * @param subId the unique SubInfoRecord index in database + * @return the number of records updated + */ + public static int setDisplayNumberFormat(Context context, int format, long subId) { + if (VDBG) logd("[setDisplayNumberFormat]+ format:" + format + " subId:" + subId); + if (format < 0 || subId <= 0) { + logd("[setDisplayNumberFormat]- fail, return -1"); + return -1; + } + + int result = 0; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.setDisplayNumberFormat(format, subId); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + + } + + /** + * Set data roaming by simInfo index + * @param context Context provided by caller + * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming + * @param subId the unique SubInfoRecord index in database + * @return the number of records updated + */ + public static int setDataRoaming(Context context, int roaming, long subId) { + if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId); + if (roaming < 0 || subId <= 0) { + logd("[setDataRoaming]- fail"); + return -1; + } + + int result = 0; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.setDataRoaming(roaming, subId); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + } + + public static int getSlotId(long subId) { + if (VDBG) logd("[getSlotId]+ subId:" + subId); + + int result = 0; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.getSlotId(subId); + } + } catch (RemoteException ex) { + // ignore it + } + + return result; + + } + + public static long[] getSubId(int slotId) { + if (VDBG) logd("[getSubId]+ slotId:" + slotId); + + long[] subId = null; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + subId = iSub.getSubId(slotId); + } + } catch (RemoteException ex) { + // ignore it + } + + return subId; + } + + public static int getPhoneId(long subId) { + if (VDBG) logd("[getPhoneId]+ subId=" + subId); + + int result = 0; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + result = iSub.getPhoneId(subId); + } + } catch (RemoteException ex) { + // ignore it + } + + if (VDBG) logd("[getPhoneId]- phonId=" + result); + return result; + + } + + private static int[] setSimResource(int type) { + int[] simResource = null; + + switch (type) { + case RES_TYPE_BACKGROUND_DARK: + simResource = new int[] { + com.android.internal.R.drawable.sim_dark_blue, + com.android.internal.R.drawable.sim_dark_orange, + com.android.internal.R.drawable.sim_dark_green, + com.android.internal.R.drawable.sim_dark_purple + }; + break; + case RES_TYPE_BACKGROUND_LIGHT: + simResource = new int[] { + com.android.internal.R.drawable.sim_light_blue, + com.android.internal.R.drawable.sim_light_orange, + com.android.internal.R.drawable.sim_light_green, + com.android.internal.R.drawable.sim_light_purple + }; + break; + } + + return simResource; + } + + private static void logd(String msg) { + Rlog.d(LOG_TAG, "[SubManager] " + msg); + } + + public static long normalizeSubId(long subId) { + long retVal = (subId == DEFAULT_SUB_ID) ? getDefaultSubId() : subId; + Rlog.d(LOG_TAG, "[SubManager] normalizeSubId subId=" + retVal); + return retVal; + } + + public static boolean validSubId(long subId) { + return (subId != DEFAULT_SUB_ID) && (subId != -1); + } + + /** + * @return the "system" defaultSubId on a voice capable device this + * will be getDefaultVoiceSubId() and on a data only device it will be + * getDefaultDataSubId(). + */ + public static long getDefaultSubId() { + long subId = 1; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + subId = iSub.getDefaultSubId(); + } + } catch (RemoteException ex) { + // ignore it + } + + if (VDBG) logd("getDefaultSubId=" + subId); + return subId; + } + + public static long getDefaultVoiceSubId() { + long subId = 1; + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + subId = iSub.getDefaultVoiceSubId(); + } + } catch (RemoteException ex) { + // ignore it + } + + if (VDBG) logd("getDefaultSubId, sub id = " + subId); + return subId; + } + + public static void setDefaultVoiceSubId(long subId) { + if (VDBG) logd("setDefaultVoiceSubId sub id = " + subId); + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + iSub.setDefaultVoiceSubId(subId); + } + } catch (RemoteException ex) { + // ignore it + } + } + + public static long getPreferredSmsSubId() { + // FIXME add framework support to get the preferred sub + return getDefaultSubId(); + } + + public static long getPreferredDataSubId() { + // FIXME add framework support to get the preferred sub + return getDefaultSubId(); + } + + public static long getDefaultDataSubId() { + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + return iSub.getDefaultDataSubId(); + } else { + return -1; + } + } catch (RemoteException ex) { + return -1; + } + } + + public static void setDefaultDataSubId(long subId) { + if (VDBG) logd("setDataSubscription sub id = " + subId); + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + iSub.setDefaultDataSubId(subId); + } + } catch (RemoteException ex) { + // ignore it + } + } + + public static void clearSubInfo() + { + if (VDBG) logd("[clearSubInfo]+"); + + try { + ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); + if (iSub != null) { + iSub.clearSubInfo(); + } + } catch (RemoteException ex) { + // ignore it + } + + return; + } + + public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) { + long [] subId = SubscriptionManager.getSubId(phoneId); + if ((subId != null) && (subId.length >= 1)) { + putPhoneIdAndSubIdExtra(intent, phoneId, subId[0]); + } else { + logd("putPhoneIdAndSubIdExtra: no valid subs"); + } + } + + public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, long subId) { + if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId); + intent.putExtra(PhoneConstants.SLOT_KEY, phoneId); //FIXME: RENAME TO PHONE_ID_KEY ?? + intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); + } +} + diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 4d69c9b..35568cf 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -16,22 +16,20 @@ package android.telephony; -import android.annotation.PrivateApi; +import android.annotation.SystemApi; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.content.Context; +import android.content.Intent; import android.os.Bundle; -import android.os.Handler; -import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; -import android.telephony.Rlog; import android.util.Log; +import com.android.internal.telecomm.ITelecommService; import com.android.internal.telephony.IPhoneSubInfo; import com.android.internal.telephony.ITelephony; -import com.android.internal.telephony.ITelephonyListener; import com.android.internal.telephony.ITelephonyRegistry; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.RILConstants; @@ -39,7 +37,6 @@ import com.android.internal.telephony.TelephonyProperties; import java.io.FileInputStream; import java.io.IOException; -import java.util.HashMap; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -65,41 +62,41 @@ import java.util.regex.Pattern; public class TelephonyManager { private static final String TAG = "TelephonyManager"; - private static ITelephonyRegistry sRegistry; - - private final HashMap<CallStateListener,Listener> mListeners - = new HashMap<CallStateListener,Listener>(); - private final Context mContext; - - private static class Listener extends ITelephonyListener.Stub { - final CallStateListener mListener; - private static final int WHAT = 1; + private static final String TELECOMM_SERVICE_NAME = "telecomm"; - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - mListener.onCallStateChanged(msg.arg1, msg.arg2, (String)msg.obj); - } - }; + private static ITelephonyRegistry sRegistry; - Listener(CallStateListener listener) { - mListener = listener; - } + /** + * The allowed states of Wi-Fi calling. + * + * @hide + */ + public interface WifiCallingChoices { + /** Always use Wi-Fi calling */ + static final int ALWAYS_USE = 0; + /** Ask the user whether to use Wi-Fi on every call */ + static final int ASK_EVERY_TIME = 1; + /** Never use Wi-Fi calling */ + static final int NEVER_USE = 2; + } - @Override - public void onUpdate(final int callId, final int state, final String number) { - if (mHandler != null) { - mHandler.sendMessage(mHandler.obtainMessage(WHAT, callId, state, number)); - } - } + private final Context mContext; - void clearQueue() { - mHandler.removeMessages(WHAT); + private static String multiSimConfig = + SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG); - // Don't accept more incoming binder calls either. - mHandler = null; - } - } + /** Enum indicating multisim variants + * DSDS - Dual SIM Dual Standby + * DSDA - Dual SIM Dual Active + * TSTS - Triple SIM Triple Standby + **/ + /** @hide */ + public enum MultiSimVariants { + DSDS, + DSDA, + TSTS, + UNKNOWN + }; /** @hide */ public TelephonyManager(Context context) { @@ -129,11 +126,61 @@ public class TelephonyManager { return sInstance; } + + /** + * Returns the multi SIM variant + * Returns DSDS for Dual SIM Dual Standby + * Returns DSDA for Dual SIM Dual Active + * Returns TSTS for Triple SIM Triple Standby + * Returns UNKNOWN for others + */ + /** {@hide} */ + public MultiSimVariants getMultiSimConfiguration() { + String mSimConfig = + SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG); + if (mSimConfig.equals("dsds")) { + return MultiSimVariants.DSDS; + } else if (mSimConfig.equals("dsda")) { + return MultiSimVariants.DSDA; + } else if (mSimConfig.equals("tsts")) { + return MultiSimVariants.TSTS; + } else { + return MultiSimVariants.UNKNOWN; + } + } + + + /** + * Returns the number of phones available. + * Returns 1 for Single standby mode (Single SIM functionality) + * Returns 2 for Dual standby mode.(Dual SIM functionality) + */ + /** {@hide} */ + public int getPhoneCount() { + int phoneCount = 1; + switch (getMultiSimConfiguration()) { + case DSDS: + case DSDA: + phoneCount = PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM; + break; + case TSTS: + phoneCount = PhoneConstants.MAX_PHONE_COUNT_TRI_SIM; + break; + } + return phoneCount; + } + /** {@hide} */ public static TelephonyManager from(Context context) { return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); } + /** {@hide} */ + public boolean isMultiSimEnabled() { + return (multiSimConfig.equals("dsds") || multiSimConfig.equals("dsda") || + multiSimConfig.equals("tsts")); + } + // // Broadcast Intent actions // @@ -544,8 +591,23 @@ public class TelephonyManager { * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ public String getDeviceId() { + return getDeviceId(getDefaultSim()); + } + + /** + * Returns the unique device ID of a subscription, for example, the IMEI for + * GSM and the MEID for CDMA phones. Return null if device ID is not available. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @param slotId of which deviceID is returned + */ + /** {@hide} */ + public String getDeviceId(int slotId) { + long[] subId = SubscriptionManager.getSubId(slotId); try { - return getSubscriberInfo().getDeviceId(); + return getSubscriberInfo().getDeviceIdUsingSubId(subId[0]); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -593,8 +655,23 @@ public class TelephonyManager { * @hide */ public void enableLocationUpdates() { + enableLocationUpdates(getDefaultSubscription()); + } + + /** + * Enables location update notifications for a subscription. + * {@link PhoneStateListener#onCellLocationChanged + * PhoneStateListener.onCellLocationChanged} will be called on location updates. + * + * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES + * CONTROL_LOCATION_UPDATES} + * + * @param subId for which the location updates are enabled + */ + /** @hide */ + public void enableLocationUpdates(long subId) { try { - getITelephony().enableLocationUpdates(); + getITelephony().enableLocationUpdatesUsingSubId(subId); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -610,8 +687,13 @@ public class TelephonyManager { * @hide */ public void disableLocationUpdates() { + disableLocationUpdates(getDefaultSubscription()); + } + + /** @hide */ + public void disableLocationUpdates(long subId) { try { - getITelephony().disableLocationUpdates(); + getITelephony().disableLocationUpdatesUsingSubId(subId); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -659,22 +741,37 @@ public class TelephonyManager { * {@hide} */ public int getCurrentPhoneType() { + return getCurrentPhoneType(getDefaultSubscription()); + } + + /** + * Returns a constant indicating the device phone type for a subscription. + * + * @see #PHONE_TYPE_NONE + * @see #PHONE_TYPE_GSM + * @see #PHONE_TYPE_CDMA + * + * @param subId for which phone type is returned + */ + /** {@hide} */ + public int getCurrentPhoneType(long subId) { + try{ ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getActivePhoneType(); + return telephony.getActivePhoneTypeUsingSubId(subId); } else { // This can happen when the ITelephony interface is not up yet. - return getPhoneTypeFromProperty(); + return getPhoneTypeFromProperty(subId); } } catch (RemoteException ex) { // This shouldn't happen in the normal case, as a backup we // read from the system property. - return getPhoneTypeFromProperty(); + return getPhoneTypeFromProperty(subId); } catch (NullPointerException ex) { // This shouldn't happen in the normal case, as a backup we // read from the system property. - return getPhoneTypeFromProperty(); + return getPhoneTypeFromProperty(subId); } } @@ -695,20 +792,35 @@ public class TelephonyManager { } private int getPhoneTypeFromProperty() { - int type = - SystemProperties.getInt(TelephonyProperties.CURRENT_ACTIVE_PHONE, - getPhoneTypeFromNetworkType()); - return type; + return getPhoneTypeFromProperty(getDefaultSubscription()); + } + + /** {@hide} */ + private int getPhoneTypeFromProperty(long subId) { + String type = + getTelephonyProperty + (TelephonyProperties.CURRENT_ACTIVE_PHONE, subId, null); + if (type != null) { + return (Integer.parseInt(type)); + } else { + return getPhoneTypeFromNetworkType(subId); + } } private int getPhoneTypeFromNetworkType() { + return getPhoneTypeFromNetworkType(getDefaultSubscription()); + } + + /** {@hide} */ + private int getPhoneTypeFromNetworkType(long subId) { // When the system property CURRENT_ACTIVE_PHONE, has not been set, // use the system property for default network type. // This is a fail safe, and can only happen at first boot. - int mode = SystemProperties.getInt("ro.telephony.default_network", -1); - if (mode == -1) - return PHONE_TYPE_NONE; - return getPhoneType(mode); + String mode = getTelephonyProperty("ro.telephony.default_network", subId, null); + if (mode != null) { + return TelephonyManager.getPhoneType(Integer.parseInt(mode)); + } + return TelephonyManager.PHONE_TYPE_NONE; } /** @@ -733,7 +845,7 @@ public class TelephonyManager { case RILConstants.NETWORK_MODE_GSM_UMTS: case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA: case RILConstants.NETWORK_MODE_LTE_WCDMA: - case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA: + case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA: return PhoneConstants.PHONE_TYPE_GSM; // Use CDMA Phone for the global mode including CDMA @@ -843,7 +955,23 @@ public class TelephonyManager { * on a CDMA network). */ public String getNetworkOperatorName() { - return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ALPHA); + return getNetworkOperatorName(getDefaultSubscription()); + } + + /** + * Returns the alphabetic name of current registered operator + * for a particular subscription. + * <p> + * Availability: Only when user is registered to a network. Result may be + * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if + * on a CDMA network). + * @param subId + */ + /** {@hide} */ + public String getNetworkOperatorName(long subId) { + + return getTelephonyProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA, + subId, ""); } /** @@ -854,17 +982,48 @@ public class TelephonyManager { * on a CDMA network). */ public String getNetworkOperator() { - return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC); + return getNetworkOperator(getDefaultSubscription()); } /** + * Returns the numeric name (MCC+MNC) of current registered operator + * for a particular subscription. + * <p> + * Availability: Only when user is registered to a network. Result may be + * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if + * on a CDMA network). + * + * @param subId + */ + /** {@hide} */ + public String getNetworkOperator(long subId) { + + return getTelephonyProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, + subId, ""); + } + + /** * Returns true if the device is considered roaming on the current * network, for GSM purposes. * <p> * Availability: Only when user registered to a network. */ public boolean isNetworkRoaming() { - return "true".equals(SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING)); + return isNetworkRoaming(getDefaultSubscription()); + } + + /** + * Returns true if the device is considered roaming on the current + * network for a subscription. + * <p> + * Availability: Only when user registered to a network. + * + * @param subId + */ + /** {@hide} */ + public boolean isNetworkRoaming(long subId) { + return "true".equals(getTelephonyProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, + subId, null)); } /** @@ -876,7 +1035,23 @@ public class TelephonyManager { * on a CDMA network). */ public String getNetworkCountryIso() { - return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY); + return getNetworkCountryIso(getDefaultSubscription()); + } + + /** + * Returns the ISO country code equivalent of the current registered + * operator's MCC (Mobile Country Code) of a subscription. + * <p> + * Availability: Only when user is registered to a network. Result may be + * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if + * on a CDMA network). + * + * @param subId for which Network CountryIso is returned + */ + /** {@hide} */ + public String getNetworkCountryIso(long subId) { + return getTelephonyProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, + subId, ""); } /** Network type is unknown */ @@ -923,6 +1098,49 @@ public class TelephonyManager { /** * Returns a constant indicating the radio technology (network type) + * currently in use on the device for a subscription. + * @return the network type + * + * @param subId for which network type is returned + * + * @see #NETWORK_TYPE_UNKNOWN + * @see #NETWORK_TYPE_GPRS + * @see #NETWORK_TYPE_EDGE + * @see #NETWORK_TYPE_UMTS + * @see #NETWORK_TYPE_HSDPA + * @see #NETWORK_TYPE_HSUPA + * @see #NETWORK_TYPE_HSPA + * @see #NETWORK_TYPE_CDMA + * @see #NETWORK_TYPE_EVDO_0 + * @see #NETWORK_TYPE_EVDO_A + * @see #NETWORK_TYPE_EVDO_B + * @see #NETWORK_TYPE_1xRTT + * @see #NETWORK_TYPE_IDEN + * @see #NETWORK_TYPE_LTE + * @see #NETWORK_TYPE_EHRPD + * @see #NETWORK_TYPE_HSPAP + */ + /** {@hide} */ + public int getNetworkType(long subId) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getNetworkTypeUsingSubId(subId); + } else { + // This can happen when the ITelephony interface is not up yet. + return NETWORK_TYPE_UNKNOWN; + } + } catch(RemoteException ex) { + // This shouldn't happen in the normal case + return NETWORK_TYPE_UNKNOWN; + } catch (NullPointerException ex) { + // This could happen before phone restarts due to crashing + return NETWORK_TYPE_UNKNOWN; + } + } + + /** + * Returns a constant indicating the radio technology (network type) * currently in use on the device for data transmission. * @return the network type * @@ -946,10 +1164,22 @@ public class TelephonyManager { * @hide */ public int getDataNetworkType() { + return getDataNetworkType(getDefaultSubscription()); + } + + /** + * Returns a constant indicating the radio technology (network type) + * currently in use on the device for data transmission for a subscription + * @return the network type + * + * @param subId for which network type is returned + */ + /** {@hide} */ + public int getDataNetworkType(long subId) { try{ ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getDataNetworkType(); + return telephony.getDataNetworkTypeUsingSubId(subId); } else { // This can happen when the ITelephony interface is not up yet. return NETWORK_TYPE_UNKNOWN; @@ -969,10 +1199,19 @@ public class TelephonyManager { * @hide */ public int getVoiceNetworkType() { + return getVoiceNetworkType(getDefaultSubscription()); + } + + /** + * Returns the NETWORK_TYPE_xxxx for voice for a subId + * + */ + /** {@hide} */ + public int getVoiceNetworkType(long subId) { try{ ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getVoiceNetworkType(); + return telephony.getVoiceNetworkTypeUsingSubId(subId); } else { // This can happen when the ITelephony interface is not up yet. return NETWORK_TYPE_UNKNOWN; @@ -1038,6 +1277,13 @@ public class TelephonyManager { return getNetworkTypeName(getNetworkType()); } + /** + * Returns a string representation of the radio technology (network type) + * currently in use on the device. + * @param subId for which network type is returned + * @return the name of the radio technology + * + */ /** {@hide} */ public static String getNetworkTypeName(int type) { switch (type) { @@ -1108,8 +1354,20 @@ public class TelephonyManager { * @return true if a ICC card is present */ public boolean hasIccCard() { + return hasIccCard(getDefaultSim()); + } + + /** + * @return true if a ICC card is present for a subscription + * + * @param slotId for which icc card presence is checked + */ + /** {@hide} */ + // FIXME Input argument slotId should be of type int + public boolean hasIccCard(long slotId) { + try { - return getITelephony().hasIccCard(); + return getITelephony().hasIccCardUsingSlotId(slotId); } catch (RemoteException ex) { // Assume no ICC card if remote exception which shouldn't happen return false; @@ -1132,7 +1390,33 @@ public class TelephonyManager { * @see #SIM_STATE_CARD_IO_ERROR */ public int getSimState() { - String prop = SystemProperties.get(TelephonyProperties.PROPERTY_SIM_STATE); + return getSimState(getDefaultSim()); + } + + /** + * Returns a constant indicating the state of the + * device SIM card in a slot. + * + * @param slotId + * + * @see #SIM_STATE_UNKNOWN + * @see #SIM_STATE_ABSENT + * @see #SIM_STATE_PIN_REQUIRED + * @see #SIM_STATE_PUK_REQUIRED + * @see #SIM_STATE_NETWORK_LOCKED + * @see #SIM_STATE_READY + */ + /** {@hide} */ + // FIXME the argument to pass is subId ?? + public int getSimState(int slotId) { + long[] subId = SubscriptionManager.getSubId(slotId); + if (subId == null) { + return SIM_STATE_ABSENT; + } + // FIXME Do not use a property to determine SIM_STATE, call + // appropriate method on some object. + String prop = + getTelephonyProperty(TelephonyProperties.PROPERTY_SIM_STATE, subId[0], ""); if ("ABSENT".equals(prop)) { return SIM_STATE_ABSENT; } @@ -1165,7 +1449,27 @@ public class TelephonyManager { * @see #getSimState */ public String getSimOperator() { - return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC); + long subId = getDefaultSubscription(); + Rlog.d(TAG, "getSimOperator(): default subId=" + subId); + return getSimOperator(subId); + } + + /** + * Returns the MCC+MNC (mobile country code + mobile network code) of the + * provider of the SIM for a particular subscription. 5 or 6 decimal digits. + * <p> + * Availability: SIM state must be {@link #SIM_STATE_READY} + * + * @see #getSimState + * + * @param subId for which SimOperator is returned + */ + /** {@hide} */ + public String getSimOperator(long subId) { + String operator = getTelephonyProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, + subId, ""); + Rlog.d(TAG, "getSimOperator: subId=" + subId + " operator=" + operator); + return operator; } /** @@ -1176,14 +1480,40 @@ public class TelephonyManager { * @see #getSimState */ public String getSimOperatorName() { - return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA); + return getSimOperatorName(getDefaultSubscription()); + } + + /** + * Returns the Service Provider Name (SPN). + * <p> + * Availability: SIM state must be {@link #SIM_STATE_READY} + * + * @see #getSimState + * + * @param subId for which SimOperatorName is returned + */ + /** {@hide} */ + public String getSimOperatorName(long subId) { + return getTelephonyProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, + subId, ""); } /** * Returns the ISO country code equivalent for the SIM provider's country code. */ public String getSimCountryIso() { - return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY); + return getSimCountryIso(getDefaultSubscription()); + } + + /** + * Returns the ISO country code equivalent for the SIM provider's country code. + * + * @param subId for which SimCountryIso is returned + */ + /** {@hide} */ + public String getSimCountryIso(long subId) { + return getTelephonyProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, + subId, ""); } /** @@ -1194,8 +1524,21 @@ public class TelephonyManager { * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ public String getSimSerialNumber() { + return getSimSerialNumber(getDefaultSubscription()); + } + + /** + * Returns the serial number for the given subscription, if applicable. Return null if it is + * unavailable. + * <p> + * @param subId for which Sim Serial number is returned + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + */ + /** {@hide} */ + public String getSimSerialNumber(long subId) { try { - return getSubscriberInfo().getIccSerialNumber(); + return getSubscriberInfo().getIccSerialNumberUsingSubId(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1215,8 +1558,23 @@ public class TelephonyManager { * @hide */ public int getLteOnCdmaMode() { + return getLteOnCdmaMode(getDefaultSubscription()); + } + + /** + * Return if the current radio is LTE on CDMA for Subscription. This + * is a tri-state return value as for a period of time + * the mode may be unknown. + * + * @param subId for which radio is LTE on CDMA is returned + * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE} + * or {@link PhoneConstants#LTE_ON_CDMA_TRUE} + * + */ + /** {@hide} */ + public int getLteOnCdmaMode(long subId) { try { - return getITelephony().getLteOnCdmaMode(); + return getITelephony().getLteOnCdmaModeUsingSubId(subId); } catch (RemoteException ex) { // Assume no ICC card if remote exception which shouldn't happen return PhoneConstants.LTE_ON_CDMA_UNKNOWN; @@ -1240,8 +1598,23 @@ public class TelephonyManager { * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ public String getSubscriberId() { + return getSubscriberId(getDefaultSubscription()); + } + + /** + * Returns the unique subscriber ID, for example, the IMSI for a GSM phone + * for a subscription. + * Return null if it is unavailable. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @param subId whose subscriber id is returned + */ + /** {@hide} */ + public String getSubscriberId(long subId) { try { - return getSubscriberInfo().getSubscriberId(); + return getSubscriberInfo().getSubscriberIdUsingSubId(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1269,6 +1642,27 @@ public class TelephonyManager { } /** + * Returns the Group Identifier Level1 for a GSM phone for a particular subscription. + * Return null if it is unavailable. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @param subscription whose subscriber id is returned + */ + /** {@hide} */ + public String getGroupIdLevel1(long subId) { + try { + return getSubscriberInfo().getGroupIdLevel1UsingSubId(subId); + } catch (RemoteException ex) { + return null; + } catch (NullPointerException ex) { + // This could happen before phone restarts due to crashing + return null; + } + } + + /** * Returns the phone number string for line 1, for example, the MSISDN * for a GSM phone. Return null if it is unavailable. * <p> @@ -1276,8 +1670,31 @@ public class TelephonyManager { * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ public String getLine1Number() { + return getLine1Number(getDefaultSubscription()); + } + + /** + * Returns the phone number string for line 1, for example, the MSISDN + * for a GSM phone for a particular subscription. Return null if it is unavailable. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @param subId whose phone number for line 1 is returned + */ + /** {@hide} */ + public String getLine1Number(long subId) { + String number = null; + try { + number = getITelephony().getLine1NumberForDisplay(subId); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + if (number != null) { + return number; + } try { - return getSubscriberInfo().getLine1Number(); + return getSubscriberInfo().getLine1NumberUsingSubId(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1287,6 +1704,45 @@ public class TelephonyManager { } /** + * Set the phone number string and its alphatag for line 1 for display + * purpose only, for example, displayed in Phone Status. It won't change + * the actual MSISDN/MDN. This setting won't be persisted during power cycle + * and it should be set again after reboot. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param alphaTag alpha-tagging of the dailing nubmer + * @param number The dialing number + */ + public void setLine1NumberForDisplay(String alphaTag, String number) { + setLine1NumberForDisplay(getDefaultSubscription(), alphaTag, number); + } + + /** + * Set the phone number string and its alphatag for line 1 for display + * purpose only, for example, displayed in Phone Status. It won't change + * the actual MSISDN/MDN. This setting won't be persisted during power cycle + * and it should be set again after reboot. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subId the subscriber that the alphatag and dialing number belongs to. + * @param alphaTag alpha-tagging of the dailing nubmer + * @param number The dialing number + */ + public void setLine1NumberForDisplay(long subId, String alphaTag, String number) { + try { + getITelephony().setLine1NumberForDisplay(subId, alphaTag, number); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + } + + /** * Returns the alphabetic identifier associated with the line 1 number. * Return null if it is unavailable. * <p> @@ -1296,8 +1752,32 @@ public class TelephonyManager { * nobody seems to call this. */ public String getLine1AlphaTag() { + return getLine1AlphaTag(getDefaultSubscription()); + } + + /** + * Returns the alphabetic identifier associated with the line 1 number + * for a subscription. + * Return null if it is unavailable. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * @param subId whose alphabetic identifier associated with line 1 is returned + * nobody seems to call this. + */ + /** {@hide} */ + public String getLine1AlphaTag(long subId) { + String alphaTag = null; try { - return getSubscriberInfo().getLine1AlphaTag(); + alphaTag = getITelephony().getLine1AlphaTagForDisplay(subId); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + if (alphaTag != null) { + return alphaTag; + } + try { + return getSubscriberInfo().getLine1AlphaTagUsingSubId(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1316,8 +1796,22 @@ public class TelephonyManager { * @hide */ public String getMsisdn() { + return getMsisdn(getDefaultSubscription()); + } + + /** + * Returns the MSISDN string. + * for a GSM phone. Return null if it is unavailable. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @param subId for which msisdn is returned + */ + /** {@hide} */ + public String getMsisdn(long subId) { try { - return getSubscriberInfo().getMsisdn(); + return getSubscriberInfo().getMsisdnUsingSubId(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1333,8 +1827,21 @@ public class TelephonyManager { * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ public String getVoiceMailNumber() { + return getVoiceMailNumber(getDefaultSubscription()); + } + + /** + * Returns the voice mail number for a subscription. + * Return null if it is unavailable. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * @param subId whose voice mail number is returned + */ + /** {@hide} */ + public String getVoiceMailNumber(long subId) { try { - return getSubscriberInfo().getVoiceMailNumber(); + return getSubscriberInfo().getVoiceMailNumberUsingSubId(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1352,8 +1859,21 @@ public class TelephonyManager { * @hide */ public String getCompleteVoiceMailNumber() { + return getCompleteVoiceMailNumber(getDefaultSubscription()); + } + + /** + * Returns the complete voice mail number. Return null if it is unavailable. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED} + * + * @param subId + */ + /** {@hide} */ + public String getCompleteVoiceMailNumber(long subId) { try { - return getSubscriberInfo().getCompleteVoiceMailNumber(); + return getSubscriberInfo().getCompleteVoiceMailNumberUsingSubId(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1370,8 +1890,20 @@ public class TelephonyManager { * @hide */ public int getVoiceMessageCount() { + return getVoiceMessageCount(getDefaultSubscription()); + } + + /** + * Returns the voice mail count for a subscription. Return 0 if unavailable. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * @param subId whose voice message count is returned + */ + /** {@hide} */ + public int getVoiceMessageCount(long subId) { try { - return getITelephony().getVoiceMessageCount(); + return getITelephony().getVoiceMessageCountUsingSubId(subId); } catch (RemoteException ex) { return 0; } catch (NullPointerException ex) { @@ -1388,8 +1920,22 @@ public class TelephonyManager { * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ public String getVoiceMailAlphaTag() { + return getVoiceMailAlphaTag(getDefaultSubscription()); + } + + /** + * Retrieves the alphabetic identifier associated with the voice + * mail number for a subscription. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * @param subId whose alphabetic identifier associated with the + * voice mail number is returned + */ + /** {@hide} */ + public String getVoiceMailAlphaTag(long subId) { try { - return getSubscriberInfo().getVoiceMailAlphaTag(); + return getSubscriberInfo().getVoiceMailAlphaTagUsingSubId(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1452,7 +1998,6 @@ public class TelephonyManager { return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo")); } - /** Device call state: No activity. */ public static final int CALL_STATE_IDLE = 0; /** Device call state: Ringing. A new call arrived and is @@ -1468,8 +2013,19 @@ public class TelephonyManager { * Returns a constant indicating the call state (cellular) on the device. */ public int getCallState() { + return getCallState(getDefaultSubscription()); + } + + /** + * Returns a constant indicating the call state (cellular) on the device + * for a subscription. + * + * @param subId whose call state is returned + */ + /** {@hide} */ + public int getCallState(long subId) { try { - return getITelephony().getCallState(); + return getITelephony().getCallStateUsingSubId(subId); } catch (RemoteException ex) { // the phone process is restarting. return CALL_STATE_IDLE; @@ -1554,6 +2110,10 @@ public class TelephonyManager { return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); } + private ITelecommService getTelecommService() { + return ITelecommService.Stub.asInterface(ServiceManager.getService(TELECOMM_SERVICE_NAME)); + } + // // // PhoneStateListener @@ -1571,7 +2131,7 @@ public class TelephonyManager { * At registration, and when a specified telephony state * changes, the telephony manager invokes the appropriate * callback method on the listener object and passes the - * current (udpated) values. + * current (updated) values. * <p> * To unregister a listener, pass the listener object and set the * events argument to @@ -1586,8 +2146,8 @@ public class TelephonyManager { public void listen(PhoneStateListener listener, int events) { String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>"; try { - Boolean notifyNow = true; - sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow); + Boolean notifyNow = (getITelephony() != null); + sRegistry.listenUsingSubId(listener.mSubId, pkgForDebug, listener.callback, events, notifyNow); } catch (RemoteException ex) { // system process dead } catch (NullPointerException ex) { @@ -1601,8 +2161,16 @@ public class TelephonyManager { * @hide */ public int getCdmaEriIconIndex() { + return getCdmaEriIconIndex(getDefaultSubscription()); + } + + /** + * Returns the CDMA ERI icon index to display for a subscription + */ + /** {@hide} */ + public int getCdmaEriIconIndex(long subId) { try { - return getITelephony().getCdmaEriIconIndex(); + return getITelephony().getCdmaEriIconIndexUsingSubId(subId); } catch (RemoteException ex) { // the phone process is restarting. return -1; @@ -1619,8 +2187,18 @@ public class TelephonyManager { * @hide */ public int getCdmaEriIconMode() { + return getCdmaEriIconMode(getDefaultSubscription()); + } + + /** + * Returns the CDMA ERI icon mode for a subscription. + * 0 - ON + * 1 - FLASHING + */ + /** {@hide} */ + public int getCdmaEriIconMode(long subId) { try { - return getITelephony().getCdmaEriIconMode(); + return getITelephony().getCdmaEriIconModeUsingSubId(subId); } catch (RemoteException ex) { // the phone process is restarting. return -1; @@ -1635,8 +2213,17 @@ public class TelephonyManager { * @hide */ public String getCdmaEriText() { + return getCdmaEriText(getDefaultSubscription()); + } + + /** + * Returns the CDMA ERI text, of a subscription + * + */ + /** {@hide} */ + public String getCdmaEriText(long subId) { try { - return getITelephony().getCdmaEriText(); + return getITelephony().getCdmaEriTextUsingSubId(subId); } catch (RemoteException ex) { // the phone process is restarting. return null; @@ -1675,8 +2262,6 @@ public class TelephonyManager { * <p> * Note: Voicemail waiting sms, cell broadcasting sms, and MMS are * disabled when device doesn't support sms. - * - * @hide pending API review */ public boolean isSmsCapable() { if (mContext == null) return true; @@ -1753,121 +2338,713 @@ public class TelephonyManager { com.android.internal.R.string.config_mms_user_agent_profile_url); } - /** @hide */ - @PrivateApi - public void dial(String number) { + /** + * Opens a logical channel to the ICC card. + * + * Input parameters equivalent to TS 27.007 AT+CCHO command. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param AID Application id. See ETSI 102.221 and 101.220. + * @return The logical channel id which is negative on error. + */ + public int iccOpenLogicalChannel(String AID) { try { - getITelephony().dial(number); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#dial", e); + return getITelephony().iccOpenLogicalChannel(AID); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + return -1; + } + + /** + * Closes a previously opened logical channel to the ICC card. + * + * Input parameters equivalent to TS 27.007 AT+CCHC command. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param channel is the channel id to be closed as retruned by a successful + * iccOpenLogicalChannel. + * @return true if the channel was closed successfully. + */ + public boolean iccCloseLogicalChannel(int channel) { + try { + return getITelephony().iccCloseLogicalChannel(channel); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + return false; + } + + /** + * Transmit an APDU to the ICC card over a logical channel. + * + * Input parameters equivalent to TS 27.007 AT+CGLA command. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param channel is the channel id to be closed as returned by a successful + * iccOpenLogicalChannel. + * @param cla Class of the APDU command. + * @param instruction Instruction of the APDU command. + * @param p1 P1 value of the APDU command. + * @param p2 P2 value of the APDU command. + * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU + * is sent to the SIM. + * @param data Data to be sent with the APDU. + * @return The APDU response from the ICC card with the status appended at + * the end. If an error occurs, an empty string is returned. + */ + public String iccTransmitApduLogicalChannel(int channel, int cla, + int instruction, int p1, int p2, int p3, String data) { + try { + return getITelephony().iccTransmitApduLogicalChannel(channel, cla, + instruction, p1, p2, p3, data); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + return ""; + } + + /** + * Send ENVELOPE to the SIM and return the response. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param content String containing SAT/USAT response in hexadecimal + * format starting with command tag. See TS 102 223 for + * details. + * @return The APDU response from the ICC card, with the last 4 bytes + * being the status word. If the command fails, returns an empty + * string. + */ + public String sendEnvelopeWithStatus(String content) { + try { + return getITelephony().sendEnvelopeWithStatus(content); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + return ""; + } + + /** + * Read one of the NV items defined in com.android.internal.telephony.RadioNVItems. + * Used for device configuration by some CDMA operators. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param itemID the ID of the item to read. + * @return the NV item as a String, or null on any failure. + * + * @hide + */ + public String nvReadItem(int itemID) { + try { + return getITelephony().nvReadItem(itemID); + } catch (RemoteException ex) { + Rlog.e(TAG, "nvReadItem RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "nvReadItem NPE", ex); + } + return ""; + } + + /** + * Write one of the NV items defined in com.android.internal.telephony.RadioNVItems. + * Used for device configuration by some CDMA operators. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param itemID the ID of the item to read. + * @param itemValue the value to write, as a String. + * @return true on success; false on any failure. + * + * @hide + */ + public boolean nvWriteItem(int itemID, String itemValue) { + try { + return getITelephony().nvWriteItem(itemID, itemValue); + } catch (RemoteException ex) { + Rlog.e(TAG, "nvWriteItem RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "nvWriteItem NPE", ex); + } + return false; + } + + /** + * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. + * Used for device configuration by some CDMA operators. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param preferredRoamingList byte array containing the new PRL. + * @return true on success; false on any failure. + * + * @hide + */ + public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) { + try { + return getITelephony().nvWriteCdmaPrl(preferredRoamingList); + } catch (RemoteException ex) { + Rlog.e(TAG, "nvWriteCdmaPrl RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "nvWriteCdmaPrl NPE", ex); + } + return false; + } + + /** + * Perform the specified type of NV config reset. The radio will be taken offline + * and the device must be rebooted after the operation. Used for device + * configuration by some CDMA operators. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset + * @return true on success; false on any failure. + * + * @hide + */ + public boolean nvResetConfig(int resetType) { + try { + return getITelephony().nvResetConfig(resetType); + } catch (RemoteException ex) { + Rlog.e(TAG, "nvResetConfig RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "nvResetConfig NPE", ex); + } + return false; + } + + /** + * Returns Default subscription. + */ + private static long getDefaultSubscription() { + return SubscriptionManager.getDefaultSubId(); + } + + /** {@hide} */ + public int getDefaultSim() { + //TODO Need to get it from Telephony Devcontroller + return 0; + } + + /** + * Sets the telephony property with the value specified. + * + * @hide + */ + public static void setTelephonyProperty(String property, long subId, String value) { + String propVal = ""; + String p[] = null; + String prop = SystemProperties.get(property); + int phoneId = SubscriptionManager.getPhoneId(subId); + + if (value == null) { + value = ""; + } + + if (prop != null) { + p = prop.split(","); + } + + if (phoneId < 0) return; + + for (int i = 0; i < phoneId; i++) { + String str = ""; + if ((p != null) && (i < p.length)) { + str = p[i]; + } + propVal = propVal + str + ","; + } + + propVal = propVal + value; + if (p != null) { + for (int i = phoneId + 1; i < p.length; i++) { + propVal = propVal + "," + p[i]; + } + } + + // TODO: workaround for QC + if (property.length() > SystemProperties.PROP_NAME_MAX || propVal.length() > SystemProperties.PROP_VALUE_MAX) { + Rlog.d(TAG, "setTelephonyProperty length too long:" + property + ", " + propVal); + return; + } + + Rlog.d(TAG, "setTelephonyProperty property=" + property + " propVal=" + propVal); + SystemProperties.set(property, propVal); + } + + /** + * Convenience function for retrieving a value from the secure settings + * value list as an integer. Note that internally setting values are + * always stored as strings; this function converts the string to an + * integer for you. + * <p> + * This version does not take a default value. If the setting has not + * been set, or the string value is not a number, + * it throws {@link SettingNotFoundException}. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to retrieve. + * @param index The index of the list + * + * @throws SettingNotFoundException Thrown if a setting by the given + * name can't be found or the setting value is not an integer. + * + * @return The value at the given index of settings. + * @hide + */ + public static int getIntAtIndex(android.content.ContentResolver cr, + String name, int index) + throws android.provider.Settings.SettingNotFoundException { + String v = android.provider.Settings.Global.getString(cr, name); + if (v != null) { + String valArray[] = v.split(","); + if ((index >= 0) && (index < valArray.length) && (valArray[index] != null)) { + try { + return Integer.parseInt(valArray[index]); + } catch (NumberFormatException e) { + //Log.e(TAG, "Exception while parsing Integer: ", e); + } + } + } + throw new android.provider.Settings.SettingNotFoundException(name); + } + + /** + * Convenience function for updating settings value as coma separated + * integer values. This will either create a new entry in the table if the + * given name does not exist, or modify the value of the existing row + * with that name. Note that internally setting values are always + * stored as strings, so this function converts the given value to a + * string before storing it. + * + * @param cr The ContentResolver to access. + * @param name The name of the setting to modify. + * @param index The index of the list + * @param value The new value for the setting to be added to the list. + * @return true if the value was set, false on database errors + * @hide + */ + public static boolean putIntAtIndex(android.content.ContentResolver cr, + String name, int index, int value) { + String data = ""; + String valArray[] = null; + String v = android.provider.Settings.Global.getString(cr, name); + + if (v != null) { + valArray = v.split(","); + } + + // Copy the elements from valArray till index + for (int i = 0; i < index; i++) { + String str = ""; + if ((valArray != null) && (i < valArray.length)) { + str = valArray[i]; + } + data = data + str + ","; + } + + data = data + value; + + // Copy the remaining elements from valArray if any. + if (valArray != null) { + for (int i = index+1; i < valArray.length; i++) { + data = data + "," + valArray[i]; + } } + return android.provider.Settings.Global.putString(cr, name, data); + } + + /** + * Gets the telephony property. + * + * @hide + */ + public static String getTelephonyProperty(String property, long subId, String defaultVal) { + String propVal = null; + int phoneId = SubscriptionManager.getPhoneId(subId); + String prop = SystemProperties.get(property); + if ((prop != null) && (prop.length() > 0)) { + String values[] = prop.split(","); + if ((phoneId >= 0) && (phoneId < values.length) && (values[phoneId] != null)) { + propVal = values[phoneId]; + } + } + return propVal == null ? defaultVal : propVal; } /** @hide */ - @PrivateApi - public void call(String callingPackage, String number) { + public int getSimCount() { + if(isMultiSimEnabled()) { + //TODO Need to get it from Telephony Devcontroller + return 2; + } else { + return 1; + } + } + + /** + * Returns the IMS Service Table (IST) that was loaded from the ISIM. + * @return IMS Service Table or null if not present or not loaded + * @hide + */ + public String getIsimIst() { try { - getITelephony().call(callingPackage, number); + return getSubscriberInfo().getIsimIst(); + } catch (RemoteException ex) { + return null; + } catch (NullPointerException ex) { + // This could happen before phone restarts due to crashing + return null; + } + } + + /** + * Returns the IMS Proxy Call Session Control Function(PCSCF) that were loaded from the ISIM. + * @return an array of PCSCF strings with one PCSCF per string, or null if + * not present or not loaded + * @hide + */ + public String[] getIsimPcscf() { + try { + return getSubscriberInfo().getIsimPcscf(); + } catch (RemoteException ex) { + return null; + } catch (NullPointerException ex) { + // This could happen before phone restarts due to crashing + return null; + } + } + + /** + * Returns the response of ISIM Authetification through RIL. + * Returns null if the Authentification hasn't been successed or isn't present iphonesubinfo. + * @return the response of ISIM Authetification, or null if not available + * @hide + * @deprecated + * @see getIccSimChallengeResponse with appType=PhoneConstants.APPTYPE_ISIM + */ + public String getIsimChallengeResponse(String nonce){ + try { + return getSubscriberInfo().getIsimChallengeResponse(nonce); + } catch (RemoteException ex) { + return null; + } catch (NullPointerException ex) { + // This could happen before phone restarts due to crashing + return null; + } + } + + /** + * Returns the response of SIM Authentication through RIL. + * Returns null if the Authentication hasn't been successful + * @param subId subscription ID to be queried + * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx) + * @param data authentication challenge data + * @return the response of SIM Authentication, or null if not available + * @hide + */ + public String getIccSimChallengeResponse(long subId, int appType, String data) { + try { + return getSubscriberInfo().getIccSimChallengeResponse(subId, appType, data); + } catch (RemoteException ex) { + return null; + } catch (NullPointerException ex) { + // This could happen before phone starts + return null; + } + } + + /** + * Returns the response of SIM Authentication through RIL for the default subscription. + * Returns null if the Authentication hasn't been successful + * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx) + * @param data authentication challenge data + * @return the response of SIM Authentication, or null if not available + * @hide + */ + public String getIccSimChallengeResponse(int appType, String data) { + return getIccSimChallengeResponse(getDefaultSubscription(), appType, data); + } + + /** + * Get P-CSCF address from PCO after data connection is established or modified. + * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN + * @return array of P-CSCF address + * @hide + */ + public String[] getPcscfAddress(String apnType) { + try { + return getITelephony().getPcscfAddress(apnType); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#call", e); + return new String[0]; } } - /** @hide */ - @PrivateApi - public boolean showCallScreen() { + /** + * Set IMS registration state + * + * @param Registration state + * @hide + */ + public void setImsRegistrationState(boolean registered) { try { - return getITelephony().showCallScreen(); + getITelephony().setImsRegistrationState(registered); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#showCallScreen", e); + } + } + + /** + * Get the calculated preferred network type. + * Used for debugging incorrect network type. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @return the preferred network type, defined in RILConstants.java or -1 if + * none available. + */ + public int getCalculatedPreferredNetworkType() { + try { + return getITelephony().getCalculatedPreferredNetworkType(); + } catch (RemoteException ex) { + Rlog.e(TAG, "getCalculatedPreferredNetworkType RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "getCalculatedPreferredNetworkType NPE", ex); + } + return -1; + } + + /** + * Get the preferred network type. + * Used for device configuration by some CDMA operators. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @return the preferred network type, defined in RILConstants.java. + */ + public int getPreferredNetworkType() { + try { + return getITelephony().getPreferredNetworkType(); + } catch (RemoteException ex) { + Rlog.e(TAG, "getPreferredNetworkType RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "getPreferredNetworkType NPE", ex); + } + return -1; + } + + /** + * Set the preferred network type. + * Used for device configuration by some CDMA operators. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param networkType the preferred network type, defined in RILConstants.java. + * @return true on success; false on any failure. + */ + public boolean setPreferredNetworkType(int networkType) { + try { + return getITelephony().setPreferredNetworkType(networkType); + } catch (RemoteException ex) { + Rlog.e(TAG, "setPreferredNetworkType RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "setPreferredNetworkType NPE", ex); } return false; } - /** @hide */ - @PrivateApi - public boolean showCallScreenWithDialpad(boolean showDialpad) { + /** + * Set the CDMA subscription source. + * Used for device supporting both NV and RUIM for CDMA. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subscriptionType the subscription type, 0 for RUIM, 1 for NV. + * @return true on success; false on any failure. + */ + public boolean setCdmaSubscription(int subscriptionType) { try { - return getITelephony().showCallScreenWithDialpad(showDialpad); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#showCallScreenWithDialpad", e); + return getITelephony().setCdmaSubscription(subscriptionType); + } catch (RemoteException ex) { + Rlog.e(TAG, "setCdmaSubscription RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "setCdmaSubscription NPE", ex); } return false; } - /** @hide */ - @PrivateApi - public boolean endCall() { + /** + * Values used to return status for hasCarrierPrivileges call. + */ + public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; + public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; + public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; + public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; + + /** + * Has the calling application been granted carrier privileges by the carrier. + * + * If any of the packages in the calling UID has carrier privileges, the + * call will return true. This access is granted by the owner of the UICC + * card and does not depend on the registered carrier. + * + * TODO: Add a link to documentation. + * + * @return CARRIER_PRIVILEGE_STATUS_HAS_ACCESS if the app has carrier privileges. + * CARRIER_PRIVILEGE_STATUS_NO_ACCESS if the app does not have carrier privileges. + * CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED if the carrier rules are not loaded. + * CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES if there was an error loading carrier + * rules (or if there are no rules). + */ + public int hasCarrierPrivileges() { try { - return getITelephony().endCall(); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#endCall", e); + return getITelephony().hasCarrierPrivileges(); + } catch (RemoteException ex) { + Rlog.e(TAG, "hasCarrierPrivileges RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "hasCarrierPrivileges NPE", ex); + } + return CARRIER_PRIVILEGE_STATUS_NO_ACCESS; + } + + /** + * Override the branding for the input ICCID. + * + * Once set, whenever the ICCID is inserted into the device, the service + * provider name (SPN) and the operator name will both be replaced by the + * brand value input. To unset the value, the same function should be + * called with a null brand value. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * or has to be carrier app - see #hasCarrierPrivileges. + * + * @param iccId The ICCID of that the branding applies to. + * @param brand The brand name to display/set. + * @return true if the operation was executed correctly. + */ + public boolean setOperatorBrandOverride(String iccId, String brand) { + // TODO: Validate ICCID format. + try { + return getITelephony().setOperatorBrandOverride(iccId, brand); + } catch (RemoteException ex) { + Rlog.e(TAG, "setOperatorBrandOverride RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "setOperatorBrandOverride NPE", ex); } return false; } + /** + * Expose the rest of ITelephony to @SystemApi + */ + /** @hide */ - @PrivateApi - public void answerRingingCall() { + @SystemApi + public int checkCarrierPrivilegesForPackage(String pkgname) { try { - getITelephony().answerRingingCall(); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#answerRingingCall", e); + return getITelephony().checkCarrierPrivilegesForPackage(pkgname); + } catch (RemoteException ex) { + Rlog.e(TAG, "hasCarrierPrivileges RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "hasCarrierPrivileges NPE", ex); } + return CARRIER_PRIVILEGE_STATUS_NO_ACCESS; } /** @hide */ - @PrivateApi - public void toggleHold() { + @SystemApi + public List<String> getCarrierPackageNamesForBroadcastIntent(Intent intent) { try { - getITelephony().toggleHold(); + return getITelephony().getCarrierPackageNamesForBroadcastIntent(intent); + } catch (RemoteException ex) { + Rlog.e(TAG, "getCarrierPackageNamesForBroadcastIntent RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "getCarrierPackageNamesForBroadcastIntent NPE", ex); + } + return null; + } + + /** @hide */ + @SystemApi + public void dial(String number) { + try { + getITelephony().dial(number); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#toggleHold", e); + Log.e(TAG, "Error calling ITelephony#dial", e); } } /** @hide */ - @PrivateApi - public void merge() { + @SystemApi + public void call(String callingPackage, String number) { try { - getITelephony().merge(); + getITelephony().call(callingPackage, number); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#merge", e); + Log.e(TAG, "Error calling ITelephony#call", e); } } /** @hide */ - @PrivateApi - public void swap() { + @SystemApi + public boolean endCall() { try { - getITelephony().swap(); + return getITelephony().endCall(); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#swap", e); + Log.e(TAG, "Error calling ITelephony#endCall", e); } + return false; } /** @hide */ - @PrivateApi - public void mute(boolean mute) { + @SystemApi + public void answerRingingCall() { try { - getITelephony().mute(mute); + getITelephony().answerRingingCall(); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#mute", e); + Log.e(TAG, "Error calling ITelephony#answerRingingCall", e); } } /** @hide */ - @PrivateApi + @SystemApi public void silenceRinger() { try { - getITelephony().silenceRinger(); + getTelecommService().silenceRinger(); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#silenceRinger", e); + Log.e(TAG, "Error calling ITelecommService#silenceRinger", e); } } /** @hide */ - @PrivateApi + @SystemApi public boolean isOffhook() { try { return getITelephony().isOffhook(); @@ -1878,7 +3055,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean isRinging() { try { return getITelephony().isRinging(); @@ -1889,7 +3066,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean isIdle() { try { return getITelephony().isIdle(); @@ -1900,7 +3077,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean isRadioOn() { try { return getITelephony().isRadioOn(); @@ -1911,7 +3088,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean isSimPinEnabled() { try { return getITelephony().isSimPinEnabled(); @@ -1922,17 +3099,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi - public void cancelMissedCallsNotification() { - try { - getITelephony().cancelMissedCallsNotification(); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#cancelMissedCallsNotification", e); - } - } - - /** @hide */ - @PrivateApi + @SystemApi public boolean supplyPin(String pin) { try { return getITelephony().supplyPin(pin); @@ -1943,7 +3110,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean supplyPuk(String puk, String pin) { try { return getITelephony().supplyPuk(puk, pin); @@ -1954,7 +3121,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public int[] supplyPinReportResult(String pin) { try { return getITelephony().supplyPinReportResult(pin); @@ -1965,7 +3132,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public int[] supplyPukReportResult(String puk, String pin) { try { return getITelephony().supplyPukReportResult(puk, pin); @@ -1976,7 +3143,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean handlePinMmi(String dialString) { try { return getITelephony().handlePinMmi(dialString); @@ -1987,7 +3154,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public void toggleRadioOnOff() { try { getITelephony().toggleRadioOnOff(); @@ -1997,7 +3164,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean setRadio(boolean turnOn) { try { return getITelephony().setRadio(turnOn); @@ -2008,7 +3175,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean setRadioPower(boolean turnOn) { try { return getITelephony().setRadioPower(turnOn); @@ -2019,7 +3186,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public void updateServiceLocation() { try { getITelephony().updateServiceLocation(); @@ -2029,29 +3196,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi - public int enableApnType(String type) { - try { - return getITelephony().enableApnType(type); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#enableApnType", e); - } - return PhoneConstants.APN_REQUEST_FAILED; - } - - /** @hide */ - @PrivateApi - public int disableApnType(String type) { - try { - return getITelephony().disableApnType(type); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#disableApnType", e); - } - return PhoneConstants.APN_REQUEST_FAILED; - } - - /** @hide */ - @PrivateApi + @SystemApi public boolean enableDataConnectivity() { try { return getITelephony().enableDataConnectivity(); @@ -2062,7 +3207,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean disableDataConnectivity() { try { return getITelephony().disableDataConnectivity(); @@ -2073,7 +3218,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean isDataConnectivityPossible() { try { return getITelephony().isDataConnectivityPossible(); @@ -2084,7 +3229,7 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi + @SystemApi public boolean needsOtaServiceProvisioning() { try { return getITelephony().needsOtaServiceProvisioning(); @@ -2095,54 +3240,105 @@ public class TelephonyManager { } /** @hide */ - @PrivateApi - public void playDtmfTone(char digit, boolean timedShortCode) { + @SystemApi + public void setDataEnabled(boolean enable) { try { - getITelephony().playDtmfTone(digit, timedShortCode); + getITelephony().setDataEnabled(enable); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#playDtmfTone", e); + Log.e(TAG, "Error calling ITelephony#setDataEnabled", e); } } /** @hide */ - @PrivateApi - public void stopDtmfTone() { + @SystemApi + public boolean getDataEnabled() { try { - getITelephony().stopDtmfTone(); + return getITelephony().getDataEnabled(); } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#stopDtmfTone", e); + Log.e(TAG, "Error calling ITelephony#getDataEnabled", e); } + return false; } - /** @hide */ - @PrivateApi - public void addCallStateListener(CallStateListener listener) { + /** + * Set whether Android should display a simplified Mobile Network Settings UI. + * The setting won't be persisted during power cycle. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param enable true means enabling the simplified UI. + */ + public void enableSimplifiedNetworkSettings(boolean enable) { + enableSimplifiedNetworkSettings(getDefaultSubscription(), enable); + } + + /** + * Set whether Android should display a simplified Mobile Network Settings UI. + * The setting won't be persisted during power cycle. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subId for which the simplified UI should be enabled or disabled. + * @param enable true means enabling the simplified UI. + */ + public void enableSimplifiedNetworkSettings(long subId, boolean enable) { try { - if (listener == null) { - throw new RuntimeException("Listener can't be null"); - } - if (!mListeners.containsKey(listener)) { - final Listener l = new Listener(listener); - mListeners.put(listener, l); - getITelephony().addListener(l); - } - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#addListener", e); + getITelephony().enableSimplifiedNetworkSettings(subId, enable); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { } } - /** @hide */ - @PrivateApi - public void removeCallStateListener(CallStateListener listener) { - try { - final Listener l = mListeners.remove(listener); - if (l != null) { - // Make sure that no callbacks that are already in flight come. - l.clearQueue(); - getITelephony().removeListener(l); - } - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#removeListener", e); + /** + * Get whether a simplified Mobile Network Settings UI is enabled. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @return true if the simplified UI is enabled. + */ + public boolean getSimplifiedNetworkSettingsEnabled() { + return getSimplifiedNetworkSettingsEnabled(getDefaultSubscription()); + } + + /** + * Get whether a simplified Mobile Network Settings UI is enabled. + * <p> + * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @param subId for which the simplified UI should be enabled or disabled. + * @return true if the simplified UI is enabled. + */ + public boolean getSimplifiedNetworkSettingsEnabled(long subId) { + try { + return getITelephony().getSimplifiedNetworkSettingsEnabled(subId); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + return false; + } + + /** + * Returns the result and response from RIL for oem request + * + * @param oemReq the data is sent to ril. + * @param oemResp the respose data from RIL. + * @return negative value request was not handled or get error + * 0 request was handled succesfully, but no response data + * positive value success, data length of response + * @hide + */ + public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) { + try { + return getITelephony().invokeOemRilRequestRaw(oemReq, oemResp); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { } + return -1; } } diff --git a/telephony/java/android/telephony/VoLteServiceState.aidl b/telephony/java/android/telephony/VoLteServiceState.aidl new file mode 100644 index 0000000..59dd04f --- /dev/null +++ b/telephony/java/android/telephony/VoLteServiceState.aidl @@ -0,0 +1,21 @@ +/* +** +** Copyright (C) 2014 The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.telephony; + +parcelable VoLteServiceState; + diff --git a/telephony/java/android/telephony/VoLteServiceState.java b/telephony/java/android/telephony/VoLteServiceState.java new file mode 100644 index 0000000..afef601 --- /dev/null +++ b/telephony/java/android/telephony/VoLteServiceState.java @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.Rlog; + +/** + * Contains LTE network state related information. + * + * @hide + */ +public final class VoLteServiceState implements Parcelable { + + private static final String LOG_TAG = "VoLteServiceState"; + private static final boolean DBG = false; + + //Use int max, as -1 is a valid value in signal strength + public static final int INVALID = 0x7FFFFFFF; + + public static final int NOT_SUPPORTED = 0; + public static final int SUPPORTED = 1; + + // Single Radio Voice Call Continuity(SRVCC) progress state + public static final int HANDOVER_STARTED = 0; + public static final int HANDOVER_COMPLETED = 1; + public static final int HANDOVER_FAILED = 2; + public static final int HANDOVER_CANCELED = 3; + + private int mSrvccState; + + /** + * Create a new VoLteServiceState from a intent notifier Bundle + * + * This method is used by PhoneStateIntentReceiver and maybe by + * external applications. + * + * @param m Bundle from intent notifier + * @return newly created VoLteServiceState + * + * @hide + */ + public static VoLteServiceState newFromBundle(Bundle m) { + VoLteServiceState ret; + ret = new VoLteServiceState(); + ret.setFromNotifierBundle(m); + return ret; + } + + /** + * Empty constructor + * + * @hide + */ + public VoLteServiceState() { + initialize(); + } + + /** + * Constructor + * + * @hide + */ + public VoLteServiceState(int srvccState) { + initialize(); + + mSrvccState = srvccState; + } + + /** + * Copy constructors + * + * @param s Source VoLteServiceState + * + * @hide + */ + public VoLteServiceState(VoLteServiceState s) { + copyFrom(s); + } + + /** + * Initialize values to defaults. + * + * @hide + */ + private void initialize() { + mSrvccState = INVALID; + } + + /** + * @hide + */ + protected void copyFrom(VoLteServiceState s) { + mSrvccState = s.mSrvccState; + } + + /** + * Construct a VoLteServiceState object from the given parcel. + * + * @hide + */ + public VoLteServiceState(Parcel in) { + if (DBG) log("Size of VoLteServiceState parcel:" + in.dataSize()); + + mSrvccState = in.readInt(); + } + + /** + * {@link Parcelable#writeToParcel} + */ + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mSrvccState); + } + + /** + * {@link Parcelable#describeContents} + */ + public int describeContents() { + return 0; + } + + /** + * {@link Parcelable.Creator} + * + * @hide + */ + public static final Parcelable.Creator<VoLteServiceState> CREATOR = new Parcelable.Creator() { + public VoLteServiceState createFromParcel(Parcel in) { + return new VoLteServiceState(in); + } + + public VoLteServiceState[] newArray(int size) { + return new VoLteServiceState[size]; + } + }; + + /** + * Validate the individual fields as per the range + * specified in ril.h + * Set to invalid any field that is not in the valid range + * + * @return + * Valid values for all fields + * @hide + */ + public void validateInput() { + } + + public int hashCode() { + int primeNum = 31; + return ((mSrvccState * primeNum)); + } + + /** + * @return true if the LTE network states are the same + */ + @Override + public boolean equals (Object o) { + VoLteServiceState s; + + try { + s = (VoLteServiceState) o; + } catch (ClassCastException ex) { + return false; + } + + if (o == null) { + return false; + } + + return (mSrvccState == s.mSrvccState); + } + + /** + * @return string representation. + */ + @Override + public String toString() { + return ("VoLteServiceState:" + + " " + mSrvccState); + } + + /** + * Set VoLteServiceState based on intent notifier map + * + * @param m intent notifier map + * @hide + */ + private void setFromNotifierBundle(Bundle m) { + mSrvccState = m.getInt("mSrvccState"); + } + + /** + * Set intent notifier Bundle based on VoLteServiceState + * + * @param m intent notifier Bundle + * @hide + */ + public void fillInNotifierBundle(Bundle m) { + m.putInt("mSrvccState", mSrvccState); + } + + public int getSrvccState() { + return mSrvccState; + } + + /** + * log + */ + private static void log(String s) { + Rlog.w(LOG_TAG, s); + } +} diff --git a/telephony/java/com/android/ims/ImsCallForwardInfo.aidl b/telephony/java/com/android/ims/ImsCallForwardInfo.aidl new file mode 100644 index 0000000..a7c3f9a --- /dev/null +++ b/telephony/java/com/android/ims/ImsCallForwardInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +parcelable ImsCallForwardInfo; diff --git a/telephony/java/com/android/ims/ImsCallForwardInfo.java b/telephony/java/com/android/ims/ImsCallForwardInfo.java new file mode 100644 index 0000000..3f8fd19 --- /dev/null +++ b/telephony/java/com/android/ims/ImsCallForwardInfo.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Provides the call forward information for the supplementary service configuration. + * + * @hide + */ +public class ImsCallForwardInfo implements Parcelable { + // Refer to ImsUtInterface#CDIV_CF_XXX + public int mCondition; + // 0: disabled, 1: enabled + public int mStatus; + // 0x91: International, 0x81: Unknown + public int mToA; + // Number (it will not include the "sip" or "tel" URI scheme) + public String mNumber; + // No reply timer for CF + public int mTimeSeconds; + + public ImsCallForwardInfo() { + } + + public ImsCallForwardInfo(Parcel in) { + readFromParcel(in); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mCondition); + out.writeInt(mStatus); + out.writeInt(mToA); + out.writeString(mNumber); + out.writeInt(mTimeSeconds); + } + + @Override + public String toString() { + return super.toString() + ", Condition: " + mCondition + + ", Status: " + ((mStatus == 0) ? "disabled" : "enabled") + + ", ToA: " + mToA + ", Number=" + mNumber + + ", Time (seconds): " + mTimeSeconds; + } + + private void readFromParcel(Parcel in) { + mCondition = in.readInt(); + mStatus = in.readInt(); + mToA = in.readInt(); + mNumber = in.readString(); + mTimeSeconds = in.readInt(); + } + + public static final Creator<ImsCallForwardInfo> CREATOR = + new Creator<ImsCallForwardInfo>() { + @Override + public ImsCallForwardInfo createFromParcel(Parcel in) { + return new ImsCallForwardInfo(in); + } + + @Override + public ImsCallForwardInfo[] newArray(int size) { + return new ImsCallForwardInfo[size]; + } + }; +} diff --git a/telephony/java/com/android/ims/ImsCallProfile.aidl b/telephony/java/com/android/ims/ImsCallProfile.aidl new file mode 100644 index 0000000..a356d13 --- /dev/null +++ b/telephony/java/com/android/ims/ImsCallProfile.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +parcelable ImsCallProfile; diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java new file mode 100644 index 0000000..6896f4d --- /dev/null +++ b/telephony/java/com/android/ims/ImsCallProfile.java @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.telecomm.VideoCallProfile; + +/** + * Parcelable object to handle IMS call profile. + * It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111. + * It provides the service and call type, the additional information related to the call. + * + * @hide + */ +public class ImsCallProfile implements Parcelable { + private static final String TAG = "ImsCallProfile"; + + /** + * Service types + */ + /** + * It is for a special case. It helps that the application can make a call + * without IMS connection (not registered). + * In the moment of the call initiation, the device try to connect to the IMS network + * and initiates the call. + */ + public static final int SERVICE_TYPE_NONE = 0; + /** + * It is a default type and can be selected when the device is connected to the IMS network. + */ + public static final int SERVICE_TYPE_NORMAL = 1; + /** + * It is for an emergency call. + */ + public static final int SERVICE_TYPE_EMERGENCY = 2; + + /** + * Call types + */ + /** + * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade) + */ + public static final int CALL_TYPE_VOICE_N_VIDEO = 1; + /** + * IR.92 (Voice only) + */ + public static final int CALL_TYPE_VOICE = 2; + /** + * VT to support IR.92 & IR.94 (voice + video upgrade/downgrade) + */ + public static final int CALL_TYPE_VIDEO_N_VOICE = 3; + /** + * Video Telephony (audio / video two way) + */ + public static final int CALL_TYPE_VT = 4; + /** + * Video Telephony (audio two way / video TX one way) + */ + public static final int CALL_TYPE_VT_TX = 5; + /** + * Video Telephony (audio two way / video RX one way) + */ + public static final int CALL_TYPE_VT_RX = 6; + /** + * Video Telephony (audio two way / video inactive) + */ + public static final int CALL_TYPE_VT_NODIR = 7; + /** + * VideoShare (video two way) + */ + public static final int CALL_TYPE_VS = 8; + /** + * VideoShare (video TX one way) + */ + public static final int CALL_TYPE_VS_TX = 9; + /** + * VideoShare (video RX one way) + */ + public static final int CALL_TYPE_VS_RX = 10; + + /** + * Extra properties for IMS call. + */ + /** + * Boolean extra properties - "true" / "false" + * conference : Indicates if the session is for the conference call or not. + * e_call : Indicates if the session is for the emergency call or not. + * vms : Indicates if the session is connected to the voice mail system or not. + * call_mode_changeable : Indicates if the session is able to upgrade/downgrade + * the video during voice call. + * conference_avail : Indicates if the session can be extended to the conference. + */ + public static final String EXTRA_CONFERENCE = "conference"; + public static final String EXTRA_E_CALL = "e_call"; + public static final String EXTRA_VMS = "vms"; + public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable"; + public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail"; + + /** + * Integer extra properties + * oir : Rule for originating identity (number) presentation, MO/MT. + * {@link ImsCallProfile#OIR_DEFAULT} + * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} + * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} + * cnap : Rule for calling name presentation + * {@link ImsCallProfile#OIR_DEFAULT} + * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} + * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} + * dialstring : To identify the Ims call type, MO + * {@link ImsCallProfile#DIALSTRING_NORMAL_CALL} + * {@link ImsCallProfile#DIALSTRING_SS_CONF} + * {@link ImsCallProfile#DIALSTRING_USSD} + */ + public static final String EXTRA_OIR = "oir"; + public static final String EXTRA_CNAP = "cnap"; + public static final String EXTRA_DIALSTRING = "dialstring"; + + /** + * Values for EXTRA_OIR / EXTRA_CNAP + */ + public static final int OIR_DEFAULT = 0; // "user subscription default value" + public static final int OIR_PRESENTATION_RESTRICTED = 1; + public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; + + /** + * Values for EXTRA_DIALSTRING + */ + // default (normal call) + public static final int DIALSTRING_NORMAL = 0; + // Call for SIP-based user configuration + public static final int DIALSTRING_SS_CONF = 1; + // Call for USSD message + public static final int DIALSTRING_USSD = 2; + + /** + * String extra properties + * oi : Originating identity (number), MT only + * cna : Calling name + * ussd : For network-initiated USSD, MT only + * remote_uri : Connected user identity (it can be used for the conference) + */ + public static final String EXTRA_OI = "oi"; + public static final String EXTRA_CNA = "cna"; + public static final String EXTRA_USSD = "ussd"; + public static final String EXTRA_REMOTE_URI = "remote_uri"; + + public int mServiceType; + public int mCallType; + public Bundle mCallExtras; + public ImsStreamMediaProfile mMediaProfile; + + + + public ImsCallProfile(Parcel in) { + readFromParcel(in); + } + + public ImsCallProfile() { + mServiceType = SERVICE_TYPE_NORMAL; + mCallType = CALL_TYPE_VOICE_N_VIDEO; + mCallExtras = new Bundle(); + mMediaProfile = new ImsStreamMediaProfile(); + } + + public ImsCallProfile(int serviceType, int callType) { + mServiceType = serviceType; + mCallType = callType; + mCallExtras = new Bundle(); + mMediaProfile = new ImsStreamMediaProfile(); + } + + public String getCallExtra(String name) { + return getCallExtra(name, ""); + } + + public String getCallExtra(String name, String defaultValue) { + if (mCallExtras == null) { + return defaultValue; + } + + return mCallExtras.getString(name, defaultValue); + } + + public boolean getCallExtraBoolean(String name) { + return getCallExtraBoolean(name, false); + } + + public boolean getCallExtraBoolean(String name, boolean defaultValue) { + if (mCallExtras == null) { + return defaultValue; + } + + return mCallExtras.getBoolean(name, defaultValue); + } + + public int getCallExtraInt(String name) { + return getCallExtraInt(name, -1); + } + + public int getCallExtraInt(String name, int defaultValue) { + if (mCallExtras == null) { + return defaultValue; + } + + return mCallExtras.getInt(name, defaultValue); + } + + public void setCallExtra(String name, String value) { + if (mCallExtras != null) { + mCallExtras.putString(name, value); + } + } + + public void setCallExtraBoolean(String name, boolean value) { + if (mCallExtras != null) { + mCallExtras.putBoolean(name, value); + } + } + + public void setCallExtraInt(String name, int value) { + if (mCallExtras != null) { + mCallExtras.putInt(name, value); + } + } + + public void updateCallType(ImsCallProfile profile) { + mCallType = profile.mCallType; + } + + public void updateCallExtras(ImsCallProfile profile) { + mCallExtras.clear(); + mCallExtras = (Bundle) profile.mCallExtras.clone(); + } + + @Override + public String toString() { + return "{ serviceType=" + mServiceType + + ", callType=" + mCallType + + ", callExtras=" + mCallExtras.toString() + + ", mediaProfile=" + mMediaProfile.toString() + " }"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mServiceType); + out.writeInt(mCallType); + out.writeParcelable(mCallExtras, 0); + out.writeParcelable(mMediaProfile, 0); + } + + private void readFromParcel(Parcel in) { + mServiceType = in.readInt(); + mCallType = in.readInt(); + mCallExtras = in.readParcelable(null); + mMediaProfile = in.readParcelable(null); + } + + public static final Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() { + @Override + public ImsCallProfile createFromParcel(Parcel in) { + return new ImsCallProfile(in); + } + + @Override + public ImsCallProfile[] newArray(int size) { + return new ImsCallProfile[size]; + } + }; + + /** + * Converts from the call types defined in {@link com.android.ims.ImsCallProfile} to the + * video state values defined in {@link android.telecomm.VideoCallProfile}. + * + * @param callType The call type. + * @return The video state. + */ + public static int getVideoStateFromCallType(int callType) { + switch (callType) { + case CALL_TYPE_VT_NODIR: + return VideoCallProfile.VIDEO_STATE_PAUSED | + VideoCallProfile.VIDEO_STATE_BIDIRECTIONAL; + case CALL_TYPE_VT_TX: + return VideoCallProfile.VIDEO_STATE_TX_ENABLED; + case CALL_TYPE_VT_RX: + return VideoCallProfile.VIDEO_STATE_RX_ENABLED; + case CALL_TYPE_VT: + return VideoCallProfile.VIDEO_STATE_BIDIRECTIONAL; + case CALL_TYPE_VOICE: + return VideoCallProfile.VIDEO_STATE_AUDIO_ONLY; + default: + return VideoCallProfile.VIDEO_STATE_AUDIO_ONLY; + } + } + + /** + * Converts from the video state values defined in {@link android.telecomm.VideoCallProfile} + * to the call types defined in {@link ImsCallProfile}. + * + * @param videoState The video state. + * @return The call type. + */ + public static int getCallTypeFromVideoState(int videoState) { + boolean videoTx = isVideoStateSet(videoState, VideoCallProfile.VIDEO_STATE_TX_ENABLED); + boolean videoRx = isVideoStateSet(videoState, VideoCallProfile.VIDEO_STATE_RX_ENABLED); + boolean isPaused = isVideoStateSet(videoState, VideoCallProfile.VIDEO_STATE_PAUSED); + if (isPaused) { + return ImsCallProfile.CALL_TYPE_VT_NODIR; + } else if (videoTx && !videoRx) { + return ImsCallProfile.CALL_TYPE_VT_TX; + } else if (!videoTx && videoRx) { + return ImsCallProfile.CALL_TYPE_VT_RX; + } else if (videoTx && videoRx) { + return ImsCallProfile.CALL_TYPE_VT; + } + return ImsCallProfile.CALL_TYPE_VOICE; + } + + /** + * Determines if a video state is set in a video state bit-mask. + * + * @param videoState The video state bit mask. + * @param videoStateToCheck The particular video state to check. + * @return True if the video state is set in the bit-mask. + */ + private static boolean isVideoStateSet(int videoState, int videoStateToCheck) { + return (videoState & videoStateToCheck) == videoStateToCheck; + } +} diff --git a/telephony/java/com/android/ims/ImsConferenceState.aidl b/telephony/java/com/android/ims/ImsConferenceState.aidl new file mode 100644 index 0000000..2fc029f --- /dev/null +++ b/telephony/java/com/android/ims/ImsConferenceState.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +parcelable ImsConferenceState; diff --git a/telephony/java/com/android/ims/ImsConferenceState.java b/telephony/java/com/android/ims/ImsConferenceState.java new file mode 100644 index 0000000..f708d5b --- /dev/null +++ b/telephony/java/com/android/ims/ImsConferenceState.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Set; + +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Provides the conference information (defined in RFC 4575) for IMS conference call. + * + * @hide + */ +public class ImsConferenceState implements Parcelable { + /** + * conference-info : user + */ + // user (String) : Tel or SIP URI + public static final String USER = "user"; + // user > display text (String) + public static final String DISPLAY_TEXT = "display-text"; + // user > endpoint (String) : URI or GRUU or Phone number + public static final String ENDPOINT = "endpoint"; + // user > endpoint > status + public static final String STATUS = "status"; + + /** + * status-type (String) : + * "pending" : Endpoint is not yet in the session, but it is anticipated that he/she will + * join in the near future. + * "dialing-out" : Focus has dialed out to connect the endpoint to the conference, + * but the endpoint is not yet in the roster (probably being authenticated). + * "dialing-in" : Endpoint is dialing into the conference, not yet in the roster + * (probably being authenticated). + * "alerting" : PSTN alerting or SIP 180 Ringing was returned for the outbound call; + * endpoint is being alerted. + * "on-hold" : Active signaling dialog exists between an endpoint and a focus, + * but endpoint is "on-hold" for this conference, i.e., he/she is neither "hearing" + * the conference mix nor is his/her media being mixed in the conference. + * "connected" : Endpoint is a participant in the conference. Depending on the media policies, + * he/she can send and receive media to and from other participants. + * "disconnecting" : Focus is in the process of disconnecting the endpoint + * (e.g. in SIP a DISCONNECT or BYE was sent to the endpoint). + * "disconnected" : Endpoint is not a participant in the conference, and no active dialog + * exists between the endpoint and the focus. + * "muted-via-focus" : Active signaling dialog exists beween an endpoint and a focus and + * the endpoint can "listen" to the conference, but the endpoint's media is not being + * mixed into the conference. + * "connect-fail" : Endpoint fails to join the conference by rejecting the conference call. + */ + public static final String STATUS_PENDING = "pending"; + public static final String STATUS_DIALING_OUT = "dialing-out"; + public static final String STATUS_DIALING_IN = "dialing-in"; + public static final String STATUS_ALERTING = "alerting"; + public static final String STATUS_ON_HOLD = "on-hold"; + public static final String STATUS_CONNECTED = "connected"; + public static final String STATUS_DISCONNECTING = "disconnecting"; + public static final String STATUS_DISCONNECTED = "disconnected"; + public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus"; + public static final String STATUS_CONNECT_FAIL = "connect-fail"; + + /** + * conference-info : SIP status code (integer) + */ + public static final String SIP_STATUS_CODE = "sipstatuscode"; + + public HashMap<String, Bundle> mParticipants = new HashMap<String, Bundle>(); + + public ImsConferenceState() { + } + + public ImsConferenceState(Parcel in) { + readFromParcel(in); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mParticipants.size()); + + if (mParticipants.size() > 0) { + Set<Entry<String, Bundle>> entries = mParticipants.entrySet(); + + if (entries != null) { + Iterator<Entry<String, Bundle>> iterator = entries.iterator(); + + while (iterator.hasNext()) { + Entry<String, Bundle> entry = iterator.next(); + + out.writeString(entry.getKey()); + out.writeParcelable(entry.getValue(), 0); + } + } + } + } + + private void readFromParcel(Parcel in) { + int size = in.readInt(); + + for (int i = 0; i < size; ++i) { + String user = in.readString(); + Bundle state = in.readParcelable(null); + mParticipants.put(user, state); + } + } + + public static final Creator<ImsConferenceState> CREATOR = + new Creator<ImsConferenceState>() { + @Override + public ImsConferenceState createFromParcel(Parcel in) { + return new ImsConferenceState(in); + } + + @Override + public ImsConferenceState[] newArray(int size) { + return new ImsConferenceState[size]; + } + }; +} diff --git a/telephony/java/com/android/ims/ImsConfigListener.aidl b/telephony/java/com/android/ims/ImsConfigListener.aidl new file mode 100644 index 0000000..e827774 --- /dev/null +++ b/telephony/java/com/android/ims/ImsConfigListener.aidl @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +/** + * Used by IMS config client to monitor the config operation results. + * {@hide} + */ +oneway interface ImsConfigListener { + /** + * Notifies client the value of the get operation result on the feature config item. + * The arguments are the same as passed to com.android.ims.ImsConfig#getFeatureValue. + * + * @param feature. as defined in com.android.ims.ImsConfig#FeatureConstants. + * @param network. as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. + * @param value. as defined in com.android.ims.ImsConfig#FeatureValueConstants. + * @param status. as defined in com.android.ims.ImsConfig#OperationStatusConstants. + * @return void. + */ + void onGetFeatureResponse(int feature, int network, int value, int status); + + /** + * Notifies client the set value operation result for feature config item. + * Used by clients that need to be notified the set operation result. + * The arguments are the same as passed to com.android.ims.ImsConfig#setFeatureValue. + * The arguments are repeated in the callback to enable the listener to understand + * which configuration attempt failed. + * + * @param feature. as defined in com.android.ims.ImsConfig#FeatureConstants. + * @param network. as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. + * @param value. as defined in com.android.ims.ImsConfig#FeatureValueConstants. + * @param status. as defined in com.android.ims.ImsConfig#OperationStatusConstants. + * + * @return void. + */ + void onSetFeatureResponse(int feature, int network, int value, int status); +}
\ No newline at end of file diff --git a/telephony/java/com/android/ims/ImsReasonInfo.aidl b/telephony/java/com/android/ims/ImsReasonInfo.aidl new file mode 100644 index 0000000..17e6d3a --- /dev/null +++ b/telephony/java/com/android/ims/ImsReasonInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +parcelable ImsReasonInfo; diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java new file mode 100644 index 0000000..99faba6 --- /dev/null +++ b/telephony/java/com/android/ims/ImsReasonInfo.java @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * This class enables an application to get details on why a method call failed. + * + * @hide + */ +public class ImsReasonInfo implements Parcelable { + + /** + * Reason types, defines the error category. + * UNSPECIFIED - unknown error reason + * LOCAL - indicates the local/device error reason + * LOCAL_TIMEOUT - indicates the local error reason when a specific timer is expired + * STATUSCODE - indicates the interworking error reason by SIP status code received + * from the network + * MEDIA - indicates the media error reason (local resource, SDP parameter, etc.) + * USER - indicates the error reason by the local or remote user + * UT - indicates the error reason for the supplementary service configuration + */ + public static final int TYPE_UNSPECIFIED = 0; + public static final int TYPE_LOCAL = 1; + public static final int TYPE_TIMEOUT = 2; + public static final int TYPE_STATUSCODE = 3; + public static final int TYPE_MEDIA = 4; + public static final int TYPE_USER = 5; + public static final int TYPE_UT = 8; + + /** + * Specific code of each types + */ + public static final int CODE_UNSPECIFIED = 0; + + /** + * LOCAL + */ + // IMS -> Telephony + // The passed argument is an invalid + public static final int CODE_LOCAL_ILLEGAL_ARGUMENT = 101; + // The operation is invoked in invalid call state + public static final int CODE_LOCAL_ILLEGAL_STATE = 102; + // IMS service internal error + public static final int CODE_LOCAL_INTERNAL_ERROR = 103; + // IMS service goes down (service connection is lost) + public static final int CODE_LOCAL_IMS_SERVICE_DOWN = 106; + // No pending incoming call exists + public static final int CODE_LOCAL_NO_PENDING_CALL = 107; + + // IMS -> Telephony + // Service unavailable; by power off + public static final int CODE_LOCAL_POWER_OFF = 111; + // Service unavailable; by low battery + public static final int CODE_LOCAL_LOW_BATTERY = 112; + // Service unavailable; by out of service (data service state) + public static final int CODE_LOCAL_NETWORK_NO_SERVICE = 121; + // Service unavailable; by no LTE coverage + // (VoLTE is not supported even though IMS is registered) + public static final int CODE_LOCAL_NETWORK_NO_LTE_COVERAGE = 122; + // Service unavailable; by located in roaming area + public static final int CODE_LOCAL_NETWORK_ROAMING = 123; + // Service unavailable; by IP changed + public static final int CODE_LOCAL_NETWORK_IP_CHANGED = 124; + // Service unavailable; other + public static final int CODE_LOCAL_SERVICE_UNAVAILABLE = 131; + // Service unavailable; IMS connection is lost (IMS is not registered) + public static final int CODE_LOCAL_NOT_REGISTERED = 132; + + // IMS <-> Telephony + // Max call exceeded + public static final int CODE_LOCAL_CALL_EXCEEDED = 141; + // IMS <- Telephony + // Call busy + public static final int CODE_LOCAL_CALL_BUSY = 142; + // Call decline + public static final int CODE_LOCAL_CALL_DECLINE = 143; + // IMS -> Telephony + // SRVCC is in progress + public static final int CODE_LOCAL_CALL_VCC_ON_PROGRESSING = 144; + // Resource reservation is failed (QoS precondition) + public static final int CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 145; + // Retry CS call; VoLTE service can't be provided by the network or remote end + // Resolve the extra code(EXTRA_CODE_CALL_RETRY_*) if the below code is set + public static final int CODE_LOCAL_CALL_CS_RETRY_REQUIRED = 146; + // Retry VoLTE call; VoLTE service can't be provided by the network temporarily + public static final int CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED = 147; + // IMS call is already terminated (in TERMINATED state) + public static final int CODE_LOCAL_CALL_TERMINATED = 148; + + /** + * TIMEOUT (IMS -> Telephony) + */ + // 1xx waiting timer is expired after sending INVITE request (MO only) + public static final int CODE_TIMEOUT_1XX_WAITING = 201; + // User no answer during call setup operation (MO/MT) + // MO : 200 OK to INVITE request is not received, + // MT : No action from user after alerting the call + public static final int CODE_TIMEOUT_NO_ANSWER = 202; + // User no answer during call update operation (MO/MT) + // MO : 200 OK to re-INVITE request is not received, + // MT : No action from user after alerting the call + public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203; + + /** + * STATUSCODE (SIP response code) (IMS -> Telephony) + */ + // 3xx responses + // SIP request is redirected + public static final int CODE_SIP_REDIRECTED = 321; + // 4xx responses + // 400 : Bad Request + public static final int CODE_SIP_BAD_REQUEST = 331; + // 403 : Forbidden + public static final int CODE_SIP_FORBIDDEN = 332; + // 404 : Not Found + public static final int CODE_SIP_NOT_FOUND = 333; + // 415 : Unsupported Media Type + // 416 : Unsupported URI Scheme + // 420 : Bad Extension + public static final int CODE_SIP_NOT_SUPPORTED = 334; + // 408 : Request Timeout + public static final int CODE_SIP_REQUEST_TIMEOUT = 335; + // 480 : Temporarily Unavailable + public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; + // 484 : Address Incomplete + public static final int CODE_SIP_BAD_ADDRESS = 337; + // 486 : Busy Here + // 600 : Busy Everywhere + public static final int CODE_SIP_BUSY = 338; + // 487 : Request Terminated + public static final int CODE_SIP_REQUEST_CANCELLED = 339; + // 406 : Not Acceptable + // 488 : Not Acceptable Here + // 606 : Not Acceptable + public static final int CODE_SIP_NOT_ACCEPTABLE = 340; + // 410 : Gone + // 604 : Does Not Exist Anywhere + public static final int CODE_SIP_NOT_REACHABLE = 341; + // Others + public static final int CODE_SIP_CLIENT_ERROR = 342; + // 5xx responses + // 501 : Server Internal Error + public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; + // 503 : Service Unavailable + public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; + // 504 : Server Time-out + public static final int CODE_SIP_SERVER_TIMEOUT = 353; + // Others + public static final int CODE_SIP_SERVER_ERROR = 354; + // 6xx responses + // 603 : Decline + public static final int CODE_SIP_USER_REJECTED = 361; + // Others + public static final int CODE_SIP_GLOBAL_ERROR = 362; + + /** + * MEDIA (IMS -> Telephony) + */ + // Media resource initialization failed + public static final int CODE_MEDIA_INIT_FAILED = 401; + // RTP timeout (no audio / video traffic in the session) + public static final int CODE_MEDIA_NO_DATA = 402; + // Media is not supported; so dropped the call + public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403; + // Unknown media related errors + public static final int CODE_MEDIA_UNSPECIFIED = 404; + + /** + * USER + */ + // Telephony -> IMS + // User triggers the call end + public static final int CODE_USER_TERMINATED = 501; + // No action while an incoming call is ringing + public static final int CODE_USER_NOANSWER = 502; + // User ignores an incoming call + public static final int CODE_USER_IGNORE = 503; + // User declines an incoming call + public static final int CODE_USER_DECLINE = 504; + // IMS -> Telephony + // The call is terminated by the network or remote user + public static final int CODE_USER_TERMINATED_BY_REMOTE = 510; + + /** + * Extra codes for the specific code value + * This value can be referred when the code is CODE_LOCAL_CALL_CS_RETRY_REQUIRED. + */ + // Try to connect CS call; normal + public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1; + // Try to connect CS call without the notification to user + public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; + // Try to connect CS call by the settings of the menu + public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; + + /** + * UT + */ + public static final int CODE_UT_NOT_SUPPORTED = 801; + public static final int CODE_UT_SERVICE_UNAVAILABLE = 802; + public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803; + public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821; + + + + // For reason type + public int mReasonType; + // For main reason code + public int mCode; + // For the extra code value; it depends on the code value. + public int mExtraCode; + // For the additional message of the reason info. + public String mExtraMessage; + + public ImsReasonInfo() { + mReasonType = TYPE_UNSPECIFIED; + mCode = CODE_UNSPECIFIED; + mExtraCode = CODE_UNSPECIFIED; + mExtraMessage = null; + } + + public ImsReasonInfo(Parcel in) { + readFromParcel(in); + } + + public ImsReasonInfo(int code, int extraCode) { + mReasonType = (int) (code / 100); + mCode = code; + mExtraCode = extraCode; + mExtraMessage = null; + } + + public ImsReasonInfo(int code, int extraCode, String extraMessage) { + mReasonType = (int) (code / 100); + mCode = code; + mExtraCode = extraCode; + mExtraMessage = extraMessage; + } + + /** + * + */ + public int getCode() { + return mCode; + } + + /** + * + */ + public int getExtraCode() { + return mExtraCode; + } + + /** + * + */ + public String getExtraMessage() { + return mExtraMessage; + } + + /** + * + */ + public int getReasonType() { + return mReasonType; + } + + /** + * Returns the string format of {@link ImsReasonInfo} + * + * @return the string format of {@link ImsReasonInfo} + */ + public String toString() { + return "ImsReasonInfo :: {" + mReasonType + ", " + + mCode + ", " + mExtraCode + ", " + mExtraMessage + "}"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mReasonType); + out.writeInt(mCode); + out.writeInt(mExtraCode); + out.writeString(mExtraMessage); + } + + private void readFromParcel(Parcel in) { + mReasonType = in.readInt(); + mCode = in.readInt(); + mExtraCode = in.readInt(); + mExtraMessage = in.readString(); + } + + public static final Creator<ImsReasonInfo> CREATOR = new Creator<ImsReasonInfo>() { + @Override + public ImsReasonInfo createFromParcel(Parcel in) { + return new ImsReasonInfo(in); + } + + @Override + public ImsReasonInfo[] newArray(int size) { + return new ImsReasonInfo[size]; + } + }; +} diff --git a/telephony/java/com/android/ims/ImsSsInfo.aidl b/telephony/java/com/android/ims/ImsSsInfo.aidl new file mode 100644 index 0000000..0ac598b --- /dev/null +++ b/telephony/java/com/android/ims/ImsSsInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +parcelable ImsSsInfo; diff --git a/telephony/java/com/android/ims/ImsSsInfo.java b/telephony/java/com/android/ims/ImsSsInfo.java new file mode 100644 index 0000000..dbde1c6 --- /dev/null +++ b/telephony/java/com/android/ims/ImsSsInfo.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Provides the result to the update operation for the supplementary service configuration. + * + * @hide + */ +public class ImsSsInfo implements Parcelable { + /** + * For the status of service registration or activation/deactivation. + */ + public static final int NOT_REGISTERED = (-1); + public static final int DISABLED = 0; + public static final int ENABLED = 1; + + // 0: disabled, 1: enabled + public int mStatus; + + public ImsSsInfo() { + } + + public ImsSsInfo(Parcel in) { + readFromParcel(in); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mStatus); + } + + @Override + public String toString() { + return super.toString() + ", Status: " + ((mStatus == 0) ? "disabled" : "enabled"); + } + + private void readFromParcel(Parcel in) { + mStatus = in.readInt(); + } + + public static final Creator<ImsSsInfo> CREATOR = + new Creator<ImsSsInfo>() { + @Override + public ImsSsInfo createFromParcel(Parcel in) { + return new ImsSsInfo(in); + } + + @Override + public ImsSsInfo[] newArray(int size) { + return new ImsSsInfo[size]; + } + }; +} diff --git a/telephony/java/com/android/ims/ImsStreamMediaProfile.aidl b/telephony/java/com/android/ims/ImsStreamMediaProfile.aidl new file mode 100644 index 0000000..d648a35 --- /dev/null +++ b/telephony/java/com/android/ims/ImsStreamMediaProfile.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +parcelable ImsStreamMediaProfile; diff --git a/telephony/java/com/android/ims/ImsStreamMediaProfile.java b/telephony/java/com/android/ims/ImsStreamMediaProfile.java new file mode 100644 index 0000000..003499c --- /dev/null +++ b/telephony/java/com/android/ims/ImsStreamMediaProfile.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Parcelable object to handle IMS stream media profile. + * It provides the media direction, quality of audio and/or video. + * + * @hide + */ +public class ImsStreamMediaProfile implements Parcelable { + private static final String TAG = "ImsStreamMediaProfile"; + + /** + * Media directions + */ + public static final int DIRECTION_INVALID = (-1); + public static final int DIRECTION_INACTIVE = 0; + public static final int DIRECTION_RECEIVE = 1; + public static final int DIRECTION_SEND = 2; + public static final int DIRECTION_SEND_RECEIVE = 3; + + /** + * Audio information + */ + public static final int AUDIO_QUALITY_NONE = 0; + public static final int AUDIO_QUALITY_AMR = (1 << 0); + public static final int AUDIO_QUALITY_AMR_WB = (1 << 1); + + /** + * Video information + */ + public static final int VIDEO_QUALITY_NONE = 0; + public static final int VIDEO_QUALITY_QCIF = (1 << 0); + public static final int VIDEO_QUALITY_QVGA_LANDSCAPE = (1 << 1); + public static final int VIDEO_QUALITY_QVGA_PORTRAIT = (1 << 2); + public static final int VIDEO_QUALITY_VGA_LANDSCAPE = (1 << 3); + public static final int VIDEO_QUALITY_VGA_PORTRAIT = (1 << 4); + + // Audio related information + public int mAudioQuality; + public int mAudioDirection; + // Video related information + public int mVideoQuality; + public int mVideoDirection; + + + + public ImsStreamMediaProfile(Parcel in) { + readFromParcel(in); + } + + public ImsStreamMediaProfile() { + mAudioQuality = AUDIO_QUALITY_AMR_WB; + mAudioDirection = DIRECTION_SEND_RECEIVE; + mVideoQuality = VIDEO_QUALITY_NONE; + mVideoDirection = DIRECTION_INVALID; + } + + public ImsStreamMediaProfile(int audioQuality, int audioDirection, + int videoQuality, int videoDirection) { + mAudioQuality = audioQuality; + mAudioDirection = audioDirection; + mVideoQuality = videoQuality; + mVideoDirection = videoDirection; + } + + public void copyFrom(ImsStreamMediaProfile profile) { + mAudioQuality = profile.mAudioQuality; + mAudioDirection = profile.mAudioDirection; + mVideoQuality = profile.mVideoQuality; + mVideoDirection = profile.mVideoDirection; + } + + @Override + public String toString() { + return "{ audioQuality=" + mAudioQuality + + ", audioDirection=" + mAudioDirection + + ", videoQuality=" + mVideoQuality + + ", videoDirection=" + mVideoDirection + " }"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mAudioQuality); + out.writeInt(mAudioDirection); + out.writeInt(mVideoQuality); + out.writeInt(mVideoDirection); + } + + private void readFromParcel(Parcel in) { + mAudioQuality = in.readInt(); + mAudioDirection = in.readInt(); + mVideoQuality = in.readInt(); + mVideoDirection = in.readInt(); + } + + public static final Creator<ImsStreamMediaProfile> CREATOR = + new Creator<ImsStreamMediaProfile>() { + @Override + public ImsStreamMediaProfile createFromParcel(Parcel in) { + return new ImsStreamMediaProfile(in); + } + + @Override + public ImsStreamMediaProfile[] newArray(int size) { + return new ImsStreamMediaProfile[size]; + } + }; +} diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl new file mode 100644 index 0000000..5f2ff36 --- /dev/null +++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims.internal; + +import com.android.ims.ImsCallProfile; +import com.android.ims.ImsStreamMediaProfile; +import com.android.ims.internal.IImsCallSessionListener; + +/** + * An IMS session that is associated with a SIP dialog which is established from/to + * INVITE request or a mid-call transaction to control the session. + * {@hide} + */ +interface IImsCallSession { + /** + * Closes the object. This object is not usable after being closed. + */ + void close(); + + /** + * Gets the call ID of the session. + * + * @return the call ID + */ + String getCallId(); + + /** + * Gets the call profile that this session is associated with + * + * @return the call profile that this session is associated with + */ + ImsCallProfile getCallProfile(); + + /** + * Gets the local call profile that this session is associated with + * + * @return the local call profile that this session is associated with + */ + ImsCallProfile getLocalCallProfile(); + + /** + * Gets the value associated with the specified property of this session. + * + * @return the string value associated with the specified property + */ + String getProperty(String name); + + /** + * Gets the session state. The value returned must be one of the states in + * {@link ImsCallSession#State}. + * + * @return the session state + */ + int getState(); + + /** + * Checks if the session is in a call. + * + * @return true if the session is in a call + */ + boolean isInCall(); + + /** + * Sets the listener to listen to the session events. A {@link IImsCallSession} + * can only hold one listener at a time. Subsequent calls to this method + * override the previous listener. + * + * @param listener to listen to the session events of this object + */ + void setListener(in IImsCallSessionListener listener); + + /** + * Mutes or unmutes the mic for the active call. + * + * @param muted true if the call is muted, false otherwise + */ + void setMute(boolean muted); + + /** + * Initiates an IMS call with the specified target and call profile. + * The session listener is called back upon defined session events. + * The method is only valid to call when the session state is in + * {@link ImsCallSession#State#IDLE}. + * + * @param callee dialed string to make the call to + * @param profile call profile to make the call with the specified service type, + * call type and media information + * @see Listener#callSessionStarted, Listener#callSessionStartFailed + */ + void start(String callee, in ImsCallProfile profile); + + /** + * Initiates an IMS call with the specified participants and call profile. + * The session listener is called back upon defined session events. + * The method is only valid to call when the session state is in + * {@link ImsCallSession#State#IDLE}. + * + * @param participants participant list to initiate an IMS conference call + * @param profile call profile to make the call with the specified service type, + * call type and media information + * @see Listener#callSessionStarted, Listener#callSessionStartFailed + */ + void startConference(in String[] participants, in ImsCallProfile profile); + + /** + * Accepts an incoming call or session update. + * + * @param callType call type specified in {@link ImsCallProfile} to be answered + * @param profile stream media profile {@link ImsStreamMediaProfile} to be answered + * @see Listener#callSessionStarted + */ + void accept(int callType, in ImsStreamMediaProfile profile); + + /** + * Rejects an incoming call or session update. + * + * @param reason reason code to reject an incoming call + * @see Listener#callSessionStartFailed + */ + void reject(int reason); + + /** + * Terminates a call. + * + * @see Listener#callSessionTerminated + */ + void terminate(int reason); + + /** + * Puts a call on hold. When it succeeds, {@link Listener#callSessionHeld} is called. + * + * @param profile stream media profile {@link ImsStreamMediaProfile} to hold the call + * @see Listener#callSessionHeld, Listener#callSessionHoldFailed + */ + void hold(in ImsStreamMediaProfile profile); + + /** + * Continues a call that's on hold. When it succeeds, {@link Listener#callSessionResumed} + * is called. + * + * @param profile stream media profile {@link ImsStreamMediaProfile} to resume the call + * @see Listener#callSessionResumed, Listener#callSessionResumeFailed + */ + void resume(in ImsStreamMediaProfile profile); + + /** + * Merges the active & hold call. When it succeeds, {@link Listener#callSessionMerged} + * is called. + * + * @see Listener#callSessionMerged, Listener#callSessionMergeFailed + */ + void merge(); + + /** + * Updates the current call's properties (ex. call mode change: video upgrade / downgrade). + * + * @param callType call type specified in {@link ImsCallProfile} to be updated + * @param profile stream media profile {@link ImsStreamMediaProfile} to be updated + * @see Listener#callSessionUpdated, Listener#callSessionUpdateFailed + */ + void update(int callType, in ImsStreamMediaProfile profile); + + /** + * Extends this call to the conference call with the specified recipients. + * + * @param participants participant list to be invited to the conference call after extending the call + * @see Listener#sessionConferenceExtened, Listener#sessionConferenceExtendFailed + */ + void extendToConference(in String[] participants); + + /** + * Requests the conference server to invite an additional participants to the conference. + * + * @param participants participant list to be invited to the conference call + * @see Listener#sessionInviteParticipantsRequestDelivered, + * Listener#sessionInviteParticipantsRequestFailed + */ + void inviteParticipants(in String[] participants); + + /** + * Requests the conference server to remove the specified participants from the conference. + * + * @param participants participant list to be removed from the conference call + * @see Listener#sessionRemoveParticipantsRequestDelivered, + * Listener#sessionRemoveParticipantsRequestFailed + */ + void removeParticipants(in String[] participants); + + /** + * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>, + * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15, + * and event flash to 16. Currently, event flash is not supported. + * + * @param code the DTMF to send. Value 0 to 15 (inclusive) are valid inputs. + * @param duration the interval in milli-seconds between the DTMFs + */ + void sendDtmf(int code, int duration); + + /** + * Sends an USSD message. + * + * @param ussdMessage USSD message to send + */ + void sendUssd(String ussdMessage); +} diff --git a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl new file mode 100644 index 0000000..f36cf39 --- /dev/null +++ b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims.internal; + +import com.android.ims.ImsStreamMediaProfile; +import com.android.ims.ImsCallProfile; +import com.android.ims.ImsReasonInfo; +import com.android.ims.ImsConferenceState; +import com.android.ims.internal.IImsCallSession; + +/** + * A listener type for receiving notification on IMS call session events. + * When an event is generated for an {@link IImsCallSession}, the application is notified + * by having one of the methods called on the {@link IImsCallSessionListener}. + * {@hide} + */ +interface IImsCallSessionListener { + /** + * Notifies the result of the basic session operation (setup / terminate). + */ + void callSessionProgressing(in IImsCallSession session, in ImsStreamMediaProfile profile); + void callSessionStarted(in IImsCallSession session, in ImsCallProfile profile); + void callSessionStartFailed(in IImsCallSession session, in ImsReasonInfo reasonInfo); + void callSessionTerminated(in IImsCallSession session, in ImsReasonInfo reasonInfo); + + /** + * Notifies the result of the call hold/resume operation. + */ + void callSessionHeld(in IImsCallSession session, in ImsCallProfile profile); + void callSessionHoldFailed(in IImsCallSession session, in ImsReasonInfo reasonInfo); + void callSessionHoldReceived(in IImsCallSession session, in ImsCallProfile profile); + void callSessionResumed(in IImsCallSession session, in ImsCallProfile profile); + void callSessionResumeFailed(in IImsCallSession session, in ImsReasonInfo reasonInfo); + void callSessionResumeReceived(in IImsCallSession session, in ImsCallProfile profile); + + /** + * Notifiies the result of call merge operation. + */ + void callSessionMerged(in IImsCallSession session, + in IImsCallSession newSession, in ImsCallProfile profile); + void callSessionMergeFailed(in IImsCallSession session, + in ImsReasonInfo reasonInfo); + + /** + * Notifies the result of call upgrade / downgrade or any other call updates. + */ + void callSessionUpdated(in IImsCallSession session, + in ImsCallProfile profile); + void callSessionUpdateFailed(in IImsCallSession session, + in ImsReasonInfo reasonInfo); + void callSessionUpdateReceived(in IImsCallSession session, + in ImsCallProfile profile); + + /** + * Notifies the result of conference extension. + */ + void callSessionConferenceExtended(in IImsCallSession session, + in IImsCallSession newSession, in ImsCallProfile profile); + void callSessionConferenceExtendFailed(in IImsCallSession session, + in ImsReasonInfo reasonInfo); + void callSessionConferenceExtendReceived(in IImsCallSession session, + in IImsCallSession newSession, in ImsCallProfile profile); + + /** + * Notifies the result of the participant invitation / removal to/from the conference session. + */ + void callSessionInviteParticipantsRequestDelivered(in IImsCallSession session); + void callSessionInviteParticipantsRequestFailed(in IImsCallSession session, + in ImsReasonInfo reasonInfo); + void callSessionRemoveParticipantsRequestDelivered(in IImsCallSession session); + void callSessionRemoveParticipantsRequestFailed(in IImsCallSession session, + in ImsReasonInfo reasonInfo); + + /** + * Notifies the changes of the conference info. in the conference session. + */ + void callSessionConferenceStateUpdated(in IImsCallSession session, + in ImsConferenceState state); + + /** + * Notifies the incoming USSD message. + */ + void callSessionUssdMessageReceived(in IImsCallSession session, + int mode, String ussdMessage); +} diff --git a/telephony/java/com/android/ims/internal/IImsConfig.aidl b/telephony/java/com/android/ims/internal/IImsConfig.aidl new file mode 100644 index 0000000..e8d921e --- /dev/null +++ b/telephony/java/com/android/ims/internal/IImsConfig.aidl @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.android.ims.internal; + +import com.android.ims.ImsConfigListener; + +/** + * Provides APIs to get/set the IMS service capability/parameters. + * The parameters can be configured by operator and/or user. + * We define 4 storage locations for the IMS config items: + * 1) Default config:For factory out device or device after factory data reset, + * the default config is used to build the initial state of the master config value. + * 2) Provisioned value: as the parameters provisioned by operator need to be preserved + * across FDR(factory data reset)/BOTA(over the air software upgrade), the operator + * provisioned items should be stored in memory location preserved across FDR/BOTA. + * 3) Master value: as the provisioned value can override the user setting, + * and the master config are used by IMS stack. They should be stored in the + * storage based on IMS vendor implementations. + * 4) User setting: For items can be changed by both user/operator, the user + * setting should take effect in some cases. So the user setting should be stored in + * database like setting.db. + * + * Priority consideration if both operator/user can config the same item: + * 1) For feature config items, the master value is obtained from the provisioned value + * masks with the user setting. Specifically the provisioned values overrides + * the user setting if feature is provisioned off. Otherwise, user setting takes + * effect. + * 2) For non-feature config item: to be implemented based on cases. + * Special cases considered as below: + * 1) Factory out device, the master configuration is built from default config. + * 2) For Factory data reset/SW upgrade device, the master config is built by + * taking provisioned value overriding default config. + * {@hide} + */ +interface IImsConfig { + /** + * Gets the value for ims service/capabilities parameters from the master + * value storage. Synchronous blocking call. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @return value in Integer format. + */ + int getMasterValue(int item); + + /** + * Gets the value for ims service/capabilities parameters from the master + * value storage. Synchronous blocking call. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @return value in String format. + */ + String getMasterStringValue(int item); + + /** + * Sets the value for IMS service/capabilities parameters by the operator device + * management entity. It sets the config item value in the provisioned storage + * from which the master value is derived. Synchronous blocking call. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param value in Integer format. + * @return void. + */ + void setProvisionedValue(int item, int value); + + /** + * Sets the value for IMS service/capabilities parameters by the operator device + * management entity. It sets the config item value in the provisioned storage + * from which the master value is derived. Synchronous blocking call. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param value in String format. + * @return void. + */ + void setProvisionedStringValue(int item, String value); + + /** + * Gets the value of the specified IMS feature item for specified network type. + * This operation gets the feature config value from the master storage (i.e. final + * value). Asynchronous non-blocking call. + * + * @param feature. as defined in com.android.ims.ImsConfig#FeatureConstants. + * @param network. as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. + * @param listener. feature value returned asynchronously through listener. + * @return void + */ + oneway void getFeatureValue(int feature, int network, ImsConfigListener listener); + + /** + * Sets the value for IMS feature item for specified network type. + * This operation stores the user setting in setting db from which master db + * is dervied. + * + * @param feature. as defined in com.android.ims.ImsConfig#FeatureConstants. + * @param network. as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. + * @param value. as defined in com.android.ims.ImsConfig#FeatureValueConstants. + * @param listener, provided if caller needs to be notified for set result. + * @return void + */ + oneway void setFeatureValue(int feature, int network, int value, ImsConfigListener listener); +} diff --git a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl new file mode 100644 index 0000000..1413e58 --- /dev/null +++ b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims.internal; + +/** + * A listener type for receiving notifications about the changes to + * the IMS connection(registration). + * + * {@hide} + */ +interface IImsRegistrationListener { + /** + * Notifies the application when the device is connected to the IMS network. + */ + void registrationConnected(); + + /** + * Notifies the application when the device is disconnected from the IMS network. + */ + void registrationDisconnected(); + + /** + * Notifies the application when its suspended IMS connection is resumed, + * meaning the connection now allows throughput. + */ + void registrationResumed(); + + /** + * Notifies the application when its current IMS connection is suspended, + * meaning there is no data throughput. + */ + void registrationSuspended(); + + /** + * Notifies the application when its current IMS connection is updated + * since the service setting is changed or the service is added/removed. + * + * @param serviceClass a service class specified in {@link ImsServiceClass} + * @param event an event type when this callback is called + * If {@code event} is 0, meaning the specified service is removed from the IMS connection. + * Else ({@code event} is 1), meaning the specified service is added to the IMS connection. + */ + void registrationServiceCapabilityChanged(int serviceClass, int event); + + /** + * Notifies the application when features on a particular service enabled or + * disabled successfully based on user preferences. + * + * @param serviceClass a service class specified in {@link ImsServiceClass} + * @param enabledFeatures features enabled as defined in com.android.ims.ImsConfig#FeatureConstants. + * @param disabledFeatures features disabled as defined in com.android.ims.ImsConfig#FeatureConstants. + */ + void registrationFeatureCapabilityChanged(int serviceClass, + out int[] enabledFeatures, out int[] disabledFeatures); +} diff --git a/telephony/java/com/android/ims/internal/IImsService.aidl b/telephony/java/com/android/ims/internal/IImsService.aidl new file mode 100644 index 0000000..869cd9f --- /dev/null +++ b/telephony/java/com/android/ims/internal/IImsService.aidl @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims.internal; + +import android.app.PendingIntent; + +import com.android.ims.ImsCallProfile; +import com.android.ims.internal.IImsRegistrationListener; +import com.android.ims.internal.IImsCallSession; +import com.android.ims.internal.IImsCallSessionListener; +import com.android.ims.internal.IImsUt; +import com.android.ims.internal.IImsConfig; + +/** + * {@hide} + */ +interface IImsService { + int open(int serviceClass, in PendingIntent incomingCallIntent, + in IImsRegistrationListener listener); + void close(int serviceId); + boolean isConnected(int serviceId, int serviceType, int callType); + boolean isOpened(int serviceId); + void setRegistrationListener(int serviceId, in IImsRegistrationListener listener); + + ImsCallProfile createCallProfile(int serviceId, int serviceType, int callType); + + IImsCallSession createCallSession(int serviceId, in ImsCallProfile profile, + in IImsCallSessionListener listener); + IImsCallSession getPendingCallSession(int serviceId, String callId); + + /** + * Ut interface for the supplementary service configuration. + */ + IImsUt getUtInterface(int serviceId); + + /** + * Config interface to get/set IMS service/capability parameters. + */ + IImsConfig getConfigInterface(); + + /** + * Used for turning on IMS when its in OFF state. + */ + void turnOnIms(); + + /** + * Used for turning off IMS when its in ON state. + * When IMS is OFF, device will behave as CSFB'ed. + */ + void turnOffIms(); +} diff --git a/telephony/java/com/android/internal/telephony/ITelephonyListener.aidl b/telephony/java/com/android/ims/internal/IImsStreamMediaSession.aidl index c226217..459c685 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsStreamMediaSession.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * Copyright (c) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,12 @@ * limitations under the License. */ -package com.android.internal.telephony; +package com.android.ims.internal; /** - * Interface used to register a listener that gets more detailed call state information than - * {@link android.telephony.PhoneStateListener} * * {@hide} */ -oneway interface ITelephonyListener { - void onUpdate(int callId, int state, String number); +interface IImsStreamMediaSession { + void close(); } diff --git a/telephony/java/com/android/ims/internal/IImsUt.aidl b/telephony/java/com/android/ims/internal/IImsUt.aidl new file mode 100644 index 0000000..f9375e4 --- /dev/null +++ b/telephony/java/com/android/ims/internal/IImsUt.aidl @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims.internal; + +import android.os.Bundle; + +import com.android.ims.internal.IImsUtListener; + +/** + * Provides the Ut interface interworking to get/set the supplementary service configuration. + * + * {@hide} + */ +interface IImsUt { + /** + * Closes the object. This object is not usable after being closed. + */ + void close(); + + /** + * Retrieves the configuration of the call barring. + */ + int queryCallBarring(int cbType); + + /** + * Retrieves the configuration of the call forward. + */ + int queryCallForward(int condition, String number); + + /** + * Retrieves the configuration of the call waiting. + */ + int queryCallWaiting(); + + /** + * Retrieves the default CLIR setting. + */ + int queryCLIR(); + + /** + * Retrieves the CLIP call setting. + */ + int queryCLIP(); + + /** + * Retrieves the COLR call setting. + */ + int queryCOLR(); + + /** + * Retrieves the COLP call setting. + */ + int queryCOLP(); + + /** + * Updates or retrieves the supplementary service configuration. + */ + int transact(in Bundle ssInfo); + + /** + * Updates the configuration of the call barring. + */ + int updateCallBarring(int cbType, boolean enable); + + /** + * Updates the configuration of the call forward. + */ + int updateCallForward(int action, int condition, String number, int timeSeconds); + + /** + * Updates the configuration of the call waiting. + */ + int updateCallWaiting(boolean enable); + + /** + * Updates the configuration of the CLIR supplementary service. + */ + int updateCLIR(int clirMode); + + /** + * Updates the configuration of the CLIP supplementary service. + */ + int updateCLIP(boolean enable); + + /** + * Updates the configuration of the COLR supplementary service. + */ + int updateCOLR(int presentation); + + /** + * Updates the configuration of the COLP supplementary service. + */ + int updateCOLP(boolean enable); + + /** + * Sets the listener. + */ + void setListener(in IImsUtListener listener); +} diff --git a/telephony/java/com/android/ims/internal/IImsUtListener.aidl b/telephony/java/com/android/ims/internal/IImsUtListener.aidl new file mode 100644 index 0000000..3f1b5a7 --- /dev/null +++ b/telephony/java/com/android/ims/internal/IImsUtListener.aidl @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims.internal; + +import android.os.Bundle; + +import com.android.ims.ImsCallForwardInfo; +import com.android.ims.ImsSsInfo; +import com.android.ims.internal.IImsUt; + +/** + * {@hide} + */ +interface IImsUtListener { + /** + * Notifies the result of the supplementary service configuration udpate. + */ + void utConfigurationUpdated(in IImsUt ut, int id); + void utConfigurationUpdateFailed(in IImsUt ut, int id, int errorCode); + + /** + * Notifies the result of the supplementary service configuration query. + */ + void utConfigurationQueried(in IImsUt ut, int id, in Bundle ssInfo); + void utConfigurationQueryFailed(in IImsUt ut, int id, int errorCode); + + /** + * Notifies the status of the call barring supplementary service. + */ + void utConfigurationCallBarringQueried(in IImsUt ut, + int id, in ImsSsInfo[] cbInfo); + + /** + * Notifies the status of the call forwarding supplementary service. + */ + void utConfigurationCallForwardQueried(in IImsUt ut, + int id, in ImsCallForwardInfo[] cfInfo); + + /** + * Notifies the status of the call waiting supplementary service. + */ + void utConfigurationCallWaitingQueried(in IImsUt ut, + int id, in ImsSsInfo[] cwInfo); +} diff --git a/telephony/java/com/android/internal/telephony/CallInfo.aidl b/telephony/java/com/android/internal/telephony/CallInfo.aidl new file mode 100644 index 0000000..9140388 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/CallInfo.aidl @@ -0,0 +1,19 @@ +/* +** Copyright 2013, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package com.android.internal.telephony; + +parcelable CallInfo; diff --git a/telephony/java/com/android/internal/telephony/CallInfo.java b/telephony/java/com/android/internal/telephony/CallInfo.java new file mode 100644 index 0000000..6bfc9d7 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/CallInfo.java @@ -0,0 +1,77 @@ +/* +** Copyright 2013, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package com.android.internal.telephony; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A parcelable holder class of Call information data. + */ +public class CallInfo implements Parcelable { + + /** + * Endpoint to which the call is connected. + * This could be the dialed value for outgoing calls or the caller id of incoming calls. + */ + private String handle; + + public CallInfo(String handle) { + this.handle = handle; + } + + public String getHandle() { + return handle; + } + + // + // Parcelling related code below here. + // + + /** + * Responsible for creating CallInfo objects for deserialized Parcels. + */ + public static final Parcelable.Creator<CallInfo> CREATOR + = new Parcelable.Creator<CallInfo> () { + + @Override + public CallInfo createFromParcel(Parcel source) { + return new CallInfo(source.readString()); + } + + @Override + public CallInfo[] newArray(int size) { + return new CallInfo[size]; + } + }; + + /** + * {@inheritDoc} + */ + @Override + public int describeContents() { + return 0; + } + + /** + * Writes CallInfo object into a serializeable Parcel. + */ + @Override + public void writeToParcel(Parcel destination, int flags) { + destination.writeString(handle); + } +} diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java index f6143ed..c9c4586 100644 --- a/telephony/java/com/android/internal/telephony/CallerInfo.java +++ b/telephony/java/com/android/internal/telephony/CallerInfo.java @@ -24,6 +24,7 @@ import android.location.Country; import android.location.CountryDetector; import android.net.Uri; import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.PhoneLookup; import android.provider.ContactsContract.RawContacts; @@ -37,6 +38,9 @@ import com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder; import com.android.i18n.phonenumbers.NumberParseException; import com.android.i18n.phonenumbers.PhoneNumberUtil; import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber; +import android.telephony.SubscriptionManager; + +import android.telephony.TelephonyManager; import java.util.Locale; @@ -93,10 +97,18 @@ public class CallerInfo { public String numberLabel; public int photoResource; - public long person_id; + + // Contact ID, which will be 0 if a contact comes from the corp CP2. + public long contactIdOrZero; public boolean needUpdate; public Uri contactRefUri; + /** + * Contact display photo URI. If a contact has no display photo but a thumbnail, it'll be + * the thumbnail URI instead. + */ + public Uri contactDisplayPhotoUri; + // fields to hold individual contact preference data, // including the send to voicemail flag and the ringtone // uri reference. @@ -206,16 +218,29 @@ public class CallerInfo { // Look for the person_id. columnIndex = getColumnIndexForPersonId(contactRef, cursor); if (columnIndex != -1) { - info.person_id = cursor.getLong(columnIndex); - if (VDBG) Rlog.v(TAG, "==> got info.person_id: " + info.person_id); + final long contactId = cursor.getLong(columnIndex); + if (contactId != 0 && !Contacts.isCorpContactId(contactId)) { + info.contactIdOrZero = contactId; + if (VDBG) { + Rlog.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero); + } + } } else { // No valid columnIndex, so we can't look up person_id. - Rlog.w(TAG, "Couldn't find person_id column for " + contactRef); + Rlog.w(TAG, "Couldn't find contact_id column for " + contactRef); // Watch out: this means that anything that depends on // person_id will be broken (like contact photo lookups in // the in-call UI, for example.) } + // Display photo URI. + columnIndex = cursor.getColumnIndex(PhoneLookup.PHOTO_URI); + if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { + info.contactDisplayPhotoUri = Uri.parse(cursor.getString(columnIndex)); + } else { + info.contactDisplayPhotoUri = null; + } + // look for the custom ringtone, create from the string stored // in the database. columnIndex = cursor.getColumnIndex(PhoneLookup.CUSTOM_RINGTONE); @@ -233,6 +258,7 @@ public class CallerInfo { info.contactExists = true; } cursor.close(); + cursor = null; } info.needUpdate = false; @@ -253,7 +279,8 @@ public class CallerInfo { public static CallerInfo getCallerInfo(Context context, Uri contactRef) { return getCallerInfo(context, contactRef, - context.getContentResolver().query(contactRef, null, null, null, null)); + CallerInfoAsyncQuery.getCurrentProfileContentResolver(context) + .query(contactRef, null, null, null, null)); } /** @@ -269,6 +296,23 @@ public class CallerInfo { public static CallerInfo getCallerInfo(Context context, String number) { if (VDBG) Rlog.v(TAG, "getCallerInfo() based on number..."); + long subId = SubscriptionManager.getDefaultSubId(); + return getCallerInfo(context, number, subId); + } + + /** + * getCallerInfo given a phone number and subscription, look up in the call-log database + * for the matching caller id info. + * @param context the context used to get the ContentResolver + * @param number the phone number used to lookup caller id + * @param subId the subscription for checking for if voice mail number or not + * @return the CallerInfo which contains the caller id for the given + * number. The returned CallerInfo is null if no number is supplied. If + * a matching number is not found, then a generic caller info is returned, + * with all relevant fields empty or null. + */ + public static CallerInfo getCallerInfo(Context context, String number, long subId) { + if (TextUtils.isEmpty(number)) { return null; } @@ -276,13 +320,14 @@ public class CallerInfo { // Change the callerInfo number ONLY if it is an emergency number // or if it is the voicemail number. If it is either, take a // shortcut and skip the query. - if (PhoneNumberUtils.isLocalEmergencyNumber(number, context)) { + if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) { return new CallerInfo().markAsEmergency(context); - } else if (PhoneNumberUtils.isVoiceMailNumber(number)) { + } else if (PhoneNumberUtils.isVoiceMailNumber(subId, number)) { return new CallerInfo().markAsVoiceMail(); } - Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); + Uri contactUri = Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, + Uri.encode(number)); CallerInfo info = getCallerInfo(context, contactUri); info = doSecondaryLookupIfNecessary(context, number, info); @@ -313,46 +358,13 @@ public class CallerInfo { String username = PhoneNumberUtils.getUsernameFromUriNumber(number); if (PhoneNumberUtils.isGlobalPhoneNumber(username)) { previousResult = getCallerInfo(context, - Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, + Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, Uri.encode(username))); } } return previousResult; } - /** - * getCallerId: a convenience method to get the caller id for a given - * number. - * - * @param context the context used to get the ContentResolver. - * @param number a phone number. - * @return if the number belongs to a contact, the contact's name is - * returned; otherwise, the number itself is returned. - * - * TODO NOTE: This MAY need to refer to the Asynchronous Query API - * [startQuery()], instead of getCallerInfo, but since it looks like - * it is only being used by the provider calls in the messaging app: - * 1. android.provider.Telephony.Mms.getDisplayAddress() - * 2. android.provider.Telephony.Sms.getDisplayAddress() - * We may not need to make the change. - */ - public static String getCallerId(Context context, String number) { - CallerInfo info = getCallerInfo(context, number); - String callerID = null; - - if (info != null) { - String name = info.name; - - if (!TextUtils.isEmpty(name)) { - callerID = name; - } else { - callerID = number; - } - } - - return callerID; - } - // Accessors /** @@ -400,10 +412,17 @@ public class CallerInfo { // TODO: As in the emergency number handling, we end up writing a // string in the phone number field. /* package */ CallerInfo markAsVoiceMail() { + + long subId = SubscriptionManager.getDefaultSubId(); + return markAsVoiceMail(subId); + + } + + /* package */ CallerInfo markAsVoiceMail(long subId) { mIsVoiceMail = true; try { - String voiceMailLabel = TelephonyManager.getDefault().getVoiceMailAlphaTag(); + String voiceMailLabel = TelephonyManager.getDefault().getVoiceMailAlphaTag(subId); phoneNumber = voiceMailLabel; } catch (SecurityException se) { @@ -608,10 +627,10 @@ public class CallerInfo { .append("\nnumberType: " + numberType) .append("\nnumberLabel: " + numberLabel) .append("\nphotoResource: " + photoResource) - .append("\nperson_id: " + person_id) + .append("\ncontactIdOrZero: " + contactIdOrZero) .append("\nneedUpdate: " + needUpdate) - .append("\ncontactRefUri: " + contactRefUri) - .append("\ncontactRingtoneUri: " + contactRefUri) + .append("\ncontactRingtoneUri: " + contactRingtoneUri) + .append("\ncontactDisplayPhotoUri: " + contactDisplayPhotoUri) .append("\nshouldSendToVoicemail: " + shouldSendToVoicemail) .append("\ncachedPhoto: " + cachedPhoto) .append("\nisCachedPhotoCurrent: " + isCachedPhotoCurrent) diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java index c63be91..0d18389 100644 --- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java +++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java @@ -16,21 +16,25 @@ package com.android.internal.telephony; +import android.app.ActivityManager; import android.content.AsyncQueryHandler; +import android.content.ContentResolver; import android.content.Context; +import android.content.pm.PackageManager.NameNotFoundException; import android.database.Cursor; import android.database.SQLException; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.SystemProperties; -import android.provider.ContactsContract.CommonDataKinds.SipAddress; -import android.provider.ContactsContract.Data; +import android.os.UserHandle; +import android.os.UserManager; import android.provider.ContactsContract.PhoneLookup; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import android.telephony.Rlog; +import android.telephony.SubscriptionManager; +import android.util.Log; /** * Helper class to make it easier to run asynchronous caller-id lookup queries. @@ -76,6 +80,8 @@ public class CallerInfoAsyncQuery { public Object cookie; public int event; public String number; + + public long subId; } @@ -89,17 +95,52 @@ public class CallerInfoAsyncQuery { } /** + * @return {@link ContentResolver} for the "current" user. + */ + static ContentResolver getCurrentProfileContentResolver(Context context) { + + if (DBG) Rlog.d(LOG_TAG, "Trying to get current content resolver..."); + + final int currentUser = ActivityManager.getCurrentUser(); + final int myUser = UserManager.get(context).getUserHandle(); + + if (DBG) Rlog.d(LOG_TAG, "myUser=" + myUser + "currentUser=" + currentUser); + + if (myUser != currentUser) { + final Context otherContext; + try { + otherContext = context.createPackageContextAsUser(context.getPackageName(), + /* flags =*/ 0, new UserHandle(currentUser)); + return otherContext.getContentResolver(); + } catch (NameNotFoundException e) { + Rlog.e(LOG_TAG, "Can't find self package", e); + // Fall back to the primary user. + } + } + return context.getContentResolver(); + } + + /** * Our own implementation of the AsyncQueryHandler. */ private class CallerInfoAsyncQueryHandler extends AsyncQueryHandler { - /** + /* * The information relevant to each CallerInfo query. Each query may have multiple * listeners, so each AsyncCursorInfo is associated with 2 or more CookieWrapper * objects in the queue (one with a new query event, and one with a end event, with * 0 or more additional listeners in between). */ - private Context mQueryContext; + + /** + * Context passed by the caller. + * + * NOTE: The actual context we use for query may *not* be this context; since we query + * against the "current" contacts provider. In the constructor we pass the "current" + * context resolver (obtained via {@link #getCurrentProfileContentResolver) and pass it + * to the super class. + */ + private Context mContext; private Uri mQueryUri; private CallerInfo mCallerInfo; @@ -178,7 +219,8 @@ public class CallerInfoAsyncQuery { * Asynchronous query handler class for the contact / callerinfo object. */ private CallerInfoAsyncQueryHandler(Context context) { - super(context.getContentResolver()); + super(getCurrentProfileContentResolver(context)); + mContext = context; } @Override @@ -208,17 +250,23 @@ public class CallerInfoAsyncQuery { // However, if there is any code that calls this method, we should // check the parameters to make sure they're viable. if (DBG) Rlog.d(LOG_TAG, "Cookie is null, ignoring onQueryComplete() request."); + if (cursor != null) { + cursor.close(); + } return; } if (cw.event == EVENT_END_OF_QUEUE) { release(); + if (cursor != null) { + cursor.close(); + } return; } // check the token and if needed, create the callerinfo object. if (mCallerInfo == null) { - if ((mQueryContext == null) || (mQueryUri == null)) { + if ((mContext == null) || (mQueryUri == null)) { throw new QueryPoolException ("Bad context or query uri, or CallerInfoAsyncQuery already released."); } @@ -231,15 +279,15 @@ public class CallerInfoAsyncQuery { if (cw.event == EVENT_EMERGENCY_NUMBER) { // Note we're setting the phone number here (refer to javadoc // comments at the top of CallerInfo class). - mCallerInfo = new CallerInfo().markAsEmergency(mQueryContext); + mCallerInfo = new CallerInfo().markAsEmergency(mContext); } else if (cw.event == EVENT_VOICEMAIL_NUMBER) { - mCallerInfo = new CallerInfo().markAsVoiceMail(); + mCallerInfo = new CallerInfo().markAsVoiceMail(cw.subId); } else { - mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor); + mCallerInfo = CallerInfo.getCallerInfo(mContext, mQueryUri, cursor); if (DBG) Rlog.d(LOG_TAG, "==> Got mCallerInfo: " + mCallerInfo); CallerInfo newCallerInfo = CallerInfo.doSecondaryLookupIfNecessary( - mQueryContext, cw.number, mCallerInfo); + mContext, cw.number, mCallerInfo); if (newCallerInfo != mCallerInfo) { mCallerInfo = newCallerInfo; if (DBG) Rlog.d(LOG_TAG, "#####async contact look up with numeric username" @@ -264,7 +312,7 @@ public class CallerInfoAsyncQuery { // the CallerInfo object is totally blank here (i.e. no name // *or* phoneNumber). So we need to pass in cw.number as // a fallback number. - mCallerInfo.updateGeoDescription(mQueryContext, cw.number); + mCallerInfo.updateGeoDescription(mContext, cw.number); } } @@ -272,7 +320,7 @@ public class CallerInfoAsyncQuery { if (!TextUtils.isEmpty(cw.number)) { mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number, mCallerInfo.normalizedNumber, - CallerInfo.getCurrentCountryIso(mQueryContext)); + CallerInfo.getCurrentCountryIso(mContext)); } } @@ -290,6 +338,10 @@ public class CallerInfoAsyncQuery { " for token: " + token + mCallerInfo); cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo); } + + if (cursor != null) { + cursor.close(); + } } } @@ -335,6 +387,25 @@ public class CallerInfoAsyncQuery { */ public static CallerInfoAsyncQuery startQuery(int token, Context context, String number, OnQueryCompleteListener listener, Object cookie) { + + long subId = SubscriptionManager.getDefaultSubId(); + return startQuery(token, context, number, listener, cookie, subId); + } + + /** + * Factory method to start the query based on a number with specific subscription. + * + * Note: if the number contains an "@" character we treat it + * as a SIP address, and look it up directly in the Data table + * rather than using the PhoneLookup table. + * TODO: But eventually we should expose two separate methods, one for + * numbers and one for SIP addresses, and then have + * PhoneUtils.startGetCallerInfo() decide which one to call based on + * the phone type of the incoming connection. + */ + public static CallerInfoAsyncQuery startQuery(int token, Context context, String number, + OnQueryCompleteListener listener, Object cookie, long subId) { + if (DBG) { Rlog.d(LOG_TAG, "##### CallerInfoAsyncQuery startQuery()... #####"); Rlog.d(LOG_TAG, "- number: " + /*number*/ "xxxxxxx"); @@ -343,51 +414,14 @@ public class CallerInfoAsyncQuery { // Construct the URI object and query params, and start the query. - Uri contactRef; - String selection; - String[] selectionArgs; - - if (PhoneNumberUtils.isUriNumber(number)) { - // "number" is really a SIP address. - if (DBG) Rlog.d(LOG_TAG, " - Treating number as a SIP address: " + /*number*/ "xxxxxxx"); - - // We look up SIP addresses directly in the Data table: - contactRef = Data.CONTENT_URI; - - // Note Data.DATA1 and SipAddress.SIP_ADDRESS are equivalent. - // - // Also note we use "upper(data1)" in the WHERE clause, and - // uppercase the incoming SIP address, in order to do a - // case-insensitive match. - // - // TODO: need to confirm that the use of upper() doesn't - // prevent us from using the index! (Linear scan of the whole - // contacts DB can be very slow.) - // - // TODO: May also need to normalize by adding "sip:" as a - // prefix, if we start storing SIP addresses that way in the - // database. - - selection = "upper(" + Data.DATA1 + ")=?" - + " AND " - + Data.MIMETYPE + "='" + SipAddress.CONTENT_ITEM_TYPE + "'"; - selectionArgs = new String[] { number.toUpperCase() }; - - } else { - // "number" is a regular phone number. Use the PhoneLookup table: - contactRef = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); - selection = null; - selectionArgs = null; - } + final Uri contactRef = PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI.buildUpon() + .appendPath(number) + .appendQueryParameter(PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, + String.valueOf(PhoneNumberUtils.isUriNumber(number))) + .build(); if (DBG) { Rlog.d(LOG_TAG, "==> contactRef: " + sanitizeUriToString(contactRef)); - Rlog.d(LOG_TAG, "==> selection: " + selection); - if (selectionArgs != null) { - for (int i = 0; i < selectionArgs.length; i++) { - Rlog.d(LOG_TAG, "==> selectionArgs[" + i + "]: " + selectionArgs[i]); - } - } } CallerInfoAsyncQuery c = new CallerInfoAsyncQuery(); @@ -398,11 +432,12 @@ public class CallerInfoAsyncQuery { cw.listener = listener; cw.cookie = cookie; cw.number = number; + cw.subId = subId; // check to see if these are recognized numbers, and use shortcuts if we can. - if (PhoneNumberUtils.isLocalEmergencyNumber(number, context)) { + if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) { cw.event = EVENT_EMERGENCY_NUMBER; - } else if (PhoneNumberUtils.isVoiceMailNumber(number)) { + } else if (PhoneNumberUtils.isVoiceMailNumber(subId, number)) { cw.event = EVENT_VOICEMAIL_NUMBER; } else { cw.event = EVENT_NEW_QUERY; @@ -412,8 +447,8 @@ public class CallerInfoAsyncQuery { cw, // cookie contactRef, // uri null, // projection - selection, // selection - selectionArgs, // selectionArgs + null, // selection + null, // selectionArgs null); // orderBy return c; } @@ -444,7 +479,6 @@ public class CallerInfoAsyncQuery { throw new QueryPoolException("Bad context or query uri."); } mHandler = new CallerInfoAsyncQueryHandler(context); - mHandler.mQueryContext = context; mHandler.mQueryUri = contactRef; } @@ -452,7 +486,7 @@ public class CallerInfoAsyncQuery { * Releases the relevant data. */ private void release() { - mHandler.mQueryContext = null; + mHandler.mContext = null; mHandler.mQueryUri = null; mHandler.mCallerInfo = null; mHandler = null; diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index 874279b..7eef89a 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -112,7 +112,8 @@ public class DctConstants { public static final int APN_FOTA_ID = 6; public static final int APN_CBS_ID = 7; public static final int APN_IA_ID = 8; - public static final int APN_NUM_TYPES = 9; + public static final int APN_EMERGENCY_ID = 9; + public static final int APN_NUM_TYPES = 10; public static final int DISABLED = 0; public static final int ENABLED = 1; diff --git a/telephony/java/com/android/internal/telephony/ICallService.aidl b/telephony/java/com/android/internal/telephony/ICallService.aidl new file mode 100644 index 0000000..cb9b2e8 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/ICallService.aidl @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +import com.android.internal.telephony.ICallServiceAdapter; + +/** + * Service interface for services which would like to provide calls to be + * managed by the system in-call UI. + * + * This interface provides methods that the android framework can use to deliver commands + * for calls provided by this call service including making new calls and disconnecting + * existing ones. A binding to ICallService implementations exists for two conditions: + * 1) There exists one or more live calls for that call service, + * 2) Prior to an outbound call to test if this call service is compatible with the outgoing call. + */ +oneway interface ICallService { + + /** + * Determines if the CallService can make calls to the handle. + * TODO(santoscordon): Move this method into its own service interface long term. + * TODO(santoscordon): Add response callback parameter. + */ + void isCompatibleWith(String handle); + + /** + * Attempts to call the relevant party using the specified handle, be it a phone number, + * SIP address, or some other kind of user ID. Note that the set of handle types is + * dynamically extensible since call providers should be able to implement arbitrary + * handle-calling systems. See {@link #isCompatibleWith}. + * TODO(santoscordon): Should this have a response attached to it to ensure that the call + * service actually plans to make the call? + */ + void call(String handle); + + /** + * Disconnects the call identified by callId. + */ + void disconnect(String callId); + + /** + * Sets an implementation of ICallServiceAdapter which the call service can use to add new calls + * and communicate state changes of existing calls. This is the first method that is called + * after a the framework binds to the call service. + */ + void setCallServiceAdapter(ICallServiceAdapter callServiceAdapter); +} diff --git a/telephony/java/com/android/internal/telephony/ICallServiceAdapter.aidl b/telephony/java/com/android/internal/telephony/ICallServiceAdapter.aidl new file mode 100644 index 0000000..bc900f0 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/ICallServiceAdapter.aidl @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +import com.android.internal.telephony.CallInfo; + +/** + * Provides methods for ICallService implementations to interact with the system phone app. + */ +oneway interface ICallServiceAdapter { + + /** + * Retrieves a new unique call id for use with newOutgoingCall and newIncomingCall. + */ + void getNextCallId(/* TODO(santoscordon): Needs response object */); + + /** + * Tells CallsManager of a new incoming call. + */ + void newIncomingCall(String callId, in CallInfo info); + + /** + * Tells CallsManager of a new outgoing call. + */ + void newOutgoingCall(String callId, in CallInfo info); + + /** + * Sets a call's state to active (e.g., an ongoing call where two parties can actively + * communicate). + */ + void setActive(String callId); + + /** + * Sets a call's state to ringing (e.g., an inbound ringing call). + */ + void setRinging(String callId); + + /** + * Sets a call's state to dialing (e.g., dialing an outbound call). + */ + void setDialing(String callId); + + /** + * Sets a call's state to disconnected. + */ + void setDisconnected(String callId); +} diff --git a/telephony/java/com/android/internal/telephony/IMms.aidl b/telephony/java/com/android/internal/telephony/IMms.aidl new file mode 100644 index 0000000..651205f --- /dev/null +++ b/telephony/java/com/android/internal/telephony/IMms.aidl @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +import android.app.PendingIntent; +import android.content.ContentValues; +import android.net.Uri; + +/** + * Service interface to handle MMS API requests + */ +interface IMms { + /** + * Send an MMS message + * + * @param subId the SIM id + * @param callingPkg the package name of the calling app + * @param pdu the MMS message encoded in standard MMS PDU format + * @param locationUrl the optional location url for where this message should be sent to + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is successfully sent, or failed + */ + void sendMessage(long subId, String callingPkg, in byte[] pdu, String locationUrl, + in PendingIntent sentIntent); + + /** + * Download an MMS message using known location and transaction id + * + * @param subId the SIM id + * @param callingPkg the package name of the calling app + * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained + * from the MMS WAP push notification + * @param downloadedIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is downloaded, or the download is failed + */ + void downloadMessage(long subId, String callingPkg, String locationUrl, + in PendingIntent downloadedIntent); + + /** + * Update the status of a pending (send-by-IP) MMS message handled by the carrier app. + * If the carrier app fails to send this message, it would be resent via carrier network. + * + * @param messageRef the reference number of the MMS message. + * @param success True if and only if the message was sent successfully. If its value is + * false, this message should be resent via carrier network + */ + void updateMmsSendStatus(int messageRef, boolean success); + + /** + * Update the status of a pending (download-by-IP) MMS message handled by the carrier app. + * If the carrier app fails to download this message, it would be re-downloaded via carrier + * network. + * + * @param messageRef the reference number of the MMS message. + * @param pdu non-empty if downloaded successfully, otherwise, it is empty and the message + * will be downloaded via carrier network + */ + void updateMmsDownloadStatus(int messageRef, in byte[] pdu); + + /** + * Get carrier-dependent configuration value as boolean. For example, if multipart SMS + * is supported. + * + * @param name the configuration name + * @param defaultValue the default value if fail to find the name + */ + boolean getCarrierConfigBoolean(String name, boolean defaultValue); + + /** + * Get carrier-dependent configuration value as int. For example, the MMS message size limit. + * + * @param name the configuration name + * @param defaultValue the default value if fail to find the name + */ + int getCarrierConfigInt(String name, int defaultValue); + + /** + * Get carrier-dependent configuration value as String. For example, extra HTTP headers for + * MMS request. + * + * @param name the configuration name + * @param defaultValue the default value if fail to find the name + */ + String getCarrierConfigString(String name, String defaultValue); + + /** + * Set carrier-dependent configuration value as boolean. For example, if multipart SMS + * is supported. + * + * @param name the configuration name + * @param value the configuration value + */ + void setCarrierConfigBoolean(String callingPkg, String name, boolean value); + + /** + * Set carrier-dependent configuration value as int. For example, the MMS message size limit. + * + * @param name the configuration name + * @param value the configuration value + */ + void setCarrierConfigInt(String callingPkg, String name, int value); + + /** + * Set carrier-dependent configuration value as String. For example, extra HTTP headers for + * MMS request. + * + * @param name the configuration name + * @param value the configuration value + */ + void setCarrierConfigString(String callingPkg, String name, String value); + + /** + * Import a text message into system's SMS store + * + * @param callingPkg the calling app's package name + * @param address the destination address of the message + * @param type the type of the message + * @param text the message text + * @param timestampMillis the message timestamp in milliseconds + * @param seen if the message is seen + * @param read if the message is read + * @return the message URI, null if failed + */ + Uri importTextMessage(String callingPkg, String address, int type, String text, + long timestampMillis, boolean seen, boolean read); + + /** + * Import a multimedia message into system's MMS store + * + * @param callingPkg the package name of the calling app + * @param pdu the PDU of the message to import + * @param messageId the optional message id + * @param timestampSecs the message timestamp in seconds + * @param seen if the message is seen + * @param read if the message is read + * @return the message URI, null if failed + */ + Uri importMultimediaMessage(String callingPkg, in byte[] pdu, String messageId, + long timestampSecs, boolean seen, boolean read); + + /** + * Delete a system stored SMS or MMS message + * + * @param callingPkg the package name of the calling app + * @param messageUri the URI of the stored message + * @return true if deletion is successful, false otherwise + */ + boolean deleteStoredMessage(String callingPkg, in Uri messageUri); + + /** + * Delete a system stored SMS or MMS thread + * + * @param callingPkg the package name of the calling app + * @param conversationId the ID of the message conversation + * @return true if deletion is successful, false otherwise + */ + boolean deleteStoredConversation(String callingPkg, long conversationId); + + /** + * Update the status properties of a system stored SMS or MMS message, e.g. + * the read status of a message, etc. + * + * @param callingPkg the package name of the calling app + * @param messageUri the URI of the stored message + * @param statusValues a list of status properties in key-value pairs to update + * @return true if deletion is successful, false otherwise + */ + boolean updateStoredMessageStatus(String callingPkg, in Uri messageUri, + in ContentValues statusValues); + + /** + * Add a text message draft to system SMS store + * + * @param callingPkg the package name of the calling app + * @param address the destination address of message + * @param text the body of the message to send + * @return the URI of the stored draft message + */ + Uri addTextMessageDraft(String callingPkg, String address, String text); + + /** + * Add a multimedia message draft to system MMS store + * + * @param callingPkg the package name of the calling app + * @param pdu the PDU data of the draft MMS + * @return the URI of the stored draft message + */ + Uri addMultimediaMessageDraft(String callingPkg, in byte[] pdu); + + /** + * Send a system stored MMS message + * + * This is used for sending a previously sent, but failed-to-send, message or + * for sending a text message that has been stored as a draft. + * + * @param subId the SIM id + * @param callingPkg the package name of the calling app + * @param messageUri the URI of the stored message + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is successfully sent, or failed + */ + void sendStoredMessage(long subId, String callingPkg, in Uri messageUri, + in PendingIntent sentIntent); + + /** + * Turns on/off the flag to automatically write sent/received SMS/MMS messages into system + * + * When this flag is on, all SMS/MMS sent/received are stored by system automatically + * When this flag is off, only SMS/MMS sent by non-default SMS apps are stored by system + * automatically + * + * This flag can only be changed by default SMS apps + * + * @param callingPkg the name of the calling app package + * @param enabled Whether to enable message auto persisting + */ + void setAutoPersisting(String callingPkg, boolean enabled); + + /** + * Get the value of the flag to automatically write sent/received SMS/MMS messages into system + * + * When this flag is on, all SMS/MMS sent/received are stored by system automatically + * When this flag is off, only SMS/MMS sent by non-default SMS apps are stored by system + * automatically + * + * @return the current value of the auto persist flag + */ + boolean getAutoPersisting(); +} diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl index f228d4e..a95336e 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -20,8 +20,10 @@ import android.os.Bundle; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.CellInfo; +import android.telephony.DataConnectionRealTimeInfo; import android.telephony.PreciseCallState; import android.telephony.PreciseDataConnectionState; +import android.telephony.VoLteServiceState; oneway interface IPhoneStateListener { void onServiceStateChanged(in ServiceState serviceState); @@ -39,5 +41,7 @@ oneway interface IPhoneStateListener { void onCellInfoChanged(in List<CellInfo> cellInfo); void onPreciseCallStateChanged(in PreciseCallState callState); void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState); + void onDataConnectionRealTimeInfoChanged(in DataConnectionRealTimeInfo dcRtInfo); + void onVoLteServiceStateChanged(in VoLteServiceState lteState); } diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl index 03940dc..4734965 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl @@ -28,6 +28,13 @@ interface IPhoneSubInfo { String getDeviceId(); /** + * Retrieves the unique device ID of a subId for the device, e.g., IMEI + * for GSM phones. + */ + String getDeviceIdUsingSubId(long subId); + + + /** * Retrieves the software version number for the device, e.g., IMEI/SV * for GSM phones. */ @@ -39,46 +46,94 @@ interface IPhoneSubInfo { String getSubscriberId(); /** + * Retrieves the unique subscriber ID of a given subId, e.g., IMSI for GSM phones. + */ + String getSubscriberIdUsingSubId(long subId); + + /** * Retrieves the Group Identifier Level1 for GSM phones. */ String getGroupIdLevel1(); /** + * Retrieves the Group Identifier Level1 for GSM phones of a subId. + */ + String getGroupIdLevel1UsingSubId(long subId); + + /** * Retrieves the serial number of the ICC, if applicable. */ String getIccSerialNumber(); /** + * Retrieves the serial number of a given subId. + */ + String getIccSerialNumberUsingSubId(long subId); + + /** * Retrieves the phone number string for line 1. */ String getLine1Number(); /** + * Retrieves the phone number string for line 1 of a subcription. + */ + String getLine1NumberUsingSubId(long subId); + + + /** * Retrieves the alpha identifier for line 1. */ String getLine1AlphaTag(); /** + * Retrieves the alpha identifier for line 1 of a subId. + */ + String getLine1AlphaTagUsingSubId(long subId); + + + /** * Retrieves MSISDN Number. */ String getMsisdn(); /** + * Retrieves the Msisdn of a subId. + */ + String getMsisdnUsingSubId(long subId); + + /** * Retrieves the voice mail number. */ String getVoiceMailNumber(); /** + * Retrieves the voice mail number of a given subId. + */ + String getVoiceMailNumberUsingSubId(long subId); + + /** * Retrieves the complete voice mail number. */ String getCompleteVoiceMailNumber(); /** + * Retrieves the complete voice mail number for particular subId + */ + String getCompleteVoiceMailNumberUsingSubId(long subId); + + /** * Retrieves the alpha identifier associated with the voice mail number. */ String getVoiceMailAlphaTag(); /** + * Retrieves the alpha identifier associated with the voice mail number + * of a subId. + */ + String getVoiceMailAlphaTagUsingSubId(long subId); + + /** * Returns the IMS private user identity (IMPI) that was loaded from the ISIM. * @return the IMPI, or null if not present or not loaded */ @@ -96,4 +151,38 @@ interface IPhoneSubInfo { * not present or not loaded */ String[] getIsimImpu(); + + /** + * Returns the IMS Service Table (IST) that was loaded from the ISIM. + * @return IMS Service Table or null if not present or not loaded + */ + String getIsimIst(); + + /** + * Returns the IMS Proxy Call Session Control Function(PCSCF) that were loaded from the ISIM. + * @return an array of PCSCF strings with one PCSCF per string, or null if + * not present or not loaded + */ + String[] getIsimPcscf(); + + /** + * TODO: Deprecate and remove this interface. Superceded by getIccsimChallengeResponse. + * Returns the response of ISIM Authetification through RIL. + * @return the response of ISIM Authetification, or null if + * the Authentification hasn't been successed or isn't present iphonesubinfo. + */ + String getIsimChallengeResponse(String nonce); + + /** + * Returns the response of the SIM application on the UICC to authentication + * challenge/response algorithm. The data string and challenge response are + * Base64 encoded Strings. + * Can support EAP-SIM, EAP-AKA with results encoded per 3GPP TS 31.102. + * + * @param subId subscription ID to be queried + * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx) + * @param data authentication challenge data + * @return challenge response + */ + String getIccSimChallengeResponse(long subId, int appType, String data); } diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl index 3e8db06..abbdc4a 100644 --- a/telephony/java/com/android/internal/telephony/ISms.aidl +++ b/telephony/java/com/android/internal/telephony/ISms.aidl @@ -17,6 +17,7 @@ package com.android.internal.telephony; import android.app.PendingIntent; +import android.net.Uri; import com.android.internal.telephony.SmsRawData; /** Interface for applications to access the ICC phone book. @@ -42,6 +43,13 @@ interface ISms { List<SmsRawData> getAllMessagesFromIccEf(String callingPkg); /** + * Retrieves all messages currently stored on ICC. + * @param subId the subId id. + * @return list of SmsRawData of all sms on ICC + */ + List<SmsRawData> getAllMessagesFromIccEfUsingSubId(in long subId, String callingPkg); + + /** * Update the specified message on the ICC. * * @param messageIndex record index of message to update @@ -56,6 +64,21 @@ interface ISms { in byte[] pdu); /** + * Update the specified message on the ICC. + * + * @param messageIndex record index of message to update + * @param newStatus new message status (STATUS_ON_ICC_READ, + * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT, + * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE) + * @param pdu the raw PDU to store + * @param subId the subId id. + * @return success or not + * + */ + boolean updateMessageOnIccEfUsingSubId(in long subId, String callingPkg, + int messageIndex, int newStatus, in byte[] pdu); + + /** * Copy a raw SMS PDU to the ICC. * * @param pdu the raw PDU to store @@ -67,6 +90,19 @@ interface ISms { boolean copyMessageToIccEf(String callingPkg, int status, in byte[] pdu, in byte[] smsc); /** + * Copy a raw SMS PDU to the ICC. + * + * @param pdu the raw PDU to store + * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD, + * STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT) + * @param subId the subId id. + * @return success or not + * + */ + boolean copyMessageToIccEfUsingSubId(in long subId, String callingPkg, int status, + in byte[] pdu, in byte[] smsc); + + /** * Send a data SMS. * * @param smsc the SMSC to send the message through, or NULL for the @@ -93,6 +129,34 @@ interface ISms { in byte[] data, in PendingIntent sentIntent, in PendingIntent deliveryIntent); /** + * Send a data SMS. + * + * @param smsc the SMSC to send the message through, or NULL for the + * default SMSC + * @param data the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is sucessfully sent, or failed. + * The result code will be <code>Activity.RESULT_OK<code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applicaitons, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is delivered to the recipient. The + * raw pdu of the status report is in the extended data ("pdu"). + * @param subId the subId id. + */ + void sendDataUsingSubId(long subId, String callingPkg, in String destAddr, + in String scAddr, in int destPort, in byte[] data, in PendingIntent sentIntent, + in PendingIntent deliveryIntent); + + /** * Send an SMS. * * @param smsc the SMSC to send the message through, or NULL for the @@ -119,6 +183,58 @@ interface ISms { in PendingIntent sentIntent, in PendingIntent deliveryIntent); /** + * Send an SMS. + * + * @param smsc the SMSC to send the message through, or NULL for the + * default SMSC + * @param text the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is sucessfully sent, or failed. + * The result code will be <code>Activity.RESULT_OK<code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applications, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is delivered to the recipient. The + * raw pdu of the status report is in the extended data ("pdu"). + * @param subId the subId on which the SMS has to be sent. + */ + void sendTextUsingSubId(in long subId, String callingPkg, in String destAddr, + in String scAddr, in String text, in PendingIntent sentIntent, + in PendingIntent deliveryIntent); + + /** + * Inject an SMS PDU into the android platform. + * + * @param pdu is the byte array of pdu to be injected into android application framework + * @param format is the format of SMS pdu (android.telephony.SmsMessage.FORMAT_3GPP or + * android.telephony.SmsMessage.FORMAT_3GPP2) + * @param receivedIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is successfully received by the + * android application framework. This intent is broadcasted at + * the same time an SMS received from radio is acknowledged back. + */ + void injectSmsPdu(in byte[] pdu, String format, in PendingIntent receivedIntent); + + /** + * Update the status of a pending (send-by-IP) SMS message and resend by PSTN if necessary. + * This outbound message was handled by the carrier app. If the carrier app fails to send + * this message, it would be resent by PSTN. + * + * @param messageRef the reference number of the SMS message. + * @param success True if and only if the message was sent successfully. If its value is + * false, this message should be resent via PSTN. + */ + void updateSmsSendStatus(int messageRef, boolean success); + + /** * Send a multi-part text based SMS. * * @param destinationAddress the address to send the message to @@ -145,6 +261,34 @@ interface ISms { in List<PendingIntent> deliveryIntents); /** + * Send a multi-part text based SMS. + * + * @param destinationAddress the address to send the message to + * @param scAddress is the service center address or null to use + * the current default SMSC + * @param parts an <code>ArrayList</code> of strings that, in order, + * comprise the original message + * @param sentIntents if not null, an <code>ArrayList</code> of + * <code>PendingIntent</code>s (one for each message part) that is + * broadcast when the corresponding message part has been sent. + * The result code will be <code>Activity.RESULT_OK<code> for success, + * or one of these errors: + * <code>RESULT_ERROR_GENERIC_FAILURE</code> + * <code>RESULT_ERROR_RADIO_OFF</code> + * <code>RESULT_ERROR_NULL_PDU</code>. + * @param deliveryIntents if not null, an <code>ArrayList</code> of + * <code>PendingIntent</code>s (one for each message part) that is + * broadcast when the corresponding message part has been delivered + * to the recipient. The raw pdu of the status report is in the + * extended data ("pdu"). + * @param subId the subId on which the SMS has to be sent. + */ + void sendMultipartTextUsingSubId(in long subId, String callingPkg, + in String destinationAddress, in String scAddress, + in List<String> parts, in List<PendingIntent> sentIntents, + in List<PendingIntent> deliveryIntents); + + /** * Enable reception of cell broadcast (SMS-CB) messages with the given * message identifier. Note that if two different clients enable the same * message identifier, they must both disable it for the device to stop @@ -159,6 +303,21 @@ interface ISms { boolean enableCellBroadcast(int messageIdentifier); /** + * Enable reception of cell broadcast (SMS-CB) messages with the given + * message identifier. Note that if two different clients enable the same + * message identifier, they must both disable it for the device to stop + * receiving those messages. + * + * @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) or + * C.R1001-G (3GPP2) + * @param subId for which the broadcast has to be enabled + * @return true if successful, false otherwise + * + * @see #disableCellBroadcast(int) + */ + boolean enableCellBroadcastUsingSubId(in long subId, int messageIdentifier); + + /** * Disable reception of cell broadcast (SMS-CB) messages with the given * message identifier. Note that if two different clients enable the same * message identifier, they must both disable it for the device to stop @@ -172,6 +331,21 @@ interface ISms { */ boolean disableCellBroadcast(int messageIdentifier); + /** + * Disable reception of cell broadcast (SMS-CB) messages with the given + * message identifier. Note that if two different clients enable the same + * message identifier, they must both disable it for the device to stop + * receiving those messages. + * + * @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) or + * C.R1001-G (3GPP2) + * @param subId for which the broadcast has to be disabled + * @return true if successful, false otherwise + * + * @see #enableCellBroadcast(int) + */ + boolean disableCellBroadcastUsingSubId(in long subId, int messageIdentifier); + /* * Enable reception of cell broadcast (SMS-CB) messages with the given * message identifier range. Note that if two different clients enable @@ -188,6 +362,23 @@ interface ISms { */ boolean enableCellBroadcastRange(int startMessageId, int endMessageId); + /* + * Enable reception of cell broadcast (SMS-CB) messages with the given + * message identifier range. Note that if two different clients enable + * a message identifier range, they must both disable it for the device + * to stop receiving those messages. + * + * @param startMessageId first message identifier as specified in TS 23.041 (3GPP) or + * C.R1001-G (3GPP2) + * @param endMessageId last message identifier as specified in TS 23.041 (3GPP) or + * C.R1001-G (3GPP2) + * @param subId for which the broadcast has to be enabled + * @return true if successful, false otherwise + * + * @see #disableCellBroadcastRange(int, int) + */ + boolean enableCellBroadcastRangeUsingSubId(long subId, int startMessageId, int endMessageId); + /** * Disable reception of cell broadcast (SMS-CB) messages with the given * message identifier range. Note that if two different clients enable @@ -205,18 +396,52 @@ interface ISms { boolean disableCellBroadcastRange(int startMessageId, int endMessageId); /** + * Disable reception of cell broadcast (SMS-CB) messages with the given + * message identifier range. Note that if two different clients enable + * a message identifier range, they must both disable it for the device + * to stop receiving those messages. + * + * @param startMessageId first message identifier as specified in TS 23.041 (3GPP) or + * C.R1001-G (3GPP2) + * @param endMessageId last message identifier as specified in TS 23.041 (3GPP) or + * C.R1001-G (3GPP2) + * @param subId for which the broadcast has to be disabled + * @return true if successful, false otherwise + * + * @see #enableCellBroadcastRange(int, int, int) + */ + boolean disableCellBroadcastRangeUsingSubId(long subId, int startMessageId, + int endMessageId); + + /** * Returns the premium SMS send permission for the specified package. * Requires system permission. */ int getPremiumSmsPermission(String packageName); /** + * Returns the premium SMS send permission for the specified package. + * Requires system permission. + */ + int getPremiumSmsPermissionUsingSubId(long subId, String packageName); + + /** * Set the SMS send permission for the specified package. * Requires system permission. */ void setPremiumSmsPermission(String packageName, int permission); /** + * Set the SMS send permission for the specified package. + * Requires system permission. + */ + /** + * Set the SMS send permission for the specified package. + * Requires system permission. + */ + void setPremiumSmsPermissionUsingSubId(long subId, String packageName, int permission); + + /** * SMS over IMS is supported if IMS is registered and SMS is supported * on IMS. * @@ -227,6 +452,22 @@ interface ISms { boolean isImsSmsSupported(); /** + * SMS over IMS is supported if IMS is registered and SMS is supported + * on IMS. + * @param subId for subId which isImsSmsSupported is queried + * @return true if SMS over IMS is supported, false otherwise + * + * @see #getImsSmsFormat() + */ + boolean isImsSmsSupportedUsingSubId(long subId); + + /* + * get user prefered SMS subId + * @return subId id + */ + long getPreferredSmsSubscription(); + + /** * Gets SMS format supported on IMS. SMS over IMS format is * either 3GPP or 3GPP2. * @@ -237,4 +478,89 @@ interface ISms { * @see #isImsSmsSupported() */ String getImsSmsFormat(); + + /** + * Gets SMS format supported on IMS. SMS over IMS format is + * either 3GPP or 3GPP2. + * @param subId for subId which getImsSmsFormat is queried + * @return android.telephony.SmsMessage.FORMAT_3GPP, + * android.telephony.SmsMessage.FORMAT_3GPP2 + * or android.telephony.SmsMessage.FORMAT_UNKNOWN + * + * @see #isImsSmsSupported() + */ + String getImsSmsFormatUsingSubId(long subId); + + /* + * Get SMS prompt property, enabled or not + * @return true if enabled, false otherwise + */ + boolean isSMSPromptEnabled(); + + /** + * Send a system stored text message. + * + * This is used for sending a previously sent, but failed-to-send, message or + * for sending a text message that has been stored as a draft. + * + * @param subId the SIM id. + * @param callingPkg the package name of the calling app + * @param messageUri the URI of the stored message + * @param scAddress is the service center address or null to use the current default SMSC + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is successfully sent, or failed. + * The result code will be <code>Activity.RESULT_OK</code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applications, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is delivered to the recipient. The + * raw pdu of the status report is in the extended data ("pdu"). + */ + void sendStoredText(long subId, String callingPkg, in Uri messageUri, String scAddress, + in PendingIntent sentIntent, in PendingIntent deliveryIntent); + + /** + * Send a system stored multi-part text message. + * + * This is used for sending a previously sent, but failed-to-send, message or + * for sending a text message that has been stored as a draft. + * The provided <code>PendingIntent</code> lists should match the part number of the + * divided text of the stored message by using <code>divideMessage</code> + * + * @param subId the SIM id. + * @param callingPkg the package name of the calling app + * @param messageUri the URI of the stored message + * @param scAddress is the service center address or null to use + * the current default SMSC + * @param sentIntents if not null, an <code>ArrayList</code> of + * <code>PendingIntent</code>s (one for each message part) that is + * broadcast when the corresponding message part has been sent. + * The result code will be <code>Activity.RESULT_OK</code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> each sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applications, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntents if not null, an <code>ArrayList</code> of + * <code>PendingIntent</code>s (one for each message part) that is + * broadcast when the corresponding message part has been delivered + * to the recipient. The raw pdu of the status report is in the + * extended data ("pdu"). + */ + void sendStoredMultipartText(long subId, String callingPkg, in Uri messageUri, + String scAddress, in List<PendingIntent> sentIntents, + in List<PendingIntent> deliveryIntents); } diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl new file mode 100755 index 0000000..6021ccf --- /dev/null +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -0,0 +1,153 @@ +/* +* Copyright (C) 2011-2014 MediaTek Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.android.internal.telephony; + +import android.app.PendingIntent; +import android.telephony.SubInfoRecord; + +interface ISub { + /** + * Get the SubInfoRecord according to an index + * @param context Context provided by caller + * @param subId The unique SubInfoRecord index in database + * @return SubInfoRecord, maybe null + */ + SubInfoRecord getSubInfoUsingSubId(long subId); + + /** + * Get the SubInfoRecord according to an IccId + * @param context Context provided by caller + * @param iccId the IccId of SIM card + * @return SubInfoRecord, maybe null + */ + List<SubInfoRecord> getSubInfoUsingIccId(String iccId); + + /** + * Get the SubInfoRecord according to slotId + * @param context Context provided by caller + * @param slotId the slot which the SIM is inserted + * @return SubInfoRecord, maybe null + */ + List<SubInfoRecord> getSubInfoUsingSlotId(int slotId); + + /** + * Get all the SubInfoRecord(s) in subinfo database + * @param context Context provided by caller + * @return Array list of all SubInfoRecords in database, include thsoe that were inserted before + */ + List<SubInfoRecord> getAllSubInfoList(); + + /** + * Get the SubInfoRecord(s) of the currently inserted SIM(s) + * @param context Context provided by caller + * @return Array list of currently inserted SubInfoRecord(s) + */ + List<SubInfoRecord> getActivatedSubInfoList(); + + /** + * Get the SUB count of all SUB(s) in subinfo database + * @param context Context provided by caller + * @return all SIM count in database, include what was inserted before + */ + int getAllSubInfoCount(); + + /** + * Add a new SubInfoRecord to subinfo database if needed + * @param context Context provided by caller + * @param iccId the IccId of the SIM card + * @param slotId the slot which the SIM is inserted + * @return the URL of the newly created row or the updated row + */ + int addSubInfoRecord(String iccId, int slotId); + + /** + * Set SIM color by simInfo index + * @param context Context provided by caller + * @param color the color of the SIM + * @param subId the unique SubInfoRecord index in database + * @return the number of records updated + */ + int setColor(int color, long subId); + + /** + * Set display name by simInfo index + * @param context Context provided by caller + * @param displayName the display name of SIM card + * @param subId the unique SubInfoRecord index in database + * @return the number of records updated + */ + int setDisplayName(String displayName, long subId); + + /** + * Set display name by simInfo index with name source + * @param context Context provided by caller + * @param displayName the display name of SIM card + * @param subId the unique SubInfoRecord index in database + * @param nameSource, 0: DEFAULT_SOURCE, 1: SIM_SOURCE, 2: USER_INPUT + * @return the number of records updated + */ + int setDisplayNameUsingSrc(String displayName, long subId, long nameSource); + + /** + * Set phone number by subId + * @param context Context provided by caller + * @param number the phone number of the SIM + * @param subId the unique SubInfoRecord index in database + * @return the number of records updated + */ + int setDispalyNumber(String number, long subId); + + /** + * Set number display format. 0: none, 1: the first four digits, 2: the last four digits + * @param context Context provided by caller + * @param format the display format of phone number + * @param subId the unique SubInfoRecord index in database + * @return the number of records updated + */ + int setDisplayNumberFormat(int format, long subId); + + /** + * Set data roaming by simInfo index + * @param context Context provided by caller + * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming + * @param subId the unique SubInfoRecord index in database + * @return the number of records updated + */ + int setDataRoaming(int roaming, long subId); + + int getSlotId(long subId); + + long[] getSubId(int slotId); + + long getDefaultSubId(); + + int clearSubInfo(); + + int getPhoneId(long subId); + + /** + * Get the default data subscription + * @return Id of the data subscription + */ + long getDefaultDataSubId(); + + void setDefaultDataSubId(long subId); + + long getDefaultVoiceSubId(); + + void setDefaultVoiceSubId(long subId); +} diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 9c73059..886de40 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -16,13 +16,12 @@ package com.android.internal.telephony; +import android.content.Intent; import android.os.Bundle; -import android.telephony.CellInfo; +import java.util.List; import android.telephony.NeighboringCellInfo; +import android.telephony.CellInfo; -import com.android.internal.telephony.ITelephonyListener; - -import java.util.List; /** * Interface used to interact with the phone. Mostly this is used by the @@ -48,33 +47,18 @@ interface ITelephony { void call(String callingPackage, String number); /** - * If there is currently a call in progress, show the call screen. - * The DTMF dialpad may or may not be visible initially, depending on - * whether it was up when the user last exited the InCallScreen. - * - * @return true if the call screen was shown. - */ - boolean showCallScreen(); - - /** - * Variation of showCallScreen() that also specifies whether the - * DTMF dialpad should be initially visible when the InCallScreen - * comes up. - * - * @param showDialpad if true, make the dialpad visible initially, - * otherwise hide the dialpad initially. - * @return true if the call screen was shown. + * End call if there is a call in progress, otherwise does nothing. * - * @see showCallScreen + * @return whether it hung up */ - boolean showCallScreenWithDialpad(boolean showDialpad); + boolean endCall(); /** - * End call if there is a call in progress, otherwise does nothing. - * + * End call on particular subId or go to the Home screen + * @param subId user preferred subId. * @return whether it hung up */ - boolean endCall(); + boolean endCallUsingSubId(long subId); /** * Answer the currently-ringing call. @@ -113,6 +97,23 @@ interface ITelephony { boolean isOffhook(); /** + * Check if a particular subId has an active or holding call + * + * @param subId user preferred subId. + * @return true if the phone state is OFFHOOK. + */ + boolean isOffhookUsingSubId(long subId); + + /** + * Check if an incoming phone call is ringing or call waiting + * on a particular subId. + * + * @param subId user preferred subId. + * @return true if the phone state is RINGING. + */ + boolean isRingingUsingSubId(long subId); + + /** * Check if an incoming phone call is ringing or call waiting. * @return true if the phone state is RINGING. */ @@ -125,28 +126,47 @@ interface ITelephony { boolean isIdle(); /** + * Check if the phone is idle on a particular subId. + * + * @param subId user preferred subId. + * @return true if the phone state is IDLE. + */ + boolean isIdleUsingSubId(long subId); + + /** * Check to see if the radio is on or not. * @return returns true if the radio is on. */ boolean isRadioOn(); /** + * Check to see if the radio is on or not on particular subId. + * @param subId user preferred subId. + * @return returns true if the radio is on. + */ + boolean isRadioOnUsingSubId(long subId); + + /** * Check if the SIM pin lock is enabled. * @return true if the SIM pin lock is enabled. */ boolean isSimPinEnabled(); /** - * Cancels the missed calls notification. + * Supply a pin to unlock the SIM. Blocks until a result is determined. + * @param pin The pin to check. + * @return whether the operation was a success. */ - void cancelMissedCallsNotification(); + boolean supplyPin(String pin); /** - * Supply a pin to unlock the SIM. Blocks until a result is determined. + * Supply a pin to unlock the SIM for particular subId. + * Blocks until a result is determined. * @param pin The pin to check. + * @param subId user preferred subId. * @return whether the operation was a success. */ - boolean supplyPin(String pin); + boolean supplyPinUsingSubId(long subId, String pin); /** * Supply puk to unlock the SIM and set SIM pin to new pin. @@ -158,6 +178,16 @@ interface ITelephony { boolean supplyPuk(String puk, String pin); /** + * Supply puk to unlock the SIM and set SIM pin to new pin. + * Blocks until a result is determined. + * @param puk The puk to check. + * pin The new pin to be set in SIM + * @param subId user preferred subId. + * @return whether the operation was a success. + */ + boolean supplyPukUsingSubId(long subId, String puk, String pin); + + /** * Supply a pin to unlock the SIM. Blocks until a result is determined. * Returns a specific success/error code. * @param pin The pin to check. @@ -167,6 +197,15 @@ interface ITelephony { int[] supplyPinReportResult(String pin); /** + * Supply a pin to unlock the SIM. Blocks until a result is determined. + * Returns a specific success/error code. + * @param pin The pin to check. + * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code + * retValue[1] = number of attempts remaining if known otherwise -1 + */ + int[] supplyPinReportResultUsingSubId(long subId, String pin); + + /** * Supply puk to unlock the SIM and set SIM pin to new pin. * Blocks until a result is determined. * Returns a specific success/error code @@ -178,6 +217,17 @@ interface ITelephony { int[] supplyPukReportResult(String puk, String pin); /** + * Supply puk to unlock the SIM and set SIM pin to new pin. + * Blocks until a result is determined. + * Returns a specific success/error code + * @param puk The puk to check + * pin The pin to check. + * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code + * retValue[1] = number of attempts remaining if known otherwise -1 + */ + int[] supplyPukReportResultUsingSubId(long subId, String puk, String pin); + + /** * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated * without SEND (so <code>dial</code> is not appropriate). * @@ -187,16 +237,38 @@ interface ITelephony { boolean handlePinMmi(String dialString); /** + * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated + * without SEND (so <code>dial</code> is not appropriate) for + * a particular subId. + * @param dialString the MMI command to be executed. + * @param subId user preferred subId. + * @return true if MMI command is executed. + */ + boolean handlePinMmiUsingSubId(long subId, String dialString); + + /** * Toggles the radio on or off. */ void toggleRadioOnOff(); /** + * Toggles the radio on or off on particular subId. + * @param subId user preferred subId. + */ + void toggleRadioOnOffUsingSubId(long subId); + + /** * Set the radio to on or off */ boolean setRadio(boolean turnOn); /** + * Set the radio to on or off on particular subId. + * @param subId user preferred subId. + */ + boolean setRadioUsingSubId(long subId, boolean turnOn); + + /** * Set the radio to on or off unconditionally */ boolean setRadioPower(boolean turnOn); @@ -207,24 +279,32 @@ interface ITelephony { void updateServiceLocation(); /** + * Request to update location information for a subscrition in service state + * @param subId user preferred subId. + */ + void updateServiceLocationUsingSubId(long subId); + + /** * Enable location update notifications. */ void enableLocationUpdates(); /** - * Disable location update notifications. + * Enable location update notifications. + * @param subId user preferred subId. */ - void disableLocationUpdates(); + void enableLocationUpdatesUsingSubId(long subId); /** - * Enable a specific APN type. + * Disable location update notifications. */ - int enableApnType(String type); + void disableLocationUpdates(); /** - * Disable a specific APN type. + * Disable location update notifications. + * @param subId user preferred subId. */ - int disableApnType(String type); + void disableLocationUpdatesUsingSubId(long subId); /** * Allow mobile data connections. @@ -249,6 +329,12 @@ interface ITelephony { List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg); int getCallState(); + + /** + * Returns the call state for a subId. + */ + int getCallStateUsingSubId(long subId); + int getDataActivity(); int getDataState(); @@ -260,11 +346,25 @@ interface ITelephony { int getActivePhoneType(); /** + * Returns the current active phone type as integer for particular subId. + * Returns TelephonyManager.PHONE_TYPE_CDMA if RILConstants.CDMA_PHONE + * and TelephonyManager.PHONE_TYPE_GSM if RILConstants.GSM_PHONE + * @param subId user preferred subId. + */ + int getActivePhoneTypeUsingSubId(long subId); + + /** * Returns the CDMA ERI icon index to display */ int getCdmaEriIconIndex(); /** + * Returns the CDMA ERI icon index to display on particular subId. + * @param subId user preferred subId. + */ + int getCdmaEriIconIndexUsingSubId(long subId); + + /** * Returns the CDMA ERI icon mode, * 0 - ON * 1 - FLASHING @@ -272,11 +372,25 @@ interface ITelephony { int getCdmaEriIconMode(); /** + * Returns the CDMA ERI icon mode on particular subId, + * 0 - ON + * 1 - FLASHING + * @param subId user preferred subId. + */ + int getCdmaEriIconModeUsingSubId(long subId); + + /** * Returns the CDMA ERI text, */ String getCdmaEriText(); /** + * Returns the CDMA ERI text for particular subId, + * @param subId user preferred subId. + */ + String getCdmaEriTextUsingSubId(long subId); + + /** * Returns true if OTA service provisioning needs to run. * Only relevant on some technologies, others will always * return false. @@ -289,26 +403,61 @@ interface ITelephony { int getVoiceMessageCount(); /** + * Returns the unread count of voicemails for a subId. + * @param subId user preferred subId. + * Returns the unread count of voicemails + */ + int getVoiceMessageCountUsingSubId(long subId); + + /** * Returns the network type for data transmission */ int getNetworkType(); /** + * Returns the network type of a subId. + * @param subId user preferred subId. + * Returns the network type + */ + int getNetworkTypeUsingSubId(long subId); + + /** * Returns the network type for data transmission */ int getDataNetworkType(); /** + * Returns the data network type of a subId + * @param subId user preferred subId. + * Returns the network type + */ + int getDataNetworkTypeUsingSubId(long subId); + + /** * Returns the network type for voice */ int getVoiceNetworkType(); /** + * Returns the voice network type of a subId + * @param subId user preferred subId. + * Returns the network type + */ + int getVoiceNetworkTypeUsingSubId(long subId); + + /** * Return true if an ICC card is present */ boolean hasIccCard(); /** + * Return true if an ICC card is present for a subId. + * @param slotId user preferred slotId. + * Return true if an ICC card is present + */ + boolean hasIccCardUsingSlotId(long slotId); + + /** * Return if the current radio is LTE on CDMA. This * is a tri-state return value as for a period of time * the mode may be unknown. @@ -319,6 +468,16 @@ interface ITelephony { int getLteOnCdmaMode(); /** + * Return if the current radio is LTE on CDMA. This + * is a tri-state return value as for a period of time + * the mode may be unknown. + * + * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} + * or {@link PHone#LTE_ON_CDMA_TRUE} + */ + int getLteOnCdmaModeUsingSubId(long subId); + + /** * Returns the all observed cell information of the device. */ List<CellInfo> getAllCellInfo(); @@ -329,46 +488,265 @@ interface ITelephony { void setCellInfoListRate(int rateInMillis); /** - * Put a call on hold. + * get default sim + * @return sim id */ - void toggleHold(); + int getDefaultSim(); - /** - * Merge foreground and background calls. - */ - void merge(); + /** + * Opens a logical channel to the ICC card. + * + * Input parameters equivalent to TS 27.007 AT+CCHO command. + * + * @param AID Application id. See ETSI 102.221 and 101.220. + * @return The logical channel id which is set to -1 on error. + */ + int iccOpenLogicalChannel(String AID); - /** - * Swap foreground and background calls. - */ - void swap(); + /** + * Closes a previously opened logical channel to the ICC card. + * + * Input parameters equivalent to TS 27.007 AT+CCHC command. + * + * @param channel is the channel id to be closed as retruned by a + * successful iccOpenLogicalChannel. + * @return true if the channel was closed successfully. + */ + boolean iccCloseLogicalChannel(int channel); - /** - * Mute the phone. - */ - void mute(boolean mute); + /** + * Transmit an APDU to the ICC card over a logical channel. + * + * Input parameters equivalent to TS 27.007 AT+CGLA command. + * + * @param channel is the channel id to be closed as retruned by a + * successful iccOpenLogicalChannel. + * @param cla Class of the APDU command. + * @param instruction Instruction of the APDU command. + * @param p1 P1 value of the APDU command. + * @param p2 P2 value of the APDU command. + * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU + * is sent to the SIM. + * @param data Data to be sent with the APDU. + * @return The APDU response from the ICC card with the status appended at + * the end. If an error occurs, an empty string is returned. + */ + String iccTransmitApduLogicalChannel(int channel, int cla, int instruction, + int p1, int p2, int p3, String data); + + /** + * Send ENVELOPE to the SIM and returns the response. + * + * @param contents String containing SAT/USAT response in hexadecimal + * format starting with command tag. See TS 102 223 for + * details. + * @return The APDU response from the ICC card, with the last 4 bytes + * being the status word. If the command fails, returns an empty + * string. + */ + String sendEnvelopeWithStatus(String content); /** - * Start playing DTMF tone for the specified digit. + * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}. + * Used for device configuration by some CDMA operators. * - * @param digit the digit that corresponds with the desired tone. - * @param timedShortcode whether the specified digit should be played as a timed short code. + * @param itemID the ID of the item to read. + * @return the NV item as a String, or null on any failure. */ - void playDtmfTone(char digit, boolean timedShortCode); + String nvReadItem(int itemID); - /** - * Stop playing DTMF tones. - */ - void stopDtmfTone(); + /** + * Write one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}. + * Used for device configuration by some CDMA operators. + * + * @param itemID the ID of the item to read. + * @param itemValue the value to write, as a String. + * @return true on success; false on any failure. + */ + boolean nvWriteItem(int itemID, String itemValue); - /** - * Register a callback. - */ - void addListener(ITelephonyListener listener); + /** + * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. + * Used for device configuration by some CDMA operators. + * + * @param preferredRoamingList byte array containing the new PRL. + * @return true on success; false on any failure. + */ + boolean nvWriteCdmaPrl(in byte[] preferredRoamingList); - /** - * Unregister a callback. - */ - void removeListener(ITelephonyListener listener); + /** + * Perform the specified type of NV config reset. The radio will be taken offline + * and the device must be rebooted after the operation. Used for device + * configuration by some CDMA operators. + * + * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset). + * @return true on success; false on any failure. + */ + boolean nvResetConfig(int resetType); + + /* + * Get the calculated preferred network type. + * Used for device configuration by some CDMA operators. + * + * @return the calculated preferred network type, defined in RILConstants.java. + */ + int getCalculatedPreferredNetworkType(); + + /* + * Get the preferred network type. + * Used for device configuration by some CDMA operators. + * + * @return the preferred network type, defined in RILConstants.java. + */ + int getPreferredNetworkType(); + + /** + * Set the preferred network type. + * Used for device configuration by some CDMA operators. + * + * @param networkType the preferred network type, defined in RILConstants.java. + * @return true on success; false on any failure. + */ + boolean setPreferredNetworkType(int networkType); + + /** + * Set the CDMA subscription source. + * Used for device supporting both NV and RUIM for CDMA. + * + * @param subscriptionType the subscription type, 0 for RUIM, 1 for NV. + * @return true on success; false on any failure. + */ + boolean setCdmaSubscription(int subscriptionType); + + /** + * User enable/disable Mobile Data. + * + * @param enable true to turn on, else false + */ + void setDataEnabled(boolean enable); + + /** + * Get the user enabled state of Mobile Data. + * + * @return true on enabled + */ + boolean getDataEnabled(); + + /** + * Get P-CSCF address from PCO after data connection is established or modified. + * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN + */ + String[] getPcscfAddress(String apnType); + + /** + * Set IMS registration state + */ + void setImsRegistrationState(boolean registered); + + /** + * Has the calling application been granted special privileges by the carrier. + * + * If any of the packages in the calling UID has carrier privileges, the + * call will return true. This access is granted by the owner of the UICC + * card and does not depend on the registered carrier. + * + * TODO: Add a link to documentation. + * + * @return carrier privilege status defined in TelephonyManager. + */ + int hasCarrierPrivileges(); + + /** + * Similar to above, but check for pkg whose name is pkgname. + */ + int checkCarrierPrivilegesForPackage(String pkgname); + + /** + * Returns the package name of the carrier apps that should handle the input intent. + * + * @param packageManager PackageManager for getting receivers. + * @param intent Intent that will be broadcast. + * @return list of carrier app package names that can handle the intent. + * Returns null if there is an error and an empty list if there + * are no matching packages. + */ + List<String> getCarrierPackageNamesForBroadcastIntent(in Intent intent); + + /** + * Set whether Android should display a simplified Mobile Network Settings UI. + * The setting won't be persisted during power cycle. + * + * @param subId for which the simplified UI should be enabled or disabled. + * @param enable true means enabling the simplified UI. + */ + void enableSimplifiedNetworkSettings(long subId, boolean enable); + + /** + * Get whether a simplified Mobile Network Settings UI is enabled. + * + * @param subId for which the simplified UI should be enabled or disabled. + * @return true if the simplified UI is enabled. + */ + boolean getSimplifiedNetworkSettingsEnabled(long subId); + + /** + * Set the phone number string and its alphatag for line 1 for display + * purpose only, for example, displayed in Phone Status. It won't change + * the actual MSISDN/MDN. This setting won't be persisted during power cycle + * and it should be set again after reboot. + * + * @param subId the subscriber that the alphatag and dialing number belongs to. + * @param alphaTag alpha-tagging of the dailing nubmer + * @param number The dialing number + */ + void setLine1NumberForDisplay(long subId, String alphaTag, String number); + + /** + * Returns the displayed dialing number string if it was set previously via + * {@link #setLine1NumberForDisplay}. Otherwise returns null. + * + * @param subId whose dialing number for line 1 is returned. + * @return the displayed dialing number if set, or null if not set. + */ + String getLine1NumberForDisplay(long subId); + + /** + * Returns the displayed alphatag of the dialing number if it was set + * previously via {@link #setLine1NumberForDisplay}. Otherwise returns null. + * + * @param subId whose alphatag associated with line 1 is returned. + * @return the displayed alphatag of the dialing number if set, or null if + * not set. + */ + String getLine1AlphaTagForDisplay(long subId); + + /** + * Override the operator branding for the input ICCID. + * + * Once set, whenever the ICCID is inserted into the device, the service + * provider name (SPN) and the operator name will both be replaced by the + * brand value input. To unset the value, the same function should be + * called with a null brand value. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * or has to be carrier app - see #hasCarrierPrivileges. + * + * @param iccid The ICCID of that the branding applies to. + * @param brand The brand name to display/set. + * @return true if the operation was executed correctly. + */ + boolean setOperatorBrandOverride(String iccId, String brand); + + /** + * Returns the result and response from RIL for oem request + * + * @param oemReq the data is sent to ril. + * @param oemResp the respose data from RIL. + * @return negative value request was not handled or get error + * 0 request was handled succesfully, but no response data + * positive value success, data length of response + */ + int invokeOemRilRequestRaw(in byte[] oemReq, out byte[] oemResp); } diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 546ce17..fd2d1c7 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -18,27 +18,42 @@ package com.android.internal.telephony; import android.content.Intent; import android.net.LinkProperties; -import android.net.LinkCapabilities; +import android.net.NetworkCapabilities; import android.os.Bundle; +import android.telephony.CellInfo; +import android.telephony.DataConnectionRealTimeInfo; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.CellInfo; +import android.telephony.VoLteServiceState; import com.android.internal.telephony.IPhoneStateListener; interface ITelephonyRegistry { void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); - + void listenUsingSubId(in long subId, String pkg, IPhoneStateListener callback, int events, + boolean notifyNow); void notifyCallState(int state, String incomingNumber); + void notifyCallStateUsingSubId(in long subId, int state, String incomingNumber); void notifyServiceState(in ServiceState state); + void notifyServiceStateUsingSubId(in long subId, in ServiceState state); void notifySignalStrength(in SignalStrength signalStrength); + void notifySignalStrengthUsingSubId(in long subId, in SignalStrength signalStrength); void notifyMessageWaitingChanged(boolean mwi); + void notifyMessageWaitingChangedUsingSubId(in long subId, boolean mwi); void notifyCallForwardingChanged(boolean cfi); + void notifyCallForwardingChangedUsingSubId(in long subId, boolean cfi); void notifyDataActivity(int state); + void notifyDataActivityUsingSubId(in long subId, int state); void notifyDataConnection(int state, boolean isDataConnectivityPossible, String reason, String apn, String apnType, in LinkProperties linkProperties, - in LinkCapabilities linkCapabilities, int networkType, boolean roaming); + in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); + void notifyDataConnectionUsingSubId(long subId, int state, boolean isDataConnectivityPossible, + String reason, String apn, String apnType, in LinkProperties linkProperties, + in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); void notifyDataConnectionFailed(String reason, String apnType); + void notifyDataConnectionFailedUsingSubId(long subId, String reason, String apnType); void notifyCellLocation(in Bundle cellLocation); + void notifyCellLocationUsingSubId(in long subId, in Bundle cellLocation); void notifyOtaspChanged(in int otaspMode); void notifyCellInfo(in List<CellInfo> cellInfo); void notifyPreciseCallState(int ringingCallState, int foregroundCallState, @@ -46,4 +61,7 @@ interface ITelephonyRegistry { void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause); void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, String failCause); + void notifyCellInfoUsingSubId(in long subId, in List<CellInfo> cellInfo); + void notifyDataConnectionRealTimeInfo(in DataConnectionRealTimeInfo dcRtInfo); + void notifyVoLteServiceStateChanged(in VoLteServiceState lteState); } diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index 1fed417..cf87bec 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -57,17 +57,19 @@ public class PhoneConstants { public static final int PHONE_TYPE_GSM = RILConstants.GSM_PHONE; public static final int PHONE_TYPE_CDMA = RILConstants.CDMA_PHONE; public static final int PHONE_TYPE_SIP = RILConstants.SIP_PHONE; + public static final int PHONE_TYPE_THIRD_PARTY = RILConstants.THIRD_PARTY_PHONE; + public static final int PHONE_TYPE_IMS = RILConstants.IMS_PHONE; // Modes for LTE_ON_CDMA public static final int LTE_ON_CDMA_UNKNOWN = RILConstants.LTE_ON_CDMA_UNKNOWN; public static final int LTE_ON_CDMA_FALSE = RILConstants.LTE_ON_CDMA_FALSE; public static final int LTE_ON_CDMA_TRUE = RILConstants.LTE_ON_CDMA_TRUE; - // Number presentation type for caller id display (From internal/Conneciton.java) - public static int PRESENTATION_ALLOWED = 1; // normal - public static int PRESENTATION_RESTRICTED = 2; // block by user - public static int PRESENTATION_UNKNOWN = 3; // no specified or unknown by network - public static int PRESENTATION_PAYPHONE = 4; // show pay phone info + // Number presentation type for caller id display (From internal/Connection.java) + public static final int PRESENTATION_ALLOWED = 1; // normal + public static final int PRESENTATION_RESTRICTED = 2; // block by user + public static final int PRESENTATION_UNKNOWN = 3; // no specified or unknown by network + public static final int PRESENTATION_PAYPHONE = 4; // show pay phone info public static final String PHONE_NAME_KEY = "phoneName"; @@ -78,7 +80,7 @@ public class PhoneConstants { public static final String DATA_APN_TYPE_KEY = "apnType"; public static final String DATA_APN_KEY = "apn"; public static final String DATA_LINK_PROPERTIES_KEY = "linkProperties"; - public static final String DATA_LINK_CAPABILITIES_KEY = "linkCapabilities"; + public static final String DATA_NETWORK_CAPABILITIES_KEY = "networkCapabilities"; public static final String DATA_IFACE_NAME_KEY = "iface"; public static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable"; @@ -131,5 +133,58 @@ public class PhoneConstants { public static final String APN_TYPE_CBS = "cbs"; /** APN type for IA Initial Attach APN */ public static final String APN_TYPE_IA = "ia"; + /** APN type for IA Emergency PDN */ + public static final String APN_TYPE_EMERGENCY = "emergency"; + // FIXME: This looks to be used as default phoneId, rename + // or use SubscriptionManager.DEFAULT_SUB_ID + public static final int DEFAULT_SUBSCRIPTION = 0; + + // FIXME: This looks to be used as invalid phoneId, rename + // or use SubscriptionManager.INVALID_SUB_ID + public static final int INVALID_SUBSCRIPTION = -1; + + public static final int RIL_CARD_MAX_APPS = 8; + + public static final int DEFAULT_CARD_INDEX = 0; + + public static final int MAX_PHONE_COUNT_SINGLE_SIM = 1; + + public static final int MAX_PHONE_COUNT_DUAL_SIM = 2; + + public static final int MAX_PHONE_COUNT_TRI_SIM = 3; + + public static final String SUBSCRIPTION_KEY = "subscription"; + + public static final String SLOT_KEY = "slot"; + + public static final String SUB_SETTING = "subSettings"; + + public static final int SUB1 = 0; + public static final int SUB2 = 1; + public static final int SUB3 = 2; + + public static final int EVENT_SUBSCRIPTION_ACTIVATED = 500; + public static final int EVENT_SUBSCRIPTION_DEACTIVATED = 501; + + // TODO: Remove these constants and use an int instead. + public static final int SIM_ID_1 = 0; + public static final int SIM_ID_2 = 1; + public static final int SIM_ID_3 = 2; + public static final int SIM_ID_4 = 3; + + // ICC SIM Application Types + // TODO: Replace the IccCardApplicationStatus.AppType enums with these constants + public static final int APPTYPE_UNKNOWN = 0; + public static final int APPTYPE_SIM = 1; + public static final int APPTYPE_USIM = 2; + public static final int APPTYPE_RUIM = 3; + public static final int APPTYPE_CSIM = 4; + public static final int APPTYPE_ISIM = 5; + + public enum CardUnavailableReason { + REASON_CARD_REMOVED, + REASON_RADIO_UNAVAILABLE, + REASON_SIM_REFRESH_RESET + }; } diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 8e445d9..1529859 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -57,6 +57,7 @@ public interface RILConstants { retries needed */ int MISSING_RESOURCE = 16; /* no logical channel available */ int NO_SUCH_ELEMENT = 17; /* application not found on SIM */ + int SUBSCRIPTION_NOT_SUPPORTED = 26; /* Subscription not supported */ /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */ int NETWORK_MODE_WCDMA_PREF = 0; /* GSM/WCDMA (WCDMA preferred) */ @@ -72,7 +73,7 @@ public interface RILConstants { AVAILABLE Application Settings menu*/ int NETWORK_MODE_LTE_CDMA_EVDO = 8; /* LTE, CDMA and EvDo */ int NETWORK_MODE_LTE_GSM_WCDMA = 9; /* LTE, GSM/WCDMA */ - int NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */ + int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */ int NETWORK_MODE_LTE_ONLY = 11; /* LTE Only mode. */ int NETWORK_MODE_LTE_WCDMA = 12; /* LTE/WCDMA */ int PREFERRED_NETWORK_MODE = NETWORK_MODE_WCDMA_PREF; @@ -84,6 +85,8 @@ public interface RILConstants { int GSM_PHONE = 1; int CDMA_PHONE = 2; int SIP_PHONE = 3; + int THIRD_PARTY_PHONE = 4; + int IMS_PHONE = 5; int LTE_ON_CDMA_UNKNOWN = -1; int LTE_ON_CDMA_FALSE = 0; @@ -114,6 +117,11 @@ public interface RILConstants { int DEACTIVATE_REASON_RADIO_OFF = 1; int DEACTIVATE_REASON_PDP_RESET = 2; + /* NV config radio reset types. */ + int NV_CONFIG_RELOAD_RESET = 1; + int NV_CONFIG_ERASE_RESET = 2; + int NV_CONFIG_FACTORY_RESET = 3; + /* cat include/telephony/ril.h | \ egrep '^#define' | \ @@ -271,6 +279,15 @@ cat include/telephony/ril.h | \ int RIL_REQUEST_SIM_OPEN_CHANNEL = 115; int RIL_REQUEST_SIM_CLOSE_CHANNEL = 116; int RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL = 117; + int RIL_REQUEST_NV_READ_ITEM = 118; + int RIL_REQUEST_NV_WRITE_ITEM = 119; + int RIL_REQUEST_NV_WRITE_CDMA_PRL = 120; + int RIL_REQUEST_NV_RESET_CONFIG = 121; + int RIL_REQUEST_SET_UICC_SUBSCRIPTION = 122; + int RIL_REQUEST_ALLOW_DATA = 123; + int RIL_REQUEST_GET_HARDWARE_CONFIG = 124; + int RIL_REQUEST_SIM_AUTHENTICATION = 125; + int RIL_UNSOL_RESPONSE_BASE = 1000; int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000; int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001; @@ -310,4 +327,7 @@ cat include/telephony/ril.h | \ int RIL_UNSOL_VOICE_RADIO_TECH_CHANGED = 1035; int RIL_UNSOL_CELL_INFO_LIST = 1036; int RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED = 1037; + int RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED = 1038; + int RIL_UNSOL_SRVCC_STATE_NOTIFY = 1039; + int RIL_UNSOL_HARDWARE_CONFIG_CHANGED = 1040; } diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java index a7baf1c..5954947 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java +++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java @@ -16,6 +16,8 @@ package com.android.internal.telephony; +import android.content.Intent; + /** * The intents that the telephony services broadcast. * @@ -48,7 +50,7 @@ public class TelephonyIntents { * * <p class="note"> * Requires the READ_PHONE_STATE permission. - * + * * <p class="note">This is a protected intent that can only be sent * by the system. */ @@ -69,7 +71,7 @@ public class TelephonyIntents { * * <p class="note"> * Requires no permission. - * + * * <p class="note">This is a protected intent that can only be sent * by the system. */ @@ -88,7 +90,7 @@ public class TelephonyIntents { * * <p class="note"> * Requires no permission. - * + * * <p class="note">This is a protected intent that can only be sent * by the system. */ @@ -114,7 +116,7 @@ public class TelephonyIntents { * * <p class="note"> * Requires the READ_PHONE_STATE permission. - * + * * <p class="note">This is a protected intent that can only be sent * by the system. */ @@ -125,20 +127,18 @@ public class TelephonyIntents { * Broadcast Action: The data connection state has changed for any one of the * phone's mobile data connections (eg, default, MMS or GPS specific connection). * The intent will have the following extra values:</p> - * <ul> - * <li><em>phoneName</em> - A string version of the phone name.</li> - * <li><em>state</em> - One of <code>"CONNECTED"</code> - * <code>"CONNECTING"</code> or <code>"DISCONNNECTED"</code></li> - * <li><em>apn</em> - A string that is the APN associated with this - * connection.</li> - * <li><em>apnType</em> - A string array of APN types associated with - * this connection. The APN type <code>"*"</code> is a special - * type that means this APN services all types.</li> - * </ul> + * <dl> + * <dt>phoneName</dt><dd>A string version of the phone name.</dd> + * <dt>state</dt><dd>One of {@code CONNECTED}, {@code CONNECTING}, + * or {@code DISCONNECTED}.</dd> + * <dt>apn</dt><dd>A string that is the APN associated with this connection.</dd> + * <dt>apnType</dt><dd>A string array of APN types associated with this connection. + * The APN type {@code *} is a special type that means this APN services all types.</dd> + * </dl> * * <p class="note"> * Requires the READ_PHONE_STATE permission. - * + * * <p class="note">This is a protected intent that can only be sent * by the system. */ @@ -149,16 +149,14 @@ public class TelephonyIntents { * Broadcast Action: Occurs when a data connection connects to a provisioning apn * and is broadcast by the low level data connection code. * The intent will have the following extra values:</p> - * <ul> - * <li><em>apn</em> - A string that is the APN associated with this - * connection.</li> - * <li><em>apnType</em> - A string array of APN types associated with - * this connection. The APN type <code>"*"</code> is a special - * type that means this APN services all types.</li> - * <li><em>linkProperties</em> - The <code>LinkProperties</code> for this APN</li> - * <li><em>linkCapabilities</em> - The <code>linkCapabilities</code> for this APN</li> - * <li><em>iface</em> - A string that is the name of the interface</li> - * </ul> + * <dl> + * <dt>apn</dt><dd>A string that is the APN associated with this connection.</dd> + * <dt>apnType</dt><dd>A string array of APN types associated with this connection. + * The APN type {@code *} is a special type that means this APN services all types.</dd> + * <dt>linkProperties</dt><dd>{@code LinkProperties} for this APN.</dd> + * <dt>linkCapabilities</dt><dd>The {@code LinkCapabilities} for this APN.</dd> + * <dt>iface</dt><dd>A string that is the name of the interface.</dd> + * </dl> * * <p class="note"> * Requires the READ_PHONE_STATE permission. @@ -172,16 +170,15 @@ public class TelephonyIntents { /** * Broadcast Action: An attempt to establish a data connection has failed. * The intent will have the following extra values:</p> - * <ul> - * <li><em>phoneName</em> &mdash A string version of the phone name.</li> - * <li><em>state</em> — One of <code>"CONNECTED"</code> - * <code>"CONNECTING"</code> or <code>"DISCONNNECTED"</code></li> - * <li><em>reason</em> — A string indicating the reason for the failure, if available</li> - * </ul> + * <dl> + * <dt>phoneName</dt><dd>A string version of the phone name.</dd> + * <dt>state</dt><dd>One of {@code CONNECTED}, {@code CONNECTING}, or {code DISCONNECTED}.</dd> + * <dt>reason</dt><dd>A string indicating the reason for the failure, if available.</dd> + * </dl> * * <p class="note"> * Requires the READ_PHONE_STATE permission. - * + * * <p class="note">This is a protected intent that can only be sent * by the system. */ @@ -192,20 +189,27 @@ public class TelephonyIntents { /** * Broadcast Action: The sim card state has changed. * The intent will have the following extra values:</p> - * <ul> - * <li><em>phoneName</em> - A string version of the phone name.</li> - * <li><em>ss</em> - The sim state. One of - * <code>"ABSENT"</code> <code>"LOCKED"</code> - * <code>"READY"</code> <code>"ISMI"</code> <code>"LOADED"</code> </li> - * <li><em>reason</em> - The reason while ss is LOCKED, otherwise is null - * <code>"PIN"</code> locked on PIN1 - * <code>"PUK"</code> locked on PUK1 - * <code>"NETWORK"</code> locked on Network Personalization </li> - * </ul> + * <dl> + * <dt>phoneName</dt><dd>A string version of the phone name.</dd> + * <dt>ss</dt><dd>The sim state. One of: + * <dl> + * <dt>{@code ABSENT}</dt><dd>SIM card not found</dd> + * <dt>{@code LOCKED}</dt><dd>SIM card locked (see {@code reason})</dd> + * <dt>{@code READY}</dt><dd>SIM card ready</dd> + * <dt>{@code IMSI}</dt><dd>FIXME: what is this state?</dd> + * <dt>{@code LOADED}</dt><dd>SIM card data loaded</dd> + * </dl></dd> + * <dt>reason</dt><dd>The reason why ss is {@code LOCKED}; null otherwise.</dd> + * <dl> + * <dt>{@code PIN}</dt><dd>locked on PIN1</dd> + * <dt>{@code PUK}</dt><dd>locked on PUK1</dd> + * <dt>{@code NETWORK}</dt><dd>locked on network personalization</dd> + * </dl> + * </dl> * * <p class="note"> * Requires the READ_PHONE_STATE permission. - * + * * <p class="note">This is a protected intent that can only be sent * by the system. */ @@ -223,7 +227,7 @@ public class TelephonyIntents { * * <p class="note"> * Requires the READ_PHONE_STATE permission. - * + * * <p class="note">This is a protected intent that can only be sent * by the system. */ @@ -241,7 +245,7 @@ public class TelephonyIntents { * * <p class="note"> * Requires the READ_PHONE_STATE permission. - * + * * <p class="note">This is a protected intent that can only be sent * by the system. */ @@ -272,31 +276,30 @@ public class TelephonyIntents { /** * A <em>prefix</em> for the MCC/MNC filtering used with {@link #ACTION_CARRIER_SETUP}. * The MCC/MNC will be concatenated (zero-padded to 3 digits each) to create a final - * string of the form: - * <br /> - * <code>android.intent.category.MCCMNC_310260</code> + * string of the form: {@code android.intent.category.MCCMNC_310260} */ public static final String CATEGORY_MCCMNC_PREFIX = "android.intent.category.MCCMNC_"; /** * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are - * of the form *#*#<code>#*#*. The intent will have the data URI:</p> + * of the form {@code *#*#<code>#*#*}. The intent will have the data URI: * - * <p><code>android_secret_code://<code></code></p> + * {@code android_secret_code://<code>} */ - public static final String SECRET_CODE_ACTION = - "android.provider.Telephony.SECRET_CODE"; + public static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE"; /** * Broadcast Action: The Service Provider string(s) have been updated. Activities or * services that use these strings should update their display. * The intent will have the following extra values:</p> - * <ul> - * <li><em>showPlmn</em> - Boolean that indicates whether the PLMN should be shown.</li> - * <li><em>plmn</em> - The operator name of the registered network, as a string.</li> - * <li><em>showSpn</em> - Boolean that indicates whether the SPN should be shown.</li> - * <li><em>spn</em> - The service provider name, as a string.</li> - * </ul> + * + * <dl> + * <dt>showPlmn</dt><dd>Boolean that indicates whether the PLMN should be shown.</dd> + * <dt>plmn</dt><dd>The operator name of the registered network, as a string.</dd> + * <dt>showSpn</dt><dd>Boolean that indicates whether the SPN should be shown.</dd> + * <dt>spn</dt><dd>The service provider name, as a string.</dd> + * </dl> + * * Note that <em>showPlmn</em> may indicate that <em>plmn</em> should be displayed, even * though the value for <em>plmn</em> is null. This can happen, for example, if the phone * has not registered to a network yet. In this case the receiver may substitute an @@ -305,8 +308,7 @@ public class TelephonyIntents { * It is recommended to display <em>plmn</em> before / above <em>spn</em> if * both are displayed. * - * <p>Note this is a protected intent that can only be sent - * by the system. + * <p>Note: this is a protected intent that can only be sent by the system. */ public static final String SPN_STRINGS_UPDATED_ACTION = "android.provider.Telephony.SPN_STRINGS_UPDATED"; @@ -315,4 +317,85 @@ public class TelephonyIntents { public static final String EXTRA_PLMN = "plmn"; public static final String EXTRA_SHOW_SPN = "showSpn"; public static final String EXTRA_SPN = "spn"; + + /** + * <p>Broadcast Action: It indicates one column of a siminfo record has been changed + * The intent will have the following extra values:</p> + * <ul> + * <li><em>columnName</em> - The siminfo column that is updated.</li> + * <li><em>stringContent</em> - The string value of the updated column.</li> + * <li><em>intContent</em> - The int value of the updated column.</li> + * </ul> + * <p class="note">This is a protected intent that can only be sent + * by the system. + */ + public static final String ACTION_SIMINFO_CONTENT_CHANGE + = "android.intent.action.ACTION_SIMINFO_CONTENT_CHANGE"; + + /** + * <p>Broadcast Action: It indicates one column of a subinfo record has been changed + * The intent will have the following extra values:</p> + * <ul> + * <li><em>columnName</em> - The siminfo column that is updated.</li> + * <li><em>stringContent</em> - The string value of the updated column.</li> + * <li><em>intContent</em> - The int value of the updated column.</li> + * </ul> + * <p class="note">This is a protected intent that can only be sent + * by the system. + */ + public static final String ACTION_SUBINFO_CONTENT_CHANGE + = "android.intent.action.ACTION_SUBINFO_CONTENT_CHANGE"; + + /** + * <p>Broadcast Action: It indicates siminfo update is completed when SIM inserted state change + * The intent will have the following extra values:</p> + * <p class="note">This is a protected intent that can only be sent + * by the system. + */ + public static final String ACTION_SIMINFO_UPDATED + = "android.intent.action.ACTION_SIMINFO_UPDATED"; + + /** + * <p>Broadcast Action: It indicates subinfo record update is completed + * when SIM inserted state change + * The intent will have the following extra values:</p> + * <p class="note">This is a protected intent that can only be sent + * by the system. + */ + public static final String ACTION_SUBINFO_RECORD_UPDATED + = "android.intent.action.ACTION_SUBINFO_RECORD_UPDATED"; + + public static final String EXTRA_COLUMN_NAME = "columnName"; + public static final String EXTRA_INT_CONTENT = "intContent"; + public static final String EXTRA_STRING_CONTENT = "stringContent"; + + /** + * Broadcast Action: The default subscription has changed. This has the following + * extra values:</p> + * <ul> + * <li><em>subscription</em> - A int, the current default subscription.</li> + * </ul> + */ + public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED + = "android.intent.action.ACTION_DEFAULT_SUBSCRIPTION_CHANGED"; + + /** + * Broadcast Action: The default data subscription has changed. This has the following + * extra values:</p> + * <ul> + * <li><em>subscription</em> - A int, the current data default subscription.</li> + * </ul> + */ + public static final String ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED + = "android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED"; + + /** + * Broadcast Action: The default voice subscription has changed. This has the following + * extra values:</p> + * <ul> + * <li><em>subscription</em> - A int, the current voice default subscription.</li> + * </ul> + */ + public static final String ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED + = "android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED"; } diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java index f95e081..5ec4247 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java +++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java @@ -187,4 +187,26 @@ public interface TelephonyProperties * Ignore RIL_UNSOL_NITZ_TIME_RECEIVED completely, used for debugging/testing. */ static final String PROPERTY_IGNORE_NITZ = "telephony.test.ignore.nitz"; + + /** + * Property to set multi sim feature. + * Type: String(dsds, dsda) + */ + static final String PROPERTY_MULTI_SIM_CONFIG = "persist.radio.multisim.config"; + + /** + * Property to store default subscription. + */ + static final String PROPERTY_DEFAULT_SUBSCRIPTION = "persist.radio.default.sub"; + + /** + * Property to enable MMS Mode. + * Type: string ( default = silent, enable to = prompt ) + */ + static final String PROPERTY_MMS_TRANSACTION = "mms.transaction"; + + /** + * Set to the sim count. + */ + static final String PROPERTY_SIM_COUNT = "ro.telephony.sim.count"; } |