summaryrefslogtreecommitdiffstats
path: root/telephony/java
diff options
context:
space:
mode:
Diffstat (limited to 'telephony/java')
-rw-r--r--telephony/java/android/telephony/NeighboringCellInfo.java2
-rw-r--r--telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java223
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java169
-rw-r--r--telephony/java/android/telephony/PhoneStateListener.java34
-rw-r--r--telephony/java/android/telephony/SmsManager.java23
-rw-r--r--telephony/java/android/telephony/SmsMessage.java5
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java44
-rw-r--r--telephony/java/com/android/internal/telephony/CallerInfo.java7
-rw-r--r--telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java7
-rw-r--r--telephony/java/com/android/internal/telephony/CommandsInterface.java18
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java143
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionTracker.java444
-rw-r--r--telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java41
-rw-r--r--telephony/java/com/android/internal/telephony/GsmAlphabet.java43
-rw-r--r--telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl1
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl8
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl9
-rw-r--r--telephony/java/com/android/internal/telephony/IccUtils.java24
-rw-r--r--telephony/java/com/android/internal/telephony/MccTable.java873
-rw-r--r--telephony/java/com/android/internal/telephony/Phone.java58
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java77
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneNotifier.java7
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneProxy.java40
-rw-r--r--telephony/java/com/android/internal/telephony/RIL.java26
-rw-r--r--telephony/java/com/android/internal/telephony/SMSDispatcher.java7
-rw-r--r--telephony/java/com/android/internal/telephony/ServiceStateTracker.java8
-rw-r--r--telephony/java/com/android/internal/telephony/SmsHeader.java2
-rw-r--r--telephony/java/com/android/internal/telephony/SmsMessageBase.java5
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyProperties.java8
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CDMAPhone.java45
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java18
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java15
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java517
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java15
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java85
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java3
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/SmsMessage.java4
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java16
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GSMPhone.java29
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java22
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java777
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java15
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java49
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsMessage.java77
-rwxr-xr-xtelephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java2
-rw-r--r--telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java7
-rwxr-xr-xtelephony/java/com/android/internal/telephony/sip/SipPhone.java17
-rwxr-xr-xtelephony/java/com/android/internal/telephony/sip/SipPhoneBase.java20
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedCommands.java51
51 files changed, 2377 insertions, 1767 deletions
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
index 2f7666d..0f9a3b9 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.java
+++ b/telephony/java/android/telephony/NeighboringCellInfo.java
@@ -127,7 +127,7 @@ public class NeighboringCellInfo implements Parcelable
location = "0" + location;
}
}
-
+ // TODO - handle LTE and eHRPD (or find they can't be supported)
try {// set LAC/CID or PSC based on radioType
switch (radioType) {
case NETWORK_TYPE_GPRS:
diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
index 8a47339..ffabb7b 100644
--- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
+++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
@@ -16,83 +16,200 @@
package android.telephony;
+import com.google.i18n.phonenumbers.AsYouTypeFormatter;
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+
+import android.telephony.PhoneNumberUtils;
import android.text.Editable;
import android.text.Selection;
import android.text.TextWatcher;
-import android.widget.TextView;
import java.util.Locale;
/**
- * Watches a {@link TextView} and if a phone number is entered will format it using
- * {@link PhoneNumberUtils#formatNumber(Editable, int)}. The formatting is based on
- * the current system locale when this object is created and future locale changes
- * may not take effect on this instance.
+ * Watches a {@link android.widget.TextView} and if a phone number is entered
+ * will format it.
+ * <p>
+ * Stop formatting when the user
+ * <ul>
+ * <li>Inputs non-dialable characters</li>
+ * <li>Removes the separator in the middle of string.</li>
+ * </ul>
+ * <p>
+ * The formatting will be restarted once the text is cleared.
*/
public class PhoneNumberFormattingTextWatcher implements TextWatcher {
+ /**
+ * One or more characters were removed from the end.
+ */
+ private final static int STATE_REMOVE_LAST = 0;
+
+ /**
+ * One or more characters were appended.
+ */
+ private final static int STATE_APPEND = 1;
+
+ /**
+ * One or more digits were changed in the beginning or the middle of text.
+ */
+ private final static int STATE_MODIFY_DIGITS = 2;
+
+ /**
+ * The changes other than the above.
+ */
+ private final static int STATE_OTHER = 3;
- static private int sFormatType;
- static private Locale sCachedLocale;
- private boolean mFormatting;
- private boolean mDeletingHyphen;
- private int mHyphenStart;
- private boolean mDeletingBackward;
+ /**
+ * The state of this change could be one value of the above
+ */
+ private int mState;
+ /**
+ * Indicates the change was caused by ourselves.
+ */
+ private boolean mSelfChange = false;
+
+ /**
+ * Indicates the formatting has been stopped.
+ */
+ private boolean mStopFormatting;
+
+ private AsYouTypeFormatter mFormatter;
+
+ /**
+ * The formatting is based on the current system locale and future locale changes
+ * may not take effect on this instance.
+ */
public PhoneNumberFormattingTextWatcher() {
- if (sCachedLocale == null || sCachedLocale != Locale.getDefault()) {
- sCachedLocale = Locale.getDefault();
- sFormatType = PhoneNumberUtils.getFormatTypeForLocale(sCachedLocale);
+ this(Locale.getDefault().getCountry());
+ }
+
+ /**
+ * The formatting is based on the given <code>countryCode</code>.
+ *
+ * @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();
+ mFormatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(countryCode);
+ }
+
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {
+ if (mSelfChange || mStopFormatting) {
+ return;
+ }
+ if (count == 0 && s.length() == start) {
+ // Append one or more new chars
+ mState = STATE_APPEND;
+ } else if (after == 0 && start + count == s.length() && count > 0) {
+ // Remove one or more chars from the end of string.
+ mState = STATE_REMOVE_LAST;
+ } else if (count > 0 && !hasSeparator(s, start, count)) {
+ // Remove the dialable chars in the begin or middle of text.
+ mState = STATE_MODIFY_DIGITS;
+ } else {
+ mState = STATE_OTHER;
}
}
- public synchronized void afterTextChanged(Editable text) {
- // Make sure to ignore calls to afterTextChanged caused by the work done below
- if (!mFormatting) {
- mFormatting = true;
-
- // If deleting the hyphen, also delete the char before or after that
- if (mDeletingHyphen && mHyphenStart > 0) {
- if (mDeletingBackward) {
- if (mHyphenStart - 1 < text.length()) {
- text.delete(mHyphenStart - 1, mHyphenStart);
- }
- } else if (mHyphenStart < text.length()) {
- text.delete(mHyphenStart, mHyphenStart + 1);
- }
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ if (mSelfChange || mStopFormatting) {
+ return;
+ }
+ if (mState == STATE_OTHER) {
+ if (count > 0 && !hasSeparator(s, start, count)) {
+ // User inserted the dialable characters in the middle of text.
+ mState = STATE_MODIFY_DIGITS;
}
+ }
+ // Check whether we should stop formatting.
+ if (mState == STATE_APPEND && count > 0 && hasSeparator(s, start, count)) {
+ // User appended the non-dialable character, stop formatting.
+ stopFormatting();
+ } else if (mState == STATE_OTHER) {
+ // User must insert or remove the non-dialable characters in the begin or middle of
+ // number, stop formatting.
+ stopFormatting();
+ }
+ }
- PhoneNumberUtils.formatNumber(text, sFormatType);
-
- mFormatting = false;
+ public synchronized void afterTextChanged(Editable s) {
+ if (mStopFormatting) {
+ // Restart the formatting when all texts were clear.
+ mStopFormatting = !(s.length() == 0);
+ return;
+ }
+ if (mSelfChange) {
+ // Ignore the change caused by s.replace().
+ return;
+ }
+ String formatted = reformat(s, Selection.getSelectionEnd(s));
+ if (formatted != null) {
+ int rememberedPos = mFormatter.getRememberedPosition();
+ mSelfChange = true;
+ s.replace(0, s.length(), formatted, 0, formatted.length());
+ // The text could be changed by other TextWatcher after we changed it. If we found the
+ // text is not the one we were expecting, just give up calling setSelection().
+ if (formatted.equals(s.toString())) {
+ Selection.setSelection(s, rememberedPos);
+ }
+ mSelfChange = false;
}
}
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- // Check if the user is deleting a hyphen
- if (!mFormatting) {
- // Make sure user is deleting one char, without a selection
- final int selStart = Selection.getSelectionStart(s);
- final int selEnd = Selection.getSelectionEnd(s);
- if (s.length() > 1 // Can delete another character
- && count == 1 // Deleting only one character
- && after == 0 // Deleting
- && s.charAt(start) == '-' // a hyphen
- && selStart == selEnd) { // no selection
- mDeletingHyphen = true;
- mHyphenStart = start;
- // Check if the user is deleting forward or backward
- if (selStart == start + 1) {
- mDeletingBackward = true;
- } else {
- mDeletingBackward = false;
+ /**
+ * Generate the formatted number by ignoring all non-dialable chars and stick the cursor to the
+ * nearest dialable char to the left. For instance, if the number is (650) 123-45678 and '4' is
+ * removed then the cursor should be behind '3' instead of '-'.
+ */
+ private String reformat(CharSequence s, int cursor) {
+ // The index of char to the leftward of the cursor.
+ int curIndex = cursor - 1;
+ String formatted = null;
+ mFormatter.clear();
+ char lastNonSeparator = 0;
+ boolean hasCursor = false;
+ int len = s.length();
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt(i);
+ if (PhoneNumberUtils.isNonSeparator(c)) {
+ if (lastNonSeparator != 0) {
+ formatted = getFormattedNumber(lastNonSeparator, hasCursor);
+ hasCursor = false;
}
- } else {
- mDeletingHyphen = false;
+ lastNonSeparator = c;
}
+ if (i == curIndex) {
+ hasCursor = true;
+ }
+ }
+ if (lastNonSeparator != 0) {
+ formatted = getFormattedNumber(lastNonSeparator, hasCursor);
}
+ return formatted;
}
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- // Does nothing
+ private String getFormattedNumber(char lastNonSeparator, boolean hasCursor) {
+ return hasCursor ? mFormatter.inputDigitAndRememberPosition(lastNonSeparator)
+ : mFormatter.inputDigit(lastNonSeparator);
+ }
+
+ private void stopFormatting() {
+ mStopFormatting = true;
+ mFormatter.clear();
+ }
+
+ private boolean hasSeparator(final CharSequence s, final int start, final int count) {
+ for (int i = start; i < start + count; i++) {
+ char c = s.charAt(i);
+ if (!PhoneNumberUtils.isNonSeparator(c)) {
+ return true;
+ }
+ }
+ return false;
}
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 8e4f6fc..893ae88 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -16,6 +16,11 @@
package android.telephony;
+import com.google.i18n.phonenumbers.NumberParseException;
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
@@ -617,7 +622,7 @@ public class PhoneNumberUtils
}
} else {
// In the US, 1-650-555-1234 must be equal to 650-555-1234,
- // while 090-1234-1234 must not be equalt to 90-1234-1234 in Japan.
+ // while 090-1234-1234 must not be equal to 90-1234-1234 in Japan.
// This request exists just in US (with 1 trunk (NDD) prefix).
// In addition, "011 11 7005554141" must not equal to "+17005554141",
// while "011 1 7005554141" must equal to "+17005554141"
@@ -779,10 +784,10 @@ public class PhoneNumberUtils
if (prependPlus) {
// This is an "international number" and should have
// a plus prepended to the dialing number. But there
- // can also be Gsm MMI codes as defined in TS 22.030 6.5.2
+ // can also be GSM MMI codes as defined in TS 22.030 6.5.2
// so we need to handle those also.
//
- // http://web.telia.com/~u47904776/gsmkode.htm is a
+ // http://web.telia.com/~u47904776/gsmkode.htm
// has a nice list of some of these GSM codes.
//
// Examples are:
@@ -870,10 +875,10 @@ public class PhoneNumberUtils
// FIXME(mkf) TS 23.040 9.1.2.3 says
// "if a mobile receives 1111 in a position prior to
- // the last semi-octet then processing shall commense with
+ // the last semi-octet then processing shall commence with
// the next semi-octet and the intervening
// semi-octet shall be ignored"
- // How does this jive with 24,008 10.5.4.7
+ // How does this jive with 24.008 10.5.4.7
b = (byte)((bytes[i] >> 4) & 0xf);
@@ -1004,7 +1009,7 @@ public class PhoneNumberUtils
* Convert a dialing number to BCD byte array
*
* @param number dialing number string
- * if the dialing number starts with '+', set to internationl TOA
+ * if the dialing number starts with '+', set to international TOA
* @return BCD byte array
*/
public static byte[]
@@ -1108,10 +1113,10 @@ public class PhoneNumberUtils
*
* @param source the phone number to format
* @param defaultFormattingType The default formatting rules to apply if the number does
- * not begin with +<country_code>
+ * not begin with +[country_code]
* @return The phone number formatted with the given formatting type.
*
- * @hide TODO:Shuold be unhidden.
+ * @hide TODO: Should be unhidden.
*/
public static String formatNumber(String source, int defaultFormattingType) {
SpannableStringBuilder text = new SpannableStringBuilder(source);
@@ -1138,7 +1143,7 @@ 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>
+ * not begin with +[country_code]
*/
public static void formatNumber(Editable text, int defaultFormattingType) {
int formatType = defaultFormattingType;
@@ -1319,6 +1324,132 @@ public class PhoneNumberUtils
}
}
+ /**
+ * Format the given phoneNumber to the E.164 representation.
+ * <p>
+ * The given phone number must have an area code and could have a country
+ * code.
+ * <p>
+ * The defaultCountryIso is used to validate the given number and generate
+ * the E.164 phone number if the given number doesn't have a country code.
+ *
+ * @param phoneNumber
+ * the phone number to format
+ * @param defaultCountryIso
+ * 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();
+ String result = null;
+ try {
+ PhoneNumber pn = util.parse(phoneNumber, defaultCountryIso);
+ if (util.isValidNumber(pn)) {
+ result = util.format(pn, PhoneNumberFormat.E164);
+ }
+ } catch (NumberParseException e) {
+ }
+ return result;
+ }
+
+ /**
+ * Format a phone number.
+ * <p>
+ * If the given number doesn't have the country code, the phone will be
+ * formatted to the default country's convention.
+ *
+ * @param phoneNumber
+ * the number to be formatted.
+ * @param defaultCountryIso
+ * 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) {
+ PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+ String result = null;
+ try {
+ PhoneNumber pn = util.parseAndKeepRawInput(phoneNumber, defaultCountryIso);
+ result = util.formatInOriginalFormat(pn, defaultCountryIso);
+ } catch (NumberParseException e) {
+ }
+ return result;
+ }
+
+ /**
+ * Format the phone number only if the given number hasn't been formatted.
+ * <p>
+ * The number which has only dailable character is treated as not being
+ * formatted.
+ *
+ * @param phoneNumber
+ * the number to be formatted.
+ * @param phoneNumberE164
+ * the E164 format number whose country code is used if the given
+ * phoneNumber doesn't have the country code.
+ * @param defaultCountryIso
+ * the ISO 3166-1 two letters country code whose convention will
+ * be used if the phoneNumberE164 is null or invalid.
+ * @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) {
+ int len = phoneNumber.length();
+ for (int i = 0; i < len; i++) {
+ if (!isDialable(phoneNumber.charAt(i))) {
+ return phoneNumber;
+ }
+ }
+ PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+ // Get the country code from phoneNumberE164
+ if (phoneNumberE164 != null && phoneNumberE164.length() >= 2
+ && phoneNumberE164.charAt(0) == '+') {
+ try {
+ PhoneNumber pn = util.parse(phoneNumberE164, defaultCountryIso);
+ String regionCode = util.getRegionCodeForNumber(pn);
+ if (!TextUtils.isEmpty(regionCode)) {
+ defaultCountryIso = regionCode;
+ }
+ } catch (NumberParseException e) {
+ }
+ }
+ String result = formatNumber(phoneNumber, defaultCountryIso);
+ return result != null ? result : phoneNumber;
+ }
+
+ /**
+ * Normalize a phone number by removing the characters other than digits. If
+ * the given number has keypad letters, the letters will be converted to
+ * digits first.
+ *
+ * @param phoneNumber
+ * the number to be normalized.
+ * @return the normalized number.
+ *
+ * @hide
+ */
+ public static String normalizeNumber(String phoneNumber) {
+ StringBuilder sb = new StringBuilder();
+ int len = phoneNumber.length();
+ for (int i = 0; i < len; i++) {
+ char c = phoneNumber.charAt(i);
+ if ((i == 0 && c == '+') || PhoneNumberUtils.isISODigit(c)) {
+ sb.append(c);
+ } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ return normalizeNumber(PhoneNumberUtils.convertKeypadLettersToDigits(phoneNumber));
+ }
+ }
+ return sb.toString();
+ }
+
// Three and four digit phone numbers for either special services,
// or 3-6 digit addresses from the network (eg carrier-originated SMS messages) should
// not match.
@@ -1546,7 +1677,7 @@ public class PhoneNumberUtils
* @hide
*/
public static String
- cdmaCheckAndProcessPlusCodeByNumberFormat(String dialStr,int currFormat,int defaultFormt) {
+ cdmaCheckAndProcessPlusCodeByNumberFormat(String dialStr,int currFormat,int defaultFormat) {
String retStr = dialStr;
// Checks if the plus sign character is in the passed-in dial string
@@ -1554,7 +1685,7 @@ public class PhoneNumberUtils
dialStr.lastIndexOf(PLUS_SIGN_STRING) != -1) {
// Format the string based on the rules for the country the number is from,
// and the current country the phone is camped on.
- if ((currFormat == defaultFormt) && (currFormat == FORMAT_NANP)) {
+ if ((currFormat == defaultFormat) && (currFormat == FORMAT_NANP)) {
// Handle case where default and current telephone numbering plans are NANP.
String postDialStr = null;
String tempDialStr = dialStr;
@@ -1748,7 +1879,7 @@ public class PhoneNumberUtils
return -1;
}
- // This function appends the non-diablable P/W character to the original
+ // This function appends the non-dialable P/W character to the original
// dial string based on the dialable index passed in
private static String
appendPwCharBackToOrigDialStr(int dialableIndex,String origStr, String dialStr) {
@@ -1768,7 +1899,7 @@ public class PhoneNumberUtils
return retStr;
}
- //===== Begining of utility methods used in compareLoosely() =====
+ //===== Beginning of utility methods used in compareLoosely() =====
/**
* Phone numbers are stored in "lookup" form in the database
@@ -1890,12 +2021,12 @@ public class PhoneNumberUtils
//===== End of utility methods used only in compareLoosely() =====
- //===== Beggining of utility methods used only in compareStrictly() ====
+ //===== Beginning of utility methods used only in compareStrictly() ====
/*
* If true, the number is country calling code.
*/
- private static final boolean COUNTLY_CALLING_CALL[] = {
+ private static final boolean COUNTRY_CALLING_CALL[] = {
true, true, false, false, false, false, false, true, false, false,
false, false, false, false, false, false, false, false, false, false,
true, false, false, false, false, false, false, true, true, false,
@@ -1907,18 +2038,18 @@ public class PhoneNumberUtils
false, true, true, true, true, false, true, false, false, true,
true, true, true, true, true, true, false, false, true, false,
};
- private static final int CCC_LENGTH = COUNTLY_CALLING_CALL.length;
+ private static final int CCC_LENGTH = COUNTRY_CALLING_CALL.length;
/**
* @return true when input is valid Country Calling Code.
*/
private static boolean isCountryCallingCode(int countryCallingCodeCandidate) {
return countryCallingCodeCandidate > 0 && countryCallingCodeCandidate < CCC_LENGTH &&
- COUNTLY_CALLING_CALL[countryCallingCodeCandidate];
+ COUNTRY_CALLING_CALL[countryCallingCodeCandidate];
}
/**
- * Returns interger corresponding to the input if input "ch" is
+ * Returns integer corresponding to the input if input "ch" is
* ISO-LATIN characters 0-9.
* Returns -1 otherwise
*/
@@ -2053,7 +2184,7 @@ public class PhoneNumberUtils
/**
* Return true if the prefix of "str" is "ignorable". Here, "ignorable" means
- * that "str" has only one digit and separater characters. The one digit is
+ * that "str" has only one digit and separator characters. The one digit is
* assumed to be trunk prefix.
*/
private static boolean checkPrefixIsIgnorable(final String str,
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 830af47..eda9b71 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -25,6 +25,7 @@ import android.telephony.CellLocation;
import android.util.Log;
import com.android.internal.telephony.IPhoneStateListener;
+import com.android.internal.telephony.Phone;
/**
* A listener class for monitoring changes in specific telephony states
@@ -147,6 +148,14 @@ public class PhoneStateListener {
*/
public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100;
+ /**
+ * Listen for changes to OTASP mode.
+ *
+ * @see #onOtaspChanged
+ * @hide
+ */
+ public static final int LISTEN_OTASP_CHANGED = 0x00000200;
+
public PhoneStateListener() {
}
@@ -251,6 +260,21 @@ public class PhoneStateListener {
// default implementation empty
}
+
+ /**
+ * The Over The Air Service Provisioning (OTASP) has changed. Requires
+ * the READ_PHONE_STATE permission.
+ * @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.
+ *
+ * @hide
+ */
+ public void onOtaspChanged(int otaspMode) {
+ // default implementation empty
+ }
+
/**
* 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.
@@ -284,16 +308,21 @@ public class PhoneStateListener {
}
public void onDataConnectionStateChanged(int state, int networkType) {
- Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType, null).
+ Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType).
sendToTarget();
}
public void onDataActivity(int direction) {
Message.obtain(mHandler, LISTEN_DATA_ACTIVITY, direction, 0, null).sendToTarget();
}
+
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
Message.obtain(mHandler, LISTEN_SIGNAL_STRENGTHS, 0, 0, signalStrength).sendToTarget();
}
+
+ public void onOtaspChanged(int otaspMode) {
+ Message.obtain(mHandler, LISTEN_OTASP_CHANGED, otaspMode, 0).sendToTarget();
+ }
};
Handler mHandler = new Handler() {
@@ -328,6 +357,9 @@ public class PhoneStateListener {
case LISTEN_SIGNAL_STRENGTHS:
PhoneStateListener.this.onSignalStrengthsChanged((SignalStrength)msg.obj);
break;
+ case LISTEN_OTASP_CHANGED:
+ PhoneStateListener.this.onOtaspChanged(msg.arg1);
+ break;
}
}
};
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index f5e9751..953696b 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -21,7 +21,6 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
-import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.ISms;
import com.android.internal.telephony.IccConstants;
import com.android.internal.telephony.SmsRawData;
@@ -33,7 +32,7 @@ import java.util.List;
/*
* TODO(code review): Curious question... Why are a lot of these
* methods not declared as static, since they do not seem to require
- * any local object state? Assumedly this cannot be changed without
+ * any local object state? Presumably this cannot be changed without
* interfering with the API...
*/
@@ -42,7 +41,8 @@ import java.util.List;
* Get this object by calling the static method SmsManager.getDefault().
*/
public final class SmsManager {
- private static SmsManager sInstance;
+ /** Singleton object constructed during class initialization. */
+ private static final SmsManager sInstance = new SmsManager();
/**
* Send a text based SMS.
@@ -52,8 +52,8 @@ public final class SmsManager {
* the current 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,
+ * 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>
@@ -116,7 +116,7 @@ public final class SmsManager {
* @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,
+ * 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>
@@ -125,7 +125,7 @@ public final class SmsManager {
* 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,
+ * 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
@@ -178,8 +178,8 @@ public final class SmsManager {
* @param destinationPort the port to deliver the message to
* @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,
+ * 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>
@@ -188,7 +188,7 @@ public final class SmsManager {
* 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,
+ * 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
@@ -224,9 +224,6 @@ public final class SmsManager {
* @return the default instance of the SmsManager
*/
public static SmsManager getDefault() {
- if (sInstance == null) {
- sInstance = new SmsManager();
- }
return sInstance;
}
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index a284ea5..0746562 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -20,7 +20,6 @@ import android.os.Parcel;
import android.util.Log;
import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
@@ -54,6 +53,10 @@ public class SmsMessage {
public static final int ENCODING_7BIT = 1;
public static final int ENCODING_8BIT = 2;
public static final int ENCODING_16BIT = 3;
+ /**
+ * @hide This value is not defined in global standard. Only in Korea, this is used.
+ */
+ public static final int ENCODING_KSC5601 = 4;
/** The maximum number of payload bytes per message */
public static final int MAX_USER_DATA_BYTES = 140;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 27e08d4..9ef41f2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -272,13 +272,17 @@ public class TelephonyManager {
public static final int PHONE_TYPE_GSM = Phone.PHONE_TYPE_GSM;
/** Phone radio is CDMA. */
public static final int PHONE_TYPE_CDMA = Phone.PHONE_TYPE_CDMA;
+ /** Phone is via SIP. */
+ public static final int PHONE_TYPE_SIP = Phone.PHONE_TYPE_SIP;
/**
- * Returns a constant indicating the device phone type.
+ * Returns a constant indicating the device phone type. This
+ * indicates the type of radio used to transmit voice calls.
*
* @see #PHONE_TYPE_NONE
* @see #PHONE_TYPE_GSM
* @see #PHONE_TYPE_CDMA
+ * @see #PHONE_TYPE_SIP
*/
public int getPhoneType() {
try{
@@ -393,11 +397,15 @@ public class TelephonyManager {
public static final int NETWORK_TYPE_IDEN = 11;
/** Current network is EVDO revision B*/
public static final int NETWORK_TYPE_EVDO_B = 12;
+ /** Current network is LTE */
+ public static final int NETWORK_TYPE_LTE = 13;
+ /** Current network is eHRPD */
+ public static final int NETWORK_TYPE_EHRPD = 14;
/**
* Returns a constant indicating the radio technology (network type)
- * currently in use on the device.
+ * currently in use on the device for data transmission.
* @return the network type
*
* @see #NETWORK_TYPE_UNKNOWN
@@ -412,6 +420,9 @@ public class TelephonyManager {
* @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
*/
public int getNetworkType() {
try{
@@ -462,6 +473,10 @@ public class TelephonyManager {
return "CDMA - EvDo rev. B";
case NETWORK_TYPE_1xRTT:
return "CDMA - 1xRTT";
+ case NETWORK_TYPE_LTE:
+ return "LTE";
+ case NETWORK_TYPE_EHRPD:
+ return "CDMA - eHRPD";
default:
return "UNKNOWN";
}
@@ -787,6 +802,10 @@ public class TelephonyManager {
}
}
+ /** Data connection state: Unknown. Used before we know the state.
+ * @hide
+ */
+ public static final int DATA_UNKNOWN = -1;
/** Data connection state: Disconnected. IP traffic not available. */
public static final int DATA_DISCONNECTED = 0;
/** Data connection state: Currently setting up a data connection. */
@@ -912,4 +931,25 @@ public class TelephonyManager {
return null;
}
}
+
+ /**
+ * @return true if the current device is "voice capable".
+ * <p>
+ * "Voice capable" means that this device supports circuit-switched
+ * (i.e. voice) phone calls over the telephony network, and is allowed
+ * to display the in-call UI while a cellular voice call is active.
+ * This will be false on "data only" devices which can't make voice
+ * calls and don't support any in-call UI.
+ * <p>
+ * Note: the meaning of this flag is subtly different from the
+ * PackageManager.FEATURE_TELEPHONY system feature, which is available
+ * on any device with a telephony radio, even if the device is
+ * data-only.
+ *
+ * @hide pending API review
+ */
+ public boolean isVoiceCapable() {
+ return mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_voice_capable);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index f7506c6..82fcb6a 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -71,6 +71,7 @@ public class CallerInfo {
*/
public String name;
public String phoneNumber;
+ public String nomalizedNumber;
public String cnapName;
public int numberPresentation;
@@ -151,6 +152,12 @@ public class CallerInfo {
info.phoneNumber = cursor.getString(columnIndex);
}
+ // Look for the normalized number
+ columnIndex = cursor.getColumnIndex(PhoneLookup.NORMALIZED_NUMBER);
+ if (columnIndex != -1) {
+ info.nomalizedNumber = cursor.getString(columnIndex);
+ }
+
// Look for the label/type combo
columnIndex = cursor.getColumnIndex(PhoneLookup.LABEL);
if (columnIndex != -1) {
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index 79bb832..c47e076 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -20,6 +20,7 @@ import android.content.AsyncQueryHandler;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
+import android.location.CountryDetector;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
@@ -240,7 +241,11 @@ public class CallerInfoAsyncQuery {
// Use the number entered by the user for display.
if (!TextUtils.isEmpty(cw.number)) {
- mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number);
+ CountryDetector detector = (CountryDetector) mQueryContext.getSystemService(
+ Context.COUNTRY_DETECTOR);
+ mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number,
+ mCallerInfo.nomalizedNumber,
+ detector.detectCountry().getCountryIso());
}
}
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 5de0426..27a4dca 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -27,8 +27,8 @@ import android.os.Handler;
*/
public interface CommandsInterface {
enum RadioState {
- RADIO_OFF, /* Radio explictly powered off (eg CFUN=0) */
- RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */
+ RADIO_OFF, /* Radio explicitly powered off (e.g. CFUN=0) */
+ RADIO_UNAVAILABLE, /* Radio unavailable (e.g. resetting or not booted) */
SIM_NOT_READY, /* Radio is on, but the SIM interface is not ready */
SIM_LOCKED_OR_ABSENT, /* SIM PIN locked, PUK required, network
personalization, or SIM absent */
@@ -121,7 +121,7 @@ public interface CommandsInterface {
// See 27.007 +CCFC or +CLCK
static final int SERVICE_CLASS_NONE = 0; // no user input
static final int SERVICE_CLASS_VOICE = (1 << 0);
- static final int SERVICE_CLASS_DATA = (1 << 1); //synoym for 16+32+64+128
+ static final int SERVICE_CLASS_DATA = (1 << 1); //synonym for 16+32+64+128
static final int SERVICE_CLASS_FAX = (1 << 2);
static final int SERVICE_CLASS_SMS = (1 << 3);
static final int SERVICE_CLASS_DATA_SYNC = (1 << 4);
@@ -952,19 +952,19 @@ public interface CommandsInterface {
void writeSmsToRuim(int status, String pdu, Message response);
/**
- * @deprecated
* @param apn
* @param user
* @param password
* @param response
*/
+ @Deprecated
void setupDefaultPDP(String apn, String user, String password, Message response);
/**
- * @deprecated
* @param cid
* @param response
*/
+ @Deprecated
void deactivateDefaultPDP(int cid, Message response);
void setRadioPower(boolean on, Message response);
@@ -974,7 +974,7 @@ public interface CommandsInterface {
void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response);
/**
- * parameters equivilient to 27.007 AT+CRSM command
+ * parameters equivalent to 27.007 AT+CRSM command
* response.obj will be an AsyncResult
* response.obj.userObj will be a IccIoResult on success
*/
@@ -1079,7 +1079,7 @@ public interface CommandsInterface {
/**
* (AsyncResult)response.obj).result will be an Integer representing
- * the sum of enabled serivice classes (sum of SERVICE_CLASS_*)
+ * the sum of enabled service classes (sum of SERVICE_CLASS_*)
*
* @param facility one of CB_FACILTY_*
* @param password password or "" if not required
@@ -1152,7 +1152,7 @@ public interface CommandsInterface {
/**
* Request to enable/disable network state change notifications when
- * location informateion (lac and/or cid) has changed.
+ * location information (lac and/or cid) has changed.
*
* @param enable true to enable, false to disable
* @param response callback message
@@ -1183,7 +1183,7 @@ public interface CommandsInterface {
/**
* Indicates to the vendor ril that StkService is running
- * rand is eady to receive RIL_UNSOL_STK_XXXX commands.
+ * and is ready to receive RIL_UNSOL_STK_XXXX commands.
*
* @param result callback message
*/
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 6634017..c3ad9e6 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -21,11 +21,20 @@ import com.android.internal.telephony.gsm.ApnSetting;
import com.android.internal.util.HierarchicalState;
import com.android.internal.util.HierarchicalStateMachine;
+import android.net.LinkAddress;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
import android.os.AsyncResult;
import android.os.Message;
import android.os.SystemProperties;
import android.util.EventLog;
+import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+
/**
* {@hide}
*
@@ -60,7 +69,7 @@ import android.util.EventLog;
* EVENT_GET_LAST_FAIL_DONE,
* EVENT_DEACTIVATE_DONE.
* }
- * ++ # mInactiveState
+ * ++ # mInactiveState
* e(doNotifications)
* x(clearNotifications) {
* EVENT_RESET { notifiyDisconnectCompleted }.
@@ -252,13 +261,13 @@ public abstract class DataConnection extends HierarchicalStateMachine {
protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
//***** Member Variables
+ protected int mId;
protected int mTag;
protected PhoneBase phone;
+ protected RetryManager mRetryMgr;
protected int cid;
- protected String interfaceName;
- protected String ipAddress;
- protected String gatewayAddress;
- protected String[] dnsServers;
+ protected LinkProperties mLinkProperties = new LinkProperties();
+ protected LinkCapabilities mCapabilities = new LinkCapabilities();
protected long createTime;
protected long lastFailTime;
protected FailCause lastFailCause;
@@ -278,13 +287,12 @@ public abstract class DataConnection extends HierarchicalStateMachine {
//***** Constructor
- protected DataConnection(PhoneBase phone, String name) {
+ protected DataConnection(PhoneBase phone, String name, RetryManager rm) {
super(name);
if (DBG) log("DataConnection constructor E");
this.phone = phone;
+ mRetryMgr = rm;
this.cid = -1;
- this.dnsServers = new String[2];
-
clearSettings();
setDbg(false);
@@ -353,8 +361,8 @@ public abstract class DataConnection extends HierarchicalStateMachine {
if (dp.onCompletedMsg != null) {
Message msg = dp.onCompletedMsg;
- log(String.format("msg.what=%d msg.obj=%s",
- msg.what, ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
+ log(String.format("msg=%s msg.obj=%s", msg.toString(),
+ ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
AsyncResult.forMessage(msg);
msg.sendToTarget();
}
@@ -367,6 +375,10 @@ public abstract class DataConnection extends HierarchicalStateMachine {
clearSettings();
}
+ public RetryManager getRetryMgr() {
+ return mRetryMgr;
+ }
+
/**
* Clear all settings called when entering mInactiveState.
*/
@@ -377,11 +389,7 @@ public abstract class DataConnection extends HierarchicalStateMachine {
this.lastFailTime = -1;
this.lastFailCause = FailCause.NONE;
- interfaceName = null;
- ipAddress = null;
- gatewayAddress = null;
- dnsServers[0] = null;
- dnsServers[1] = null;
+ mLinkProperties = new LinkProperties();
}
/**
@@ -416,35 +424,67 @@ public abstract class DataConnection extends HierarchicalStateMachine {
// for (int i = 0; i < response.length; i++) {
// log(" response[" + i + "]='" + response[i] + "'");
// }
+
+ // Start with clean network properties and if we have
+ // a failure we'll clear again at the bottom of this code.
+ LinkProperties linkProperties = new LinkProperties();
if (response.length >= 2) {
cid = Integer.parseInt(response[0]);
- interfaceName = response[1];
- if (response.length > 2) {
- ipAddress = response[2];
+ String interfaceName = response[1];
+ result = SetupResult.SUCCESS;
+
+ try {
String prefix = "net." + interfaceName + ".";
- gatewayAddress = SystemProperties.get(prefix + "gw");
+
+ NetworkInterface networkInterface = NetworkInterface.getByName(interfaceName);
+ linkProperties.setInterfaceName(interfaceName);
+
+ // TODO: Get gateway and dns via RIL interface not property?
+ String gatewayAddress = SystemProperties.get(prefix + "gw");
+ linkProperties.setGateway(InetAddress.getByName(gatewayAddress));
+
+ for (InterfaceAddress addr : networkInterface.getInterfaceAddresses()) {
+ linkProperties.addLinkAddress(new LinkAddress(addr));
+ }
+ // TODO: Get gateway and dns via RIL interface not property?
+ String dnsServers[] = new String[2];
dnsServers[0] = SystemProperties.get(prefix + "dns1");
dnsServers[1] = SystemProperties.get(prefix + "dns2");
- if (DBG) {
- log("interface=" + interfaceName + " ipAddress=" + ipAddress
- + " gateway=" + gatewayAddress + " DNS1=" + dnsServers[0]
- + " DNS2=" + dnsServers[1]);
- }
-
if (isDnsOk(dnsServers)) {
- result = SetupResult.SUCCESS;
+ linkProperties.addDns(InetAddress.getByName(dnsServers[0]));
+ linkProperties.addDns(InetAddress.getByName(dnsServers[1]));
} else {
result = SetupResult.ERR_BadDns;
}
- } else {
- result = SetupResult.SUCCESS;
+ } catch (UnknownHostException e1) {
+ log("onSetupCompleted: UnknowHostException " + e1);
+ e1.printStackTrace();
+ result = SetupResult.ERR_Other;
+ } catch (SocketException e2) {
+ log("onSetupCompleted: SocketException " + e2);
+ e2.printStackTrace();
+ result = SetupResult.ERR_Other;
}
} else {
+ log("onSetupCompleted: error; expected number of responses >= 2 was " +
+ response.length);
result = SetupResult.ERR_Other;
}
+
+ // An error occurred so clear properties
+ if (result != SetupResult.SUCCESS) {
+ log("onSetupCompleted with an error clearing LinkProperties");
+ linkProperties.clear();
+ }
+ mLinkProperties = linkProperties;
}
- if (DBG) log("DataConnection setup result='" + result + "' on cid=" + cid);
+ if (DBG) {
+ log("DataConnection setup result='" + result + "' on cid=" + cid);
+ if (result == SetupResult.SUCCESS) {
+ log("LinkProperties: " + mLinkProperties.toString());
+ }
+ }
return result;
}
@@ -606,7 +646,16 @@ public abstract class DataConnection extends HierarchicalStateMachine {
break;
case ERR_BadDns:
// Connection succeeded but DNS info is bad so disconnect
- EventLog.writeEvent(EventLogTags.PDP_BAD_DNS_ADDRESS, dnsServers[0]);
+ StringBuilder dnsAddressesSb = new StringBuilder();
+ for (InetAddress addr : mLinkProperties.getDnses()) {
+ if (dnsAddressesSb.length() != 0) dnsAddressesSb.append(" ");
+ dnsAddressesSb.append(addr.toString());
+ }
+ if (dnsAddressesSb.length() == 0) {
+ dnsAddressesSb.append("no-dns-addresses");
+ }
+ EventLog.writeEvent(EventLogTags.PDP_BAD_DNS_ADDRESS,
+ dnsAddressesSb.toString());
tearDownData(cp);
transitionTo(mDisconnectingBadDnsState);
break;
@@ -815,13 +864,13 @@ public abstract class DataConnection extends HierarchicalStateMachine {
/**
* Connect to the apn and return an AsyncResult in onCompletedMsg.
- * Used for cellular networks that use Acess Point Names (APN) such
+ * Used for cellular networks that use Acesss Point Names (APN) such
* as GSM networks.
*
* @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
* With AsyncResult.userObj set to the original msg.obj,
* AsyncResult.result = FailCause and AsyncResult.exception = Exception().
- * @param apn is the Acces Point Name to connect to
+ * @param apn is the Access Point Name to connect to
*/
public void connect(Message onCompletedMsg, ApnSetting apn) {
sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(apn, onCompletedMsg)));
@@ -873,31 +922,29 @@ public abstract class DataConnection extends HierarchicalStateMachine {
}
/**
- * @return the interface name as a string.
+ * Get the DataConnection ID
*/
- public String getInterface() {
- return interfaceName;
+ public int getDataConnectionId() {
+ return mId;
}
/**
- * @return the ip address as a string.
- */
- public String getIpAddress() {
- return ipAddress;
- }
-
- /**
- * @return the gateway address as a string.
+ * Return the LinkProperties for the connection.
+ *
+ * @return a copy of the LinkProperties, is never null.
*/
- public String getGatewayAddress() {
- return gatewayAddress;
+ public LinkProperties getLinkProperties() {
+ return new LinkProperties(mLinkProperties);
}
/**
- * @return an array of associated DNS addresses.
+ * A capability is an Integer/String pair, the capabilities
+ * are defined in the class LinkSocket#Key.
+ *
+ * @return a copy of this connections capabilities, may be empty but never null.
*/
- public String[] getDnsServers() {
- return dnsServers;
+ public LinkCapabilities getLinkCapabilities() {
+ return new LinkCapabilities(mCapabilities);
}
/**
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 265bf7e..96c90a2 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -16,25 +16,38 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.cdma.CDMAPhone;
+
import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.net.IConnectivityManager;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
-import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* {@hide}
- *
*/
public abstract class DataConnectionTracker extends Handler {
- protected static final boolean DBG = false;
- protected final String LOG_TAG = "DataConnectionTracker";
+ protected static final boolean DBG = true;
/**
* IDLE: ready to start data connection setup, default state
@@ -119,9 +132,10 @@ public abstract class DataConnectionTracker extends Handler {
protected boolean mMasterDataEnabled = true;
protected boolean[] dataEnabled = new boolean[APN_NUM_TYPES];
+
protected int enabledCount = 0;
- /* Currently requested APN type */
+ /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
protected String mRequestedApnType = Phone.APN_TYPE_DEFAULT;
/** Retry configuration: A doubling of retry times from 5secs to 30minutes */
@@ -163,20 +177,27 @@ public abstract class DataConnectionTracker extends Handler {
// represents an invalid IP address
protected static final String NULL_IP = "0.0.0.0";
+ // TODO: See if we can remove INTENT_RECONNECT_ALARM
+ // having to have different values for GSM and
+ // CDMA. If so we can then remove the need for
+ // getActionIntentReconnectAlarm.
+ protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason";
// member variables
- protected PhoneBase phone;
- protected Activity activity = Activity.NONE;
- protected State state = State.IDLE;
+ protected PhoneBase mPhone;
+ protected Activity mActivity = Activity.NONE;
+ protected State mState = State.IDLE;
protected Handler mDataConnectionTracker = null;
- protected long txPkts, rxPkts, sentSinceLastRecv;
- protected int netStatPollPeriod;
+ protected long mTxPkts;
+ protected long mRxPkts;
+ protected long mSentSinceLastRecv;
+ protected int mNetStatPollPeriod;
protected int mNoRecvPollCount = 0;
- protected boolean netStatPollEnabled = false;
+ protected boolean mNetStatPollEnabled = false;
- /** Manage the behavior of data retry after failure */
+ /** Manage the behavior of data retry after failure (TODO: One per connection in the future?) */
protected RetryManager mRetryMgr = new RetryManager();
// wifi connection status will be updated by sticky intent
@@ -186,28 +207,125 @@ public abstract class DataConnectionTracker extends Handler {
protected PendingIntent mReconnectIntent = null;
/** CID of active data connection */
- protected int cidActive;
+ protected int mCidActive;
+
+ /** indication of our availability (preconditions to trysetupData are met) **/
+ protected boolean mAvailability = false;
+
+ // When false we will not auto attach and manully attaching is required.
+ protected boolean mAutoAttachOnCreation = false;
+
+ // State of screen
+ // (TODO: Reconsider tying directly to screen, maybe this is
+ // really a lower power mode")
+ protected boolean mIsScreenOn = true;
+
+ /** The link properties (dns, gateway, ip, etc) */
+ protected LinkProperties mLinkProperties = new LinkProperties();
+
+ /** The link capabilities */
+ protected LinkCapabilities mLinkCapabilities = new LinkCapabilities();
+
+ /** Allows the generation of unique Id's for DataConnection objects */
+ protected AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
+
+ /** The data connections. */
+ protected HashMap<Integer, DataConnection> mDataConnections =
+ new HashMap<Integer, DataConnection>();
+
+ protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
+ {
+ @Override
+ public void onReceive(Context context, Intent intent)
+ {
+ String action = intent.getAction();
+ if (action.equals(Intent.ACTION_SCREEN_ON)) {
+ mIsScreenOn = true;
+ stopNetStatPoll();
+ startNetStatPoll();
+ } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ mIsScreenOn = false;
+ stopNetStatPoll();
+ startNetStatPoll();
+ } else if (action.equals(getActionIntentReconnectAlarm())) {
+ log("Reconnect alarm. Previous state was " + mState);
+
+ String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
+ if (mState == State.FAILED) {
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 0; // tearDown is false
+ msg.obj = reason;
+ sendMessage(msg);
+ }
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
+ } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+ final android.net.NetworkInfo networkInfo = (NetworkInfo)
+ intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+ mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
+ } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+ final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+ WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
+
+ if (!enabled) {
+ // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
+ // quit and won't report disconnected until next enabling.
+ mIsWifiConnected = false;
+ }
+ }
+ }
+ };
- /**
+ /**
* Default constructor
*/
protected DataConnectionTracker(PhoneBase phone) {
super();
- this.phone = phone;
+ mPhone = phone;
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(getActionIntentReconnectAlarm());
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+
+ // TODO: Why is this registering the phone as the receiver of the intent
+ // and not its own handler?
+ mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
+
+ // This preference tells us 1) initial condition for "dataEnabled",
+ // and 2) whether the RIL will setup the baseband to auto-PS attach.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
+ boolean dataEnabledSetting = true;
+ try {
+ dataEnabledSetting = IConnectivityManager.Stub.asInterface(ServiceManager.
+ getService(Context.CONNECTIVITY_SERVICE)).getMobileDataEnabled();
+ } catch (Exception e) {
+ // nothing to do - use the old behavior and leave data on
+ }
+ dataEnabled[APN_DEFAULT_ID] =
+ !sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false) &&
+ dataEnabledSetting;
+ if (dataEnabled[APN_DEFAULT_ID]) {
+ enabledCount++;
+ }
+ mAutoAttachOnCreation = dataEnabled[APN_DEFAULT_ID];
}
- public abstract void dispose();
+ public void dispose() {
+ mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
+ }
public Activity getActivity() {
- return activity;
+ return mActivity;
}
public State getState() {
- return state;
+ return mState;
}
public String getStateInString() {
- switch (state) {
+ switch (mState) {
case IDLE: return "IDLE";
case INITING: return "INIT";
case CONNECTING: return "CING";
@@ -220,6 +338,14 @@ public abstract class DataConnectionTracker extends Handler {
}
/**
+ * @return the data connections
+ */
+ public ArrayList<DataConnection> getAllDataConnections() {
+ /** TODO: change return type to Collection? */
+ return new ArrayList<DataConnection>(mDataConnections.values());
+ }
+
+ /**
* The data connection is expected to be setup while device
* 1. has Icc card
* 2. registered for data service
@@ -235,9 +361,9 @@ public abstract class DataConnectionTracker extends Handler {
// the shared values. If it is not, then update it.
public void setDataOnRoamingEnabled(boolean enabled) {
if (getDataOnRoamingEnabled() != enabled) {
- Settings.Secure.putInt(phone.getContext().getContentResolver(),
+ Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
- if (phone.getServiceState().getRoaming()) {
+ if (mPhone.getServiceState().getRoaming()) {
if (enabled) {
mRetryMgr.resetRetryCount();
}
@@ -246,16 +372,19 @@ public abstract class DataConnectionTracker extends Handler {
}
}
- //Retrieve the data roaming setting from the shared preferences.
+ // Retrieve the data roaming setting from the shared preferences.
public boolean getDataOnRoamingEnabled() {
try {
- return Settings.Secure.getInt(phone.getContext().getContentResolver(),
- Settings.Secure.DATA_ROAMING) > 0;
+ return Settings.Secure.getInt(
+ mPhone.getContext().getContentResolver(), Settings.Secure.DATA_ROAMING) > 0;
} catch (SettingNotFoundException snfe) {
return false;
}
}
+
+ protected abstract String getActionIntentReconnectAlarm();
+
// abstract handler methods
protected abstract boolean onTrySetupData(String reason);
protected abstract void onRoamingOff();
@@ -263,14 +392,14 @@ public abstract class DataConnectionTracker extends Handler {
protected abstract void onRadioAvailable();
protected abstract void onRadioOffOrNotAvailable();
protected abstract void onDataSetupComplete(AsyncResult ar);
- protected abstract void onDisconnectDone(AsyncResult ar);
+ protected abstract void onDisconnectDone(int connId, AsyncResult ar);
protected abstract void onResetDone(AsyncResult ar);
protected abstract void onVoiceCallStarted();
protected abstract void onVoiceCallEnded();
protected abstract void onCleanUpConnection(boolean tearDown, String reason);
@Override
- public void handleMessage (Message msg) {
+ public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_ENABLE_NEW_APN:
@@ -280,7 +409,7 @@ public abstract class DataConnectionTracker extends Handler {
case EVENT_TRY_SETUP_DATA:
String reason = null;
if (msg.obj instanceof String) {
- reason = (String)msg.obj;
+ reason = (String) msg.obj;
}
onTrySetupData(reason);
break;
@@ -305,12 +434,13 @@ public abstract class DataConnectionTracker extends Handler {
break;
case EVENT_DATA_SETUP_COMPLETE:
- cidActive = msg.arg1;
+ mCidActive = msg.arg1;
onDataSetupComplete((AsyncResult) msg.obj);
break;
case EVENT_DISCONNECT_DONE:
- onDisconnectDone((AsyncResult) msg.obj);
+ log("DataConnectoinTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
+ onDisconnectDone(msg.arg1, (AsyncResult) msg.obj);
break;
case EVENT_VOICE_CALL_STARTED:
@@ -323,7 +453,7 @@ public abstract class DataConnectionTracker extends Handler {
case EVENT_CLEAN_UP_CONNECTION:
boolean tearDown = (msg.arg1 == 0) ? false : true;
- onCleanUpConnection(tearDown, (String)msg.obj);
+ onCleanUpConnection(tearDown, (String) msg.obj);
break;
case EVENT_SET_MASTER_DATA_ENABLE:
@@ -343,20 +473,22 @@ public abstract class DataConnectionTracker extends Handler {
/**
* Report the current state of data connectivity (enabled or disabled)
+ *
* @return {@code false} if data connectivity has been explicitly disabled,
- * {@code true} otherwise.
+ * {@code true} otherwise.
*/
public synchronized boolean getDataEnabled() {
- return dataEnabled[APN_DEFAULT_ID];
+ return (mMasterDataEnabled && dataEnabled[APN_DEFAULT_ID]);
}
/**
* Report on whether data connectivity is enabled
+ *
* @return {@code false} if data connectivity has been explicitly disabled,
- * {@code true} otherwise.
+ * {@code true} otherwise.
*/
- public boolean getAnyDataEnabled() {
- return (enabledCount != 0);
+ public synchronized boolean getAnyDataEnabled() {
+ return (mMasterDataEnabled && (enabledCount != 0));
}
protected abstract void startNetStatPoll();
@@ -367,6 +499,8 @@ public abstract class DataConnectionTracker extends Handler {
protected abstract void log(String s);
+ protected abstract void loge(String s);
+
protected int apnTypeToId(String type) {
if (TextUtils.equals(type, Phone.APN_TYPE_DEFAULT)) {
return APN_DEFAULT_ID;
@@ -396,7 +530,7 @@ public abstract class DataConnectionTracker extends Handler {
case APN_HIPRI_ID:
return Phone.APN_TYPE_HIPRI;
default:
- Log.e(LOG_TAG, "Unknown id (" + id + ") in apnIdToType");
+ log("Unknown id (" + id + ") in apnIdToType");
return Phone.APN_TYPE_DEFAULT;
}
}
@@ -409,19 +543,129 @@ public abstract class DataConnectionTracker extends Handler {
protected abstract String getActiveApnString();
- public abstract ArrayList<DataConnection> getAllDataConnections();
+ protected abstract void setState(State s);
- protected abstract String getInterfaceName(String apnType);
+ protected LinkProperties getLinkProperties(String apnType) {
+ int id = apnTypeToId(apnType);
+ if (isApnIdEnabled(id)) {
+ return new LinkProperties(mLinkProperties);
+ } else {
+ return new LinkProperties();
+ }
+ }
- protected abstract String getIpAddress(String apnType);
+ protected LinkCapabilities getLinkCapabilities(String apnType) {
+ int id = apnTypeToId(apnType);
+ if (isApnIdEnabled(id)) {
+ return new LinkCapabilities(mLinkCapabilities);
+ } else {
+ return new LinkCapabilities();
+ }
+ }
- protected abstract String getGateway(String apnType);
+ /**
+ * Return the LinkProperties for the connection.
+ *
+ * @param connection
+ * @return a copy of the LinkProperties, is never null.
+ */
+ protected LinkProperties getLinkProperties(DataConnection connection) {
+ return connection.getLinkProperties();
+ }
- protected abstract String[] getDnsServers(String apnType);
+ /**
+ * A capability is an Integer/String pair, the capabilities
+ * are defined in the class LinkSocket#Key.
+ *
+ * @param connection
+ * @return a copy of this connections capabilities, may be empty but never null.
+ */
+ protected LinkCapabilities getLinkCapabilities(DataConnection connection) {
+ return connection.getLinkCapabilities();
+ }
- protected abstract void setState(State s);
+ // tell all active apns of the current condition
+ protected void notifyDataConnection(String reason) {
+ for (int id = 0; id < APN_NUM_TYPES; id++) {
+ if (dataEnabled[id]) {
+ mPhone.notifyDataConnection(reason, apnIdToType(id));
+ }
+ }
+ notifyDataAvailability(reason);
+ }
- protected synchronized boolean isEnabled(int id) {
+ // a new APN has gone active and needs to send events to catch up with the
+ // current condition
+ private void notifyApnIdUpToCurrent(String reason, int apnId) {
+ switch (mState) {
+ case IDLE:
+ case INITING:
+ break;
+ case CONNECTING:
+ case SCANNING:
+ mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
+ break;
+ case CONNECTED:
+ case DISCONNECTING:
+ mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
+ mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTED);
+ break;
+ }
+ }
+
+ // since we normally don't send info to a disconnected APN, we need to do this specially
+ private void notifyApnIdDisconnected(String reason, int apnId) {
+ mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.DISCONNECTED);
+ }
+
+ // disabled apn's still need avail/unavail notificiations - send them out
+ protected void notifyOffApnsOfAvailability(String reason, boolean availability) {
+ if (mAvailability == availability) return;
+ mAvailability = availability;
+ for (int id = 0; id < APN_NUM_TYPES; id++) {
+ if (!isApnIdEnabled(id)) {
+ notifyApnIdDisconnected(reason, id);
+ }
+ }
+ }
+
+ // we had an availability change - tell the listeners
+ protected void notifyDataAvailability(String reason) {
+ // note that we either just turned all off because we lost availability
+ // or all were off and could now go on, so only have off apns to worry about
+ notifyOffApnsOfAvailability(reason, isDataPossible());
+ }
+
+ /**
+ * The only circumstances under which we report that data connectivity is not
+ * possible are
+ * <ul>
+ * <li>Data is disallowed (roaming, power state, voice call, etc).</li>
+ * <li>The current data state is {@code DISCONNECTED} for a reason other than
+ * having explicitly disabled connectivity. In other words, data is not available
+ * because the phone is out of coverage or some like reason.</li>
+ * </ul>
+ * @return {@code true} if data connectivity is possible, {@code false} otherwise.
+ */
+ protected boolean isDataPossible() {
+ boolean possible = (isDataAllowed()
+ && !(getDataEnabled() && (mState == State.FAILED || mState == State.IDLE)));
+ if (!possible && DBG && isDataAllowed()) {
+ log("Data not possible. No coverage: dataState = " + mState);
+ }
+ return possible;
+ }
+
+ protected abstract boolean isDataAllowed();
+
+ public boolean isApnTypeEnabled(String apnType) {
+ if (apnType == null) {
+ apnType = getActiveApnString();
+ }
+ return isApnIdEnabled(apnTypeToId(apnType));
+ }
+
+ protected synchronized boolean isApnIdEnabled(int id) {
if (id != APN_INVALID_ID) {
return dataEnabled[id];
}
@@ -430,13 +674,13 @@ public abstract class DataConnectionTracker extends Handler {
/**
* Ensure that we are connected to an APN of the specified type.
- * @param type the APN type (currently the only valid values
- * are {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL})
- * @return the result of the operation. Success is indicated by
- * a return value of either {@code Phone.APN_ALREADY_ACTIVE} or
- * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a broadcast
- * will be sent by the ConnectivityManager when a connection to
- * the APN has been established.
+ *
+ * @param type the APN type (currently the only valid values are
+ * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL})
+ * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
+ * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
+ * broadcast will be sent by the ConnectivityManager when a
+ * connection to the APN has been established.
*/
public synchronized int enableApnType(String type) {
int id = apnTypeToId(type);
@@ -444,41 +688,45 @@ public abstract class DataConnectionTracker extends Handler {
return Phone.APN_REQUEST_FAILED;
}
- if (DBG) Log.d(LOG_TAG, "enableApnType("+type+"), isApnTypeActive = "
- + isApnTypeActive(type) + " and state = " + state);
+ if (DBG) {
+ log("enableApnType(" + type + "), isApnTypeActive = " + isApnTypeActive(type)
+ + ", isApnIdEnabled =" + isApnIdEnabled(id) + " and state = " + mState);
+ }
if (!isApnTypeAvailable(type)) {
- if (DBG) Log.d(LOG_TAG, "type not available");
+ if (DBG) log("type not available");
return Phone.APN_TYPE_NOT_AVAILABLE;
}
- // just because it's active doesn't mean we had it explicitly requested before
- // (a broad default may handle many types). make sure we mark it enabled
- // so if the default is disabled we keep the connection for others
- setEnabled(id, true);
-
- if (isApnTypeActive(type)) {
- if (state == State.INITING) return Phone.APN_REQUEST_STARTED;
- else if (state == State.CONNECTED) return Phone.APN_ALREADY_ACTIVE;
+ if (isApnIdEnabled(id)) {
+ return Phone.APN_ALREADY_ACTIVE;
+ } else {
+ setEnabled(id, true);
}
return Phone.APN_REQUEST_STARTED;
}
/**
- * The APN of the specified type is no longer needed. Ensure that if
- * use of the default APN has not been explicitly disabled, we are connected
- * to the default APN.
+ * The APN of the specified type is no longer needed. Ensure that if use of
+ * the default APN has not been explicitly disabled, we are connected to the
+ * default APN.
+ *
* @param type the APN type. The only valid values are currently
- * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}.
- * @return
+ * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}.
+ * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
+ * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
+ * broadcast will be sent by the ConnectivityManager when a
+ * connection to the APN has been disconnected. A {@code
+ * Phone.APN_REQUEST_FAILED} is returned if the type parameter is
+ * invalid or if the apn wasn't enabled.
*/
public synchronized int disableApnType(String type) {
- if (DBG) Log.d(LOG_TAG, "disableApnType("+type+")");
+ if (DBG) log("disableApnType(" + type + ")");
int id = apnTypeToId(type);
if (id == APN_INVALID_ID) {
return Phone.APN_REQUEST_FAILED;
}
- if (isEnabled(id)) {
+ if (isApnIdEnabled(id)) {
setEnabled(id, false);
if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
if (dataEnabled[APN_DEFAULT_ID]) {
@@ -495,9 +743,10 @@ public abstract class DataConnectionTracker extends Handler {
}
private void setEnabled(int id, boolean enable) {
- if (DBG) Log.d(LOG_TAG, "setEnabled(" + id + ", " + enable + ") with old state = " +
- dataEnabled[id] + " and enabledCount = " + enabledCount);
-
+ if (DBG) {
+ log("setEnabled(" + id + ", " + enable + ") with old state = " + dataEnabled[id]
+ + " and enabledCount = " + enabledCount);
+ }
Message msg = obtainMessage(EVENT_ENABLE_NEW_APN);
msg.arg1 = id;
msg.arg2 = (enable ? ENABLED : DISABLED);
@@ -506,10 +755,10 @@ public abstract class DataConnectionTracker extends Handler {
protected synchronized void onEnableApn(int apnId, int enabled) {
if (DBG) {
- Log.d(LOG_TAG, "EVENT_APN_ENABLE_REQUEST " + apnId + ", " + enabled);
- Log.d(LOG_TAG, " dataEnabled = " + dataEnabled[apnId] +
- ", enabledCount = " + enabledCount +
- ", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));
+ log("EVENT_APN_ENABLE_REQUEST apnId=" + apnId + ", apnType=" + apnIdToType(apnId) +
+ ", enabled=" + enabled + ", dataEnabled = " + dataEnabled[apnId] +
+ ", enabledCount = " + enabledCount + ", isApnTypeActive = " +
+ isApnTypeActive(apnIdToType(apnId)));
}
if (enabled == ENABLED) {
if (!dataEnabled[apnId]) {
@@ -520,6 +769,8 @@ public abstract class DataConnectionTracker extends Handler {
if (!isApnTypeActive(type)) {
mRequestedApnType = type;
onEnableNewApn();
+ } else {
+ notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnId);
}
} else {
// disable
@@ -528,8 +779,17 @@ public abstract class DataConnectionTracker extends Handler {
enabledCount--;
if (enabledCount == 0) {
onCleanUpConnection(true, Phone.REASON_DATA_DISABLED);
- } else if (dataEnabled[APN_DEFAULT_ID] == true &&
- !isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
+ }
+
+ // send the disconnect msg manually, since the normal route wont send
+ // it (it's not enabled)
+ notifyApnIdDisconnected(Phone.REASON_DATA_DISABLED, apnId);
+ if (dataEnabled[APN_DEFAULT_ID] == true
+ && !isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
+ // TODO - this is an ugly way to restore the default conn - should be done
+ // by a real contention manager and policy that disconnects the lower pri
+ // stuff as enable requests come in and pops them back on as we disable back
+ // down to the lower pri stuff
mRequestedApnType = Phone.APN_TYPE_DEFAULT;
onEnableNewApn();
}
@@ -547,18 +807,22 @@ public abstract class DataConnectionTracker extends Handler {
}
/**
- * Prevent mobile data connections from being established,
- * or once again allow mobile data connections. If the state
- * toggles, then either tear down or set up data, as
- * appropriate to match the new state.
- * <p>This operation only affects the default APN, and if the same APN is
- * currently being used for MMS traffic, the teardown will not happen
- * even when {@code enable} is {@code false}.</p>
- * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data
+ * Prevent mobile data connections from being established, or once again
+ * allow mobile data connections. If the state toggles, then either tear
+ * down or set up data, as appropriate to match the new state.
+ * <p>
+ * This operation only affects the default APN, and if the same APN is
+ * currently being used for MMS traffic, the teardown will not happen even
+ * when {@code enable} is {@code false}.
+ * </p>
+ *
+ * @param enable indicates whether to enable ({@code true}) or disable (
+ * {@code false}) data
* @return {@code true} if the operation succeeded
*/
public boolean setDataEnabled(boolean enable) {
- if (DBG) Log.d(LOG_TAG, "setDataEnabled(" + enable + ")");
+ if (DBG)
+ log("setDataEnabled(" + enable + ")");
Message msg = obtainMessage(EVENT_SET_MASTER_DATA_ENABLE);
msg.arg1 = (enable ? ENABLED : DISABLED);
@@ -568,15 +832,15 @@ public abstract class DataConnectionTracker extends Handler {
protected void onSetDataEnabled(boolean enable) {
if (mMasterDataEnabled != enable) {
- mMasterDataEnabled = enable;
+ synchronized (this) {
+ mMasterDataEnabled = enable;
+ }
if (enable) {
mRetryMgr.resetRetryCount();
onTrySetupData(Phone.REASON_DATA_ENABLED);
} else {
onCleanUpConnection(true, Phone.REASON_DATA_DISABLED);
- }
+ }
}
}
-
-
}
diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index 057ba0a..52cbd7c 100644
--- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -92,26 +94,41 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
}
}
- public void notifyDataConnection(Phone sender, String reason) {
+ public void notifyDataConnection(Phone sender, String reason, String apnType,
+ Phone.DataState state) {
+ doNotifyDataConnection(sender, reason, apnType, state);
+ }
+
+ private void doNotifyDataConnection(Phone sender, String reason, String apnType,
+ Phone.DataState state) {
+ // TODO
+ // use apnType as the key to which connection we're talking about.
+ // pass apnType back up to fetch particular for this one.
TelephonyManager telephony = TelephonyManager.getDefault();
+ LinkProperties linkProperties = null;
+ LinkCapabilities linkCapabilities = null;
+ if (state == Phone.DataState.CONNECTED) {
+ linkProperties = sender.getLinkProperties(apnType);
+ linkCapabilities = sender.getLinkCapabilities(apnType);
+ }
try {
mRegistry.notifyDataConnection(
- convertDataState(sender.getDataConnectionState()),
+ convertDataState(state),
sender.isDataConnectivityPossible(), reason,
sender.getActiveApn(),
- sender.getActiveApnTypes(),
- sender.getInterfaceName(null),
+ apnType,
+ linkProperties,
+ linkCapabilities,
((telephony!=null) ? telephony.getNetworkType() :
- TelephonyManager.NETWORK_TYPE_UNKNOWN),
- sender.getGateway(null));
+ TelephonyManager.NETWORK_TYPE_UNKNOWN));
} catch (RemoteException ex) {
// system process is dead
}
}
- public void notifyDataConnectionFailed(Phone sender, String reason) {
+ public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) {
try {
- mRegistry.notifyDataConnectionFailed(reason);
+ mRegistry.notifyDataConnectionFailed(reason, apnType);
} catch (RemoteException ex) {
// system process is dead
}
@@ -127,6 +144,14 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
}
}
+ public void notifyOtaspChanged(Phone sender, int otaspMode) {
+ try {
+ mRegistry.notifyOtaspChanged(otaspMode);
+ } catch (RemoteException ex) {
+ // system process is dead
+ }
+ }
+
private void log(String s) {
Log.d(LOG_TAG, "[PhoneNotifier] " + s);
}
diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
index 30ee77c..e42827f 100644
--- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
@@ -16,11 +16,14 @@
package com.android.internal.telephony;
-import android.telephony.SmsMessage;
+import android.text.TextUtils;
import android.util.SparseIntArray;
import android.util.Log;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
/**
* This class implements the character set mapping between
* the GSM SMS 7-bit alphabet specified in TS 23.038 6.2.1
@@ -320,7 +323,7 @@ public class GsmAlphabet {
gsmVal = (0x7f & (pdu[offset + byteOffset] >> shift));
- // if it crosses a byte boundry
+ // if it crosses a byte boundary
if (shift > 1) {
// set msb bits to 0
gsmVal &= 0x7f >> (shift - 1);
@@ -355,6 +358,32 @@ public class GsmAlphabet {
*/
public static String
gsm8BitUnpackedToString(byte[] data, int offset, int length) {
+ return gsm8BitUnpackedToString(data, offset, length, "");
+ }
+
+ /**
+ * Convert a GSM alphabet string that's stored in 8-bit unpacked
+ * format (as it often appears in SIM records) into a String
+ *
+ * Field may be padded with trailing 0xff's. The decode stops
+ * at the first 0xff encountered.
+ *
+ * Additionally, in some country(ex. Korea), there are non-ASCII or MBCS characters.
+ * If a character set is given, characters in data are treat as MBCS.
+ */
+ public static String
+ gsm8BitUnpackedToString(byte[] data, int offset, int length, String characterset) {
+ boolean isMbcs = false;
+ Charset charset = null;
+ ByteBuffer mbcsBuffer = null;
+
+ if (!TextUtils.isEmpty(characterset)
+ && !characterset.equalsIgnoreCase("us-ascii")
+ && Charset.isSupported(characterset)) {
+ isMbcs = true;
+ charset = Charset.forName(characterset);
+ mbcsBuffer = ByteBuffer.allocate(2);
+ }
boolean prevWasEscape;
StringBuilder ret = new StringBuilder(length);
@@ -380,7 +409,15 @@ public class GsmAlphabet {
if (prevWasEscape) {
ret.append((char)gsmExtendedToChar.get(c, ' '));
} else {
- ret.append((char)gsmToChar.get(c, ' '));
+ if (!isMbcs || c < 0x80 || i + 1 >= offset + length) {
+ ret.append((char)gsmToChar.get(c, ' '));
+ } else {
+ // isMbcs must be true. So both mbcsBuffer and charset are initialized.
+ mbcsBuffer.clear();
+ mbcsBuffer.put(data, i++, 2);
+ mbcsBuffer.flip();
+ ret.append(charset.decode(mbcsBuffer).toString());
+ }
}
prevWasEscape = false;
}
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 856d663..082c097 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -32,5 +32,6 @@ oneway interface IPhoneStateListener {
void onDataConnectionStateChanged(int state, int networkType);
void onDataActivity(int direction);
void onSignalStrengthsChanged(in SignalStrength signalStrength);
+ void onOtaspChanged(in int otaspMode);
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 2328717..3c4bb12 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -66,7 +66,7 @@ interface ITelephony {
boolean showCallScreenWithDialpad(boolean showDialpad);
/**
- * End call or go to the Home screen
+ * End call if there is a call in progress, otherwise does nothing.
*
* @return whether it hung up
*/
@@ -239,9 +239,11 @@ interface ITelephony {
String getCdmaEriText();
/**
- * Returns true if CDMA provisioning needs to run.
+ * Returns true if OTA service provisioning needs to run.
+ * Only relevant on some technologies, others will always
+ * return false.
*/
- boolean getCdmaNeedsProvisioning();
+ boolean needsOtaServiceProvisioning();
/**
* Returns the unread count of voicemails
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 87e4b52..3c83e50 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -17,6 +17,8 @@
package com.android.internal.telephony;
import android.content.Intent;
+import android.net.LinkProperties;
+import android.net.LinkCapabilities;
import android.os.Bundle;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
@@ -32,8 +34,9 @@ interface ITelephonyRegistry {
void notifyCallForwardingChanged(boolean cfi);
void notifyDataActivity(int state);
void notifyDataConnection(int state, boolean isDataConnectivityPossible,
- String reason, String apn, in String[] apnTypes, String interfaceName, int networkType,
- String gateway);
- void notifyDataConnectionFailed(String reason);
+ String reason, String apn, String apnType, in LinkProperties linkProperties,
+ in LinkCapabilities linkCapabilities, int networkType);
+ void notifyDataConnectionFailed(String reason, String apnType);
void notifyCellLocation(in Bundle cellLocation);
+ void notifyOtaspChanged(in int otaspMode);
}
diff --git a/telephony/java/com/android/internal/telephony/IccUtils.java b/telephony/java/com/android/internal/telephony/IccUtils.java
index 957eddd..df579b0 100644
--- a/telephony/java/com/android/internal/telephony/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/IccUtils.java
@@ -16,13 +16,16 @@
package com.android.internal.telephony;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.Log;
import com.android.internal.telephony.GsmAlphabet;
-
import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
/**
* Various methods, useful for dealing with SIM data.
@@ -150,6 +153,9 @@ public class IccUtils {
*/
public static String
adnStringFieldToString(byte[] data, int offset, int length) {
+ if (length == 0) {
+ return "";
+ }
if (length >= 1) {
if (data[offset] == (byte) 0x80) {
int ucslen = (length - 1) / 2;
@@ -225,7 +231,15 @@ public class IccUtils {
return ret.toString();
}
- return GsmAlphabet.gsm8BitUnpackedToString(data, offset, length);
+ Resources resource = Resources.getSystem();
+ String defaultCharset = "";
+ try {
+ defaultCharset =
+ resource.getString(com.android.internal.R.string.gsm_alphabet_default_charset);
+ } catch (NotFoundException e) {
+ // Ignore Exception and defaultCharset is set to a empty string.
+ }
+ return GsmAlphabet.gsm8BitUnpackedToString(data, offset, length, defaultCharset.trim());
}
static int
@@ -267,9 +281,11 @@ public class IccUtils {
/**
- * Converts a byte array into a String hexidecimal characters
+ * Converts a byte array into a String of hexadecimal characters.
+ *
+ * @param bytes an array of bytes
*
- * null returns null
+ * @return hex string representation of bytes array
*/
public static String
bytesToHexString(byte[] bytes) {
diff --git a/telephony/java/com/android/internal/telephony/MccTable.java b/telephony/java/com/android/internal/telephony/MccTable.java
index 5539057..c0bf7ec 100644
--- a/telephony/java/com/android/internal/telephony/MccTable.java
+++ b/telephony/java/com/android/internal/telephony/MccTable.java
@@ -23,346 +23,13 @@ import android.content.res.Configuration;
import android.net.wifi.WifiManager;
import android.os.RemoteException;
import android.os.SystemProperties;
-import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
-import java.util.Arrays;
-
-/**
- * The table below is built from two resources:
- *
- * 1) ITU "Mobile Network Code (MNC) for the international
- * identification plan for mobile terminals and mobile users"
- * which is available as an annex to the ITU operational bulletin
- * available here: http://www.itu.int/itu-t/bulletin/annex.html
- *
- * 2) The ISO 3166 country codes list, available here:
- * http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
- *
- * This table was verified (28 Aug 2009) against
- * http://en.wikipedia.org/wiki/List_of_mobile_country_codes with the
- * only unresolved discrepancy being that this list has an extra entry
- * (461) for China.
- *
- * TODO: Complete the mappings for timezones and language/locale codes.
- *
- * The actual table data used in the Java code is generated from the
- * below Python code for efficiency. The information is expected to
- * be static, but if changes are required, the table in the python
- * code can be modified and the trailing code run to re-generate the
- * tables that are to be used by Java.
-
-mcc_table = [
- (202, 'gr', 2, 'Greece'),
- (204, 'nl', 2, 'Europe/Amsterdam', 'nl', 13, 'Netherlands (Kingdom of the)'),
- (206, 'be', 2, 'Belgium'),
- (208, 'fr', 2, 'Europe/Paris', 'fr', 'France'),
- (212, 'mc', 2, 'Monaco (Principality of)'),
- (213, 'ad', 2, 'Andorra (Principality of)'),
- (214, 'es', 2, 'Europe/Madrid', 'es', 'Spain'),
- (216, 'hu', 2, 'Hungary (Republic of)'),
- (218, 'ba', 2, 'Bosnia and Herzegovina'),
- (219, 'hr', 2, 'Croatia (Republic of)'),
- (220, 'rs', 2, 'Serbia and Montenegro'),
- (222, 'it', 2, 'Europe/Rome', 'it', 'Italy'),
- (225, 'va', 2, 'Europe/Rome', 'it', 'Vatican City State'),
- (226, 'ro', 2, 'Romania'),
- (228, 'ch', 2, 'Europe/Zurich', 'de', 'Switzerland (Confederation of)'),
- (230, 'cz', 2, 'Europe/Prague', 'cs', 13, 'Czech Republic'),
- (231, 'sk', 2, 'Slovak Republic'),
- (232, 'at', 2, 'Europe/Vienna', 'de', 13, 'Austria'),
- (234, 'gb', 2, 'Europe/London', 'en', 13, 'United Kingdom of Great Britain and Northern Ireland'),
- (235, 'gb', 2, 'Europe/London', 'en', 13, 'United Kingdom of Great Britain and Northern Ireland'),
- (238, 'dk', 2, 'Denmark'),
- (240, 'se', 2, 'Sweden'),
- (242, 'no', 2, 'Norway'),
- (244, 'fi', 2, 'Finland'),
- (246, 'lt', 2, 'Lithuania (Republic of)'),
- (247, 'lv', 2, 'Latvia (Republic of)'),
- (248, 'ee', 2, 'Estonia (Republic of)'),
- (250, 'ru', 2, 'Russian Federation'),
- (255, 'ua', 2, 'Ukraine'),
- (257, 'by', 2, 'Belarus (Republic of)'),
- (259, 'md', 2, 'Moldova (Republic of)'),
- (260, 'pl', 2, 'Europe/Warsaw', 'Poland (Republic of)'),
- (262, 'de', 2, 'Europe/Berlin', 'de', 13, 'Germany (Federal Republic of)'),
- (266, 'gi', 2, 'Gibraltar'),
- (268, 'pt', 2, 'Portugal'),
- (270, 'lu', 2, 'Luxembourg'),
- (272, 'ie', 2, 'Europe/Dublin', 'en', 'Ireland'),
- (274, 'is', 2, 'Iceland'),
- (276, 'al', 2, 'Albania (Republic of)'),
- (278, 'mt', 2, 'Malta'),
- (280, 'cy', 2, 'Cyprus (Republic of)'),
- (282, 'ge', 2, 'Georgia'),
- (283, 'am', 2, 'Armenia (Republic of)'),
- (284, 'bg', 2, 'Bulgaria (Republic of)'),
- (286, 'tr', 2, 'Turkey'),
- (288, 'fo', 2, 'Faroe Islands'),
- (289, 'ge', 2, 'Abkhazia (Georgia)'),
- (290, 'gl', 2, 'Greenland (Denmark)'),
- (292, 'sm', 2, 'San Marino (Republic of)'),
- (293, 'sl', 2, 'Slovenia (Republic of)'),
- (294, 'mk', 2, 'The Former Yugoslav Republic of Macedonia'),
- (295, 'li', 2, 'Liechtenstein (Principality of)'),
- (297, 'me', 2, 'Montenegro (Republic of)'),
- (302, 'ca', 3, '', '', 11, 'Canada'),
- (308, 'pm', 2, 'Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)'),
- (310, 'us', 3, '', 'en', 11, 'United States of America'),
- (311, 'us', 3, '', 'en', 11, 'United States of America'),
- (312, 'us', 3, '', 'en', 11, 'United States of America'),
- (313, 'us', 3, '', 'en', 11, 'United States of America'),
- (314, 'us', 3, '', 'en', 11, 'United States of America'),
- (315, 'us', 3, '', 'en', 11, 'United States of America'),
- (316, 'us', 3, '', 'en', 11, 'United States of America'),
- (330, 'pr', 2, 'Puerto Rico'),
- (332, 'vi', 2, 'United States Virgin Islands'),
- (334, 'mx', 3, 'Mexico'),
- (338, 'jm', 3, 'Jamaica'),
- (340, 'gp', 2, 'Guadeloupe (French Department of)'),
- (342, 'bb', 3, 'Barbados'),
- (344, 'ag', 3, 'Antigua and Barbuda'),
- (346, 'ky', 3, 'Cayman Islands'),
- (348, 'vg', 3, 'British Virgin Islands'),
- (350, 'bm', 2, 'Bermuda'),
- (352, 'gd', 2, 'Grenada'),
- (354, 'ms', 2, 'Montserrat'),
- (356, 'kn', 2, 'Saint Kitts and Nevis'),
- (358, 'lc', 2, 'Saint Lucia'),
- (360, 'vc', 2, 'Saint Vincent and the Grenadines'),
- (362, 'nl', 2, 'Netherlands Antilles'),
- (363, 'aw', 2, 'Aruba'),
- (364, 'bs', 2, 'Bahamas (Commonwealth of the)'),
- (365, 'ai', 3, 'Anguilla'),
- (366, 'dm', 2, 'Dominica (Commonwealth of)'),
- (368, 'cu', 2, 'Cuba'),
- (370, 'do', 2, 'Dominican Republic'),
- (372, 'ht', 2, 'Haiti (Republic of)'),
- (374, 'tt', 2, 'Trinidad and Tobago'),
- (376, 'tc', 2, 'Turks and Caicos Islands'),
- (400, 'az', 2, 'Azerbaijani Republic'),
- (401, 'kz', 2, 'Kazakhstan (Republic of)'),
- (402, 'bt', 2, 'Bhutan (Kingdom of)'),
- (404, 'in', 2, 'India (Republic of)'),
- (405, 'in', 2, 'India (Republic of)'),
- (410, 'pk', 2, 'Pakistan (Islamic Republic of)'),
- (412, 'af', 2, 'Afghanistan'),
- (413, 'lk', 2, 'Sri Lanka (Democratic Socialist Republic of)'),
- (414, 'mm', 2, 'Myanmar (Union of)'),
- (415, 'lb', 2, 'Lebanon'),
- (416, 'jo', 2, 'Jordan (Hashemite Kingdom of)'),
- (417, 'sy', 2, 'Syrian Arab Republic'),
- (418, 'iq', 2, 'Iraq (Republic of)'),
- (419, 'kw', 2, 'Kuwait (State of)'),
- (420, 'sa', 2, 'Saudi Arabia (Kingdom of)'),
- (421, 'ye', 2, 'Yemen (Republic of)'),
- (422, 'om', 2, 'Oman (Sultanate of)'),
- (423, 'ps', 2, 'Palestine'),
- (424, 'ae', 2, 'United Arab Emirates'),
- (425, 'il', 2, 'Israel (State of)'),
- (426, 'bh', 2, 'Bahrain (Kingdom of)'),
- (427, 'qa', 2, 'Qatar (State of)'),
- (428, 'mn', 2, 'Mongolia'),
- (429, 'np', 2, 'Nepal'),
- (430, 'ae', 2, 'United Arab Emirates'),
- (431, 'ae', 2, 'United Arab Emirates'),
- (432, 'ir', 2, 'Iran (Islamic Republic of)'),
- (434, 'uz', 2, 'Uzbekistan (Republic of)'),
- (436, 'tj', 2, 'Tajikistan (Republic of)'),
- (437, 'kg', 2, 'Kyrgyz Republic'),
- (438, 'tm', 2, 'Turkmenistan'),
- (440, 'jp', 2, 'Asia/Tokyo', 'ja', 14, 'Japan'),
- (441, 'jp', 2, 'Asia/Tokyo', 'ja', 14, 'Japan'),
- (450, 'kr', 2, 'Asia/Seoul', 'ko', 13, 'Korea (Republic of)'),
- (452, 'vn', 2, 'Viet Nam (Socialist Republic of)'),
- (454, 'hk', 2, '"Hong Kong, China"'),
- (455, 'mo', 2, '"Macao, China"'),
- (456, 'kh', 2, 'Cambodia (Kingdom of)'),
- (457, 'la', 2, "Lao People's Democratic Republic"),
- (460, 'cn', 2, "Asia/Beijing", 'zh', 13, "China (People's Republic of)"),
- (461, 'cn', 2, "Asia/Beijing", 'zh', 13, "China (People's Republic of)"),
- (466, 'tw', 2, "Taiwan (Republic of China)"),
- (467, 'kp', 2, "Democratic People's Republic of Korea"),
- (470, 'bd', 2, "Bangladesh (People's Republic of)"),
- (472, 'mv', 2, 'Maldives (Republic of)'),
- (502, 'my', 2, 'Malaysia'),
- (505, 'au', 2, 'Australia/Sydney', 'en', 11, 'Australia'),
- (510, 'id', 2, 'Indonesia (Republic of)'),
- (514, 'tl', 2, 'Democratic Republic of Timor-Leste'),
- (515, 'ph', 2, 'Philippines (Republic of the)'),
- (520, 'th', 2, 'Thailand'),
- (525, 'sg', 2, 'Asia/Singapore', 'en', 11, 'Singapore (Republic of)'),
- (528, 'bn', 2, 'Brunei Darussalam'),
- (530, 'nz', 2, 'Pacific/Auckland', 'en', 'New Zealand'),
- (534, 'mp', 2, 'Northern Mariana Islands (Commonwealth of the)'),
- (535, 'gu', 2, 'Guam'),
- (536, 'nr', 2, 'Nauru (Republic of)'),
- (537, 'pg', 2, 'Papua New Guinea'),
- (539, 'to', 2, 'Tonga (Kingdom of)'),
- (540, 'sb', 2, 'Solomon Islands'),
- (541, 'vu', 2, 'Vanuatu (Republic of)'),
- (542, 'fj', 2, 'Fiji (Republic of)'),
- (543, 'wf', 2, "Wallis and Futuna (Territoire franais d'outre-mer)"),
- (544, 'as', 2, 'American Samoa'),
- (545, 'ki', 2, 'Kiribati (Republic of)'),
- (546, 'nc', 2, "New Caledonia (Territoire franais d'outre-mer)"),
- (547, 'pf', 2, "French Polynesia (Territoire franais d'outre-mer)"),
- (548, 'ck', 2, 'Cook Islands'),
- (549, 'ws', 2, 'Samoa (Independent State of)'),
- (550, 'fm', 2, 'Micronesia (Federated States of)'),
- (551, 'mh', 2, 'Marshall Islands (Republic of the)'),
- (552, 'pw', 2, 'Palau (Republic of)'),
- (602, 'eg', 2, 'Egypt (Arab Republic of)'),
- (603, 'dz', 2, "Algeria (People's Democratic Republic of)"),
- (604, 'ma', 2, 'Morocco (Kingdom of)'),
- (605, 'tn', 2, 'Tunisia'),
- (606, 'ly', 2, "Libya (Socialist People's Libyan Arab Jamahiriya)"),
- (607, 'gm', 2, 'Gambia (Republic of the)'),
- (608, 'sn', 2, 'Senegal (Republic of)'),
- (609, 'mr', 2, 'Mauritania (Islamic Republic of)'),
- (610, 'ml', 2, 'Mali (Republic of)'),
- (611, 'gn', 2, 'Guinea (Republic of)'),
- (612, 'ci', 2, "Cte d'Ivoire (Republic of)"),
- (613, 'bf', 2, 'Burkina Faso'),
- (614, 'ne', 2, 'Niger (Republic of the)'),
- (615, 'tg', 2, 'Togolese Republic'),
- (616, 'bj', 2, 'Benin (Republic of)'),
- (617, 'mu', 2, 'Mauritius (Republic of)'),
- (618, 'lr', 2, 'Liberia (Republic of)'),
- (619, 'sl', 2, 'Sierra Leone'),
- (620, 'gh', 2, 'Ghana'),
- (621, 'ng', 2, 'Nigeria (Federal Republic of)'),
- (622, 'td', 2, 'Chad (Republic of)'),
- (623, 'cf', 2, 'Central African Republic'),
- (624, 'cm', 2, 'Cameroon (Republic of)'),
- (625, 'cv', 2, 'Cape Verde (Republic of)'),
- (626, 'st', 2, 'Sao Tome and Principe (Democratic Republic of)'),
- (627, 'gq', 2, 'Equatorial Guinea (Republic of)'),
- (628, 'ga', 2, 'Gabonese Republic'),
- (629, 'cg', 2, 'Congo (Republic of the)'),
- (630, 'cg', 2, 'Democratic Republic of the Congo'),
- (631, 'ao', 2, 'Angola (Republic of)'),
- (632, 'gw', 2, 'Guinea-Bissau (Republic of)'),
- (633, 'sc', 2, 'Seychelles (Republic of)'),
- (634, 'sd', 2, 'Sudan (Republic of the)'),
- (635, 'rw', 2, 'Rwanda (Republic of)'),
- (636, 'et', 2, 'Ethiopia (Federal Democratic Republic of)'),
- (637, 'so', 2, 'Somali Democratic Republic'),
- (638, 'dj', 2, 'Djibouti (Republic of)'),
- (639, 'ke', 2, 'Kenya (Republic of)'),
- (640, 'tz', 2, 'Tanzania (United Republic of)'),
- (641, 'ug', 2, 'Uganda (Republic of)'),
- (642, 'bi', 2, 'Burundi (Republic of)'),
- (643, 'mz', 2, 'Mozambique (Republic of)'),
- (645, 'zm', 2, 'Zambia (Republic of)'),
- (646, 'mg', 2, 'Madagascar (Republic of)'),
- (647, 're', 2, 'Reunion (French Department of)'),
- (648, 'zw', 2, 'Zimbabwe (Republic of)'),
- (649, 'na', 2, 'Namibia (Republic of)'),
- (650, 'mw', 2, 'Malawi'),
- (651, 'ls', 2, 'Lesotho (Kingdom of)'),
- (652, 'bw', 2, 'Botswana (Republic of)'),
- (653, 'sz', 2, 'Swaziland (Kingdom of)'),
- (654, 'km', 2, 'Comoros (Union of the)'),
- (655, 'za', 2, 'Africa/Johannesburg', 'en', 'South Africa (Republic of)'),
- (657, 'er', 2, 'Eritrea'),
- (702, 'bz', 2, 'Belize'),
- (704, 'gt', 2, 'Guatemala (Republic of)'),
- (706, 'sv', 2, 'El Salvador (Republic of)'),
- (708, 'hn', 3, 'Honduras (Republic of)'),
- (710, 'ni', 2, 'Nicaragua'),
- (712, 'cr', 2, 'Costa Rica'),
- (714, 'pa', 2, 'Panama (Republic of)'),
- (716, 'pe', 2, 'Peru'),
- (722, 'ar', 3, 'Argentine Republic'),
- (724, 'br', 2, 'Brazil (Federative Republic of)'),
- (730, 'cl', 2, 'Chile'),
- (732, 'co', 3, 'Colombia (Republic of)'),
- (734, 've', 2, 'Venezuela (Bolivarian Republic of)'),
- (736, 'bo', 2, 'Bolivia (Republic of)'),
- (738, 'gy', 2, 'Guyana'),
- (740, 'ec', 2, 'Ecuador'),
- (742, 'gf', 2, 'French Guiana (French Department of)'),
- (744, 'py', 2, 'Paraguay (Republic of)'),
- (746, 'sr', 2, 'Suriname (Republic of)'),
- (748, 'uy', 2, 'Uruguay (Eastern Republic of)'),
- (750, 'fk', 2, 'Falkland Islands (Malvinas)')]
-
-get_mcc = lambda elt: elt[0]
-get_iso = lambda elt: elt[1]
-get_sd = lambda elt: elt[2]
-get_tz = lambda elt: len(elt) > 4 and elt[3] or ''
-get_lang = lambda elt: len(elt) > 5 and elt[4] or ''
-get_wifi = lambda elt: len(elt) > 6 and elt[5] or 0
-
-mcc_codes = ['0x%04x' % get_mcc(elt) for elt in mcc_table]
-tz_set = sorted(x for x in set(get_tz(elt) for elt in mcc_table))
-lang_set = sorted(x for x in set(get_lang(elt) for elt in mcc_table))
-
-def mk_ind_code(elt):
- iso = get_iso(elt)
- iso_code = ((ord(iso[0]) << 8) | ord(iso[1])) & 0xFFFF # 16 bits
- wifi = get_wifi(elt) & 0x000F # 4 bits
- sd = get_sd(elt) & 0x0003 # 2 bits
- tz_ind = tz_set.index(get_tz(elt)) & 0x001F # 5 bits
- lang_ind = lang_set.index(get_lang(elt)) & 0x000F # 4 bits
- return (iso_code << 16) | (wifi << 11) | (sd << 9) | (tz_ind << 4) | lang_ind
-
-ind_codes = ['0x%08x' % mk_ind_code(elt) for elt in mcc_table]
-
-def fmt_list(title, l, batch_sz):
- sl = []
- for i in range(len(l) / batch_sz + (len(l) % batch_sz and 1 or 0)):
- j = i * batch_sz
- sl.append((' ' * 8) + ', '.join(l[j:j + batch_sz]))
- return ' private static final %s = {\n' % title + ',\n'.join(sl) + '\n };\n'
-
-def do_autogen_comment(extra_desc=[]):
- print ' /' + '**\n * AUTO GENERATED (by the Python code above)'
- for line in extra_desc:
- print ' * %s' % line
- print ' *' + '/'
-
-do_autogen_comment()
-print fmt_list('String[] TZ_STRINGS', ['"%s"' % x for x in tz_set], 1)
-do_autogen_comment()
-print fmt_list('String[] LANG_STRINGS', ['"%s"' % x for x in lang_set], 10)
-do_autogen_comment(['This table is a list of MCC codes. The index in this table',
- 'of a given MCC code is the index of extra information about',
- 'that MCC in the IND_CODES table.'])
-print fmt_list('short[] MCC_CODES', mcc_codes, 10)
-do_autogen_comment(['The values in this table are broken down as follows (msb to lsb):',
- ' iso country code 16 bits',
- ' (unused) 1 bit',
- ' wifi channel 4 bits',
- ' smalled digit 2 bits',
- ' default timezone 5 bits',
- ' default language 4 bits'])
-print fmt_list('int[] IND_CODES', ind_codes, 6)
-
-def parse_ind_code(ind):
- mcc = eval(mcc_codes[ind])
- code = eval(ind_codes[ind])
- iso_lsb = int((code >> 16) & 0x00FF)
- iso_msb = int((code >> 24) & 0x00FF)
- iso = '%s%s' % (chr(iso_msb), chr(iso_lsb))
- wifi = int((code >> 11) & 0x000F)
- sd = int((code >> 9) & 0x0003)
- tz_ind = (code >> 4) & 0x001F
- lang_ind = (code >> 0) & 0x000F
- return (mcc, iso, sd, tz_set[tz_ind], lang_set[lang_ind], wifi)
-
-fmt_str = 'mcc = %s, iso = %s, sd = %s, tz = %s, lang = %s, wifi = %s'
-orig_table = [fmt_str % (get_mcc(elt), get_iso(elt), get_sd(elt),
- get_tz(elt), get_lang(elt), get_wifi(elt))
- for elt in mcc_table]
-derived_table = [fmt_str % parse_ind_code(i) for i in range(len(ind_codes))]
-for i in range(len(orig_table)):
- if orig_table[i] == derived_table[i]: continue
- print 'MISMATCH ERROR : ', orig_table[i], " != ", derived_table[i]
-
-*/
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Locale;
+import libcore.icu.TimeZones;
/**
* Mobile Country Code
@@ -371,202 +38,130 @@ for i in range(len(orig_table)):
*/
public final class MccTable
{
- /**
- * AUTO GENERATED (by the Python code above)
- */
- private static final String[] TZ_STRINGS = {
- "",
- "Africa/Johannesburg",
- "Asia/Beijing",
- "Asia/Seoul",
- "Asia/Singapore",
- "Asia/Tokyo",
- "Australia/Sydney",
- "Europe/Amsterdam",
- "Europe/Berlin",
- "Europe/Dublin",
- "Europe/London",
- "Europe/Madrid",
- "Europe/Paris",
- "Europe/Prague",
- "Europe/Rome",
- "Europe/Vienna",
- "Europe/Warsaw",
- "Europe/Zurich",
- "Pacific/Auckland"
- };
+ static final String LOG_TAG = "MccTable";
- /**
- * AUTO GENERATED (by the Python code above)
- */
- private static final String[] LANG_STRINGS = {
- "", "cs", "de", "en", "es", "fr", "it", "ja", "ko", "nl",
- "zh"
- };
+ static ArrayList<MccEntry> table;
- /**
- * AUTO GENERATED (by the Python code above)
- * This table is a list of MCC codes. The index in this table
- * of a given MCC code is the index of extra information about
- * that MCC in the IND_CODES table.
- */
- private static final short[] MCC_CODES = {
- 0x00ca, 0x00cc, 0x00ce, 0x00d0, 0x00d4, 0x00d5, 0x00d6, 0x00d8, 0x00da, 0x00db,
- 0x00dc, 0x00de, 0x00e1, 0x00e2, 0x00e4, 0x00e6, 0x00e7, 0x00e8, 0x00ea, 0x00eb,
- 0x00ee, 0x00f0, 0x00f2, 0x00f4, 0x00f6, 0x00f7, 0x00f8, 0x00fa, 0x00ff, 0x0101,
- 0x0103, 0x0104, 0x0106, 0x010a, 0x010c, 0x010e, 0x0110, 0x0112, 0x0114, 0x0116,
- 0x0118, 0x011a, 0x011b, 0x011c, 0x011e, 0x0120, 0x0121, 0x0122, 0x0124, 0x0125,
- 0x0126, 0x0127, 0x0129, 0x012e, 0x0134, 0x0136, 0x0137, 0x0138, 0x0139, 0x013a,
- 0x013b, 0x013c, 0x014a, 0x014c, 0x014e, 0x0152, 0x0154, 0x0156, 0x0158, 0x015a,
- 0x015c, 0x015e, 0x0160, 0x0162, 0x0164, 0x0166, 0x0168, 0x016a, 0x016b, 0x016c,
- 0x016d, 0x016e, 0x0170, 0x0172, 0x0174, 0x0176, 0x0178, 0x0190, 0x0191, 0x0192,
- 0x0194, 0x0195, 0x019a, 0x019c, 0x019d, 0x019e, 0x019f, 0x01a0, 0x01a1, 0x01a2,
- 0x01a3, 0x01a4, 0x01a5, 0x01a6, 0x01a7, 0x01a8, 0x01a9, 0x01aa, 0x01ab, 0x01ac,
- 0x01ad, 0x01ae, 0x01af, 0x01b0, 0x01b2, 0x01b4, 0x01b5, 0x01b6, 0x01b8, 0x01b9,
- 0x01c2, 0x01c4, 0x01c6, 0x01c7, 0x01c8, 0x01c9, 0x01cc, 0x01cd, 0x01d2, 0x01d3,
- 0x01d6, 0x01d8, 0x01f6, 0x01f9, 0x01fe, 0x0202, 0x0203, 0x0208, 0x020d, 0x0210,
- 0x0212, 0x0216, 0x0217, 0x0218, 0x0219, 0x021b, 0x021c, 0x021d, 0x021e, 0x021f,
- 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0226, 0x0227, 0x0228, 0x025a,
- 0x025b, 0x025c, 0x025d, 0x025e, 0x025f, 0x0260, 0x0261, 0x0262, 0x0263, 0x0264,
- 0x0265, 0x0266, 0x0267, 0x0268, 0x0269, 0x026a, 0x026b, 0x026c, 0x026d, 0x026e,
- 0x026f, 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, 0x0278,
- 0x0279, 0x027a, 0x027b, 0x027c, 0x027d, 0x027e, 0x027f, 0x0280, 0x0281, 0x0282,
- 0x0283, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028a, 0x028b, 0x028c, 0x028d,
- 0x028e, 0x028f, 0x0291, 0x02be, 0x02c0, 0x02c2, 0x02c4, 0x02c6, 0x02c8, 0x02ca,
- 0x02cc, 0x02d2, 0x02d4, 0x02da, 0x02dc, 0x02de, 0x02e0, 0x02e2, 0x02e4, 0x02e6,
- 0x02e8, 0x02ea, 0x02ec, 0x02ee
- };
+ static class MccEntry implements Comparable<MccEntry>
+ {
+ int mcc;
+ String iso;
+ int smallestDigitsMnc;
+ String language;
- /**
- * AUTO GENERATED (by the Python code above)
- * The values in this table are broken down as follows (msb to lsb):
- * iso country code 16 bits
- * (unused) 1 bit
- * wifi channel 4 bits
- * smalled digit 2 bits
- * default timezone 5 bits
- * default language 4 bits
- */
- private static final int[] IND_CODES = {
- 0x67720400, 0x6e6c6c79, 0x62650400, 0x667204c5, 0x6d630400, 0x61640400,
- 0x657304b4, 0x68750400, 0x62610400, 0x68720400, 0x72730400, 0x697404e6,
- 0x766104e6, 0x726f0400, 0x63680512, 0x637a6cd1, 0x736b0400, 0x61746cf2,
- 0x67626ca3, 0x67626ca3, 0x646b0400, 0x73650400, 0x6e6f0400, 0x66690400,
- 0x6c740400, 0x6c760400, 0x65650400, 0x72750400, 0x75610400, 0x62790400,
- 0x6d640400, 0x706c0500, 0x64656c82, 0x67690400, 0x70740400, 0x6c750400,
- 0x69650493, 0x69730400, 0x616c0400, 0x6d740400, 0x63790400, 0x67650400,
- 0x616d0400, 0x62670400, 0x74720400, 0x666f0400, 0x67650400, 0x676c0400,
- 0x736d0400, 0x736c0400, 0x6d6b0400, 0x6c690400, 0x6d650400, 0x63615e00,
- 0x706d0400, 0x75735e03, 0x75735e03, 0x75735e03, 0x75735e03, 0x75735e03,
- 0x75735e03, 0x75735e03, 0x70720400, 0x76690400, 0x6d780600, 0x6a6d0600,
- 0x67700400, 0x62620600, 0x61670600, 0x6b790600, 0x76670600, 0x626d0400,
- 0x67640400, 0x6d730400, 0x6b6e0400, 0x6c630400, 0x76630400, 0x6e6c0400,
- 0x61770400, 0x62730400, 0x61690600, 0x646d0400, 0x63750400, 0x646f0400,
- 0x68740400, 0x74740400, 0x74630400, 0x617a0400, 0x6b7a0400, 0x62740400,
- 0x696e0400, 0x696e0400, 0x706b0400, 0x61660400, 0x6c6b0400, 0x6d6d0400,
- 0x6c620400, 0x6a6f0400, 0x73790400, 0x69710400, 0x6b770400, 0x73610400,
- 0x79650400, 0x6f6d0400, 0x70730400, 0x61650400, 0x696c0400, 0x62680400,
- 0x71610400, 0x6d6e0400, 0x6e700400, 0x61650400, 0x61650400, 0x69720400,
- 0x757a0400, 0x746a0400, 0x6b670400, 0x746d0400, 0x6a707457, 0x6a707457,
- 0x6b726c38, 0x766e0400, 0x686b0400, 0x6d6f0400, 0x6b680400, 0x6c610400,
- 0x636e6c2a, 0x636e6c2a, 0x74770400, 0x6b700400, 0x62640400, 0x6d760400,
- 0x6d790400, 0x61755c63, 0x69640400, 0x746c0400, 0x70680400, 0x74680400,
- 0x73675c43, 0x626e0400, 0x6e7a0523, 0x6d700400, 0x67750400, 0x6e720400,
- 0x70670400, 0x746f0400, 0x73620400, 0x76750400, 0x666a0400, 0x77660400,
- 0x61730400, 0x6b690400, 0x6e630400, 0x70660400, 0x636b0400, 0x77730400,
- 0x666d0400, 0x6d680400, 0x70770400, 0x65670400, 0x647a0400, 0x6d610400,
- 0x746e0400, 0x6c790400, 0x676d0400, 0x736e0400, 0x6d720400, 0x6d6c0400,
- 0x676e0400, 0x63690400, 0x62660400, 0x6e650400, 0x74670400, 0x626a0400,
- 0x6d750400, 0x6c720400, 0x736c0400, 0x67680400, 0x6e670400, 0x74640400,
- 0x63660400, 0x636d0400, 0x63760400, 0x73740400, 0x67710400, 0x67610400,
- 0x63670400, 0x63670400, 0x616f0400, 0x67770400, 0x73630400, 0x73640400,
- 0x72770400, 0x65740400, 0x736f0400, 0x646a0400, 0x6b650400, 0x747a0400,
- 0x75670400, 0x62690400, 0x6d7a0400, 0x7a6d0400, 0x6d670400, 0x72650400,
- 0x7a770400, 0x6e610400, 0x6d770400, 0x6c730400, 0x62770400, 0x737a0400,
- 0x6b6d0400, 0x7a610413, 0x65720400, 0x627a0400, 0x67740400, 0x73760400,
- 0x686e0600, 0x6e690400, 0x63720400, 0x70610400, 0x70650400, 0x61720600,
- 0x62720400, 0x636c0400, 0x636f0600, 0x76650400, 0x626f0400, 0x67790400,
- 0x65630400, 0x67660400, 0x70790400, 0x73720400, 0x75790400, 0x666b0400
- };
+ MccEntry(int mnc, String iso, int smallestDigitsMCC) {
+ this(mnc, iso, smallestDigitsMCC, null);
+ }
- static final String LOG_TAG = "MccTable";
+ MccEntry(int mnc, String iso, int smallestDigitsMCC, String language) {
+ this.mcc = mnc;
+ this.iso = iso;
+ this.smallestDigitsMnc = smallestDigitsMCC;
+ this.language = language;
+ }
+
+
+ public int compareTo(MccEntry o)
+ {
+ return mcc - o.mcc;
+ }
+ }
+
+ private static MccEntry
+ entryForMcc(int mcc)
+ {
+ int index;
+
+ MccEntry m;
+
+ m = new MccEntry(mcc, null, 0);
+
+ index = Collections.binarySearch(table, m);
- /**
- * Given a Mobile Country Code, returns a default time zone ID
- * if available. Returns null if unavailable.
- */
- public static String defaultTimeZoneForMcc(int mcc) {
- int index = Arrays.binarySearch(MCC_CODES, (short)mcc);
if (index < 0) {
return null;
+ } else {
+ return table.get(index);
}
- int indCode = IND_CODES[index];
- int tzInd = (indCode >>> 4) & 0x001F;
- String tz = TZ_STRINGS[tzInd];
- if (tz == "") {
+ }
+
+ /**
+ * Returns a default time zone ID for the given MCC.
+ * @param mcc Mobile Country Code
+ * @return default TimeZone ID, or null if not specified
+ */
+ public static String defaultTimeZoneForMcc(int mcc) {
+ MccEntry entry;
+
+ entry = entryForMcc(mcc);
+ if (entry == null || entry.iso == null) {
return null;
+ } else {
+ Locale locale;
+ if (entry.language == null) {
+ locale = new Locale(entry.iso);
+ } else {
+ locale = new Locale(entry.language, entry.iso);
+ }
+ String[] tz = TimeZones.forLocale(locale);
+ if (tz.length == 0) return null;
+ return tz[0];
}
- return tz;
}
/**
- * Given a Mobile Country Code, returns an ISO two-character
- * country code if available. Returns "" if unavailable.
+ * Given a GSM Mobile Country Code, returns
+ * an ISO two-character country code if available.
+ * Returns "" if unavailable.
*/
- public static String countryCodeForMcc(int mcc) {
- int index = Arrays.binarySearch(MCC_CODES, (short)mcc);
- if (index < 0) {
+ public static String
+ countryCodeForMcc(int mcc)
+ {
+ MccEntry entry;
+
+ entry = entryForMcc(mcc);
+
+ if (entry == null) {
return "";
+ } else {
+ return entry.iso;
}
- int indCode = IND_CODES[index];
- byte[] iso = {(byte)((indCode >>> 24) & 0x00FF), (byte)((indCode >>> 16) & 0x00FF)};
- return new String(iso);
}
/**
- * Given a GSM Mobile Country Code, returns an ISO 2-3 character
- * language code if available. Returns null if unavailable.
+ * Given a GSM Mobile Country Code, returns
+ * an ISO 2-3 character language code if available.
+ * Returns null if unavailable.
*/
public static String defaultLanguageForMcc(int mcc) {
- int index = Arrays.binarySearch(MCC_CODES, (short)mcc);
- if (index < 0) {
- return null;
- }
- int indCode = IND_CODES[index];
- int langInd = indCode & 0x000F;
- String lang = LANG_STRINGS[langInd];
- if (lang == "") {
+ MccEntry entry;
+
+ entry = entryForMcc(mcc);
+
+ if (entry == null) {
return null;
+ } else {
+ return entry.language;
}
- return lang;
}
/**
- * Given a GSM Mobile Country Code, returns the corresponding
- * smallest number of digits field. Returns 2 if unavailable.
+ * Given a GSM Mobile Country Code, returns
+ * the smallest number of digits that M if available.
+ * Returns 2 if unavailable.
*/
- public static int smallestDigitsMccForMnc(int mcc) {
- int index = Arrays.binarySearch(MCC_CODES, (short)mcc);
- if (index < 0) {
- return 2;
- }
- int indCode = IND_CODES[index];
- int smDig = (indCode >>> 9) & 0x0003;
- return smDig;
- }
+ public static int
+ smallestDigitsMccForMnc(int mcc)
+ {
+ MccEntry entry;
- /**
- * Given a GSM Mobile Country Code, returns the number of wifi
- * channels allowed in that country. Returns 0 if unavailable.
- */
- public static int wifiChannelsForMcc(int mcc) {
- int index = Arrays.binarySearch(MCC_CODES, (short)mcc);
- if (index < 0) {
- return 0;
+ entry = entryForMcc(mcc);
+
+ if (entry == null) {
+ return 2;
+ } else {
+ return entry.smallestDigitsMnc;
}
- int indCode = IND_CODES[index];
- int wifi = (indCode >>> 11) & 0x000F;
- return wifi;
}
/**
@@ -592,7 +187,7 @@ public final class MccTable
if (mcc != 0) {
setTimezoneFromMccIfNeeded(phone, mcc);
setLocaleFromMccIfNeeded(phone, mcc);
- setWifiChannelsFromMcc(phone, mcc);
+ setWifiCountryCodeFromMcc(phone, mcc);
}
try {
Configuration config = ActivityManagerNative.getDefault().getConfiguration();
@@ -648,14 +243,272 @@ public final class MccTable
* @param phone PhoneBase to act on (get context from).
* @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
*/
- private static void setWifiChannelsFromMcc(PhoneBase phone, int mcc) {
- int wifiChannels = MccTable.wifiChannelsForMcc(mcc);
- if (wifiChannels != 0) {
+ private static void setWifiCountryCodeFromMcc(PhoneBase phone, int mcc) {
+ String country = MccTable.countryCodeForMcc(mcc);
+ if (!country.isEmpty()) {
Context context = phone.getContext();
- Log.d(LOG_TAG, "WIFI_NUM_ALLOWED_CHANNELS set to " + wifiChannels);
+ Log.d(LOG_TAG, "WIFI_COUNTRY_CODE set to " + country);
WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
//persist
- wM.setNumAllowedChannels(wifiChannels, true);
+ wM.setCountryCode(country, true);
}
}
+
+ static {
+ table = new ArrayList<MccEntry>(240);
+
+
+ /*
+ * The table below is built from two resources:
+ *
+ * 1) ITU "Mobile Network Code (MNC) for the international
+ * identification plan for mobile terminals and mobile users"
+ * which is available as an annex to the ITU operational bulletin
+ * available here: http://www.itu.int/itu-t/bulletin/annex.html
+ *
+ * 2) The ISO 3166 country codes list, available here:
+ * http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
+ *
+ * This table has not been verified.
+ *
+ */
+
+ table.add(new MccEntry(202,"gr",2)); //Greece
+ table.add(new MccEntry(204,"nl",2,"nl")); //Netherlands (Kingdom of the)
+ table.add(new MccEntry(206,"be",2)); //Belgium
+ table.add(new MccEntry(208,"fr",2,"fr")); //France
+ table.add(new MccEntry(212,"mc",2)); //Monaco (Principality of)
+ table.add(new MccEntry(213,"ad",2)); //Andorra (Principality of)
+ table.add(new MccEntry(214,"es",2,"es")); //Spain
+ table.add(new MccEntry(216,"hu",2)); //Hungary (Republic of)
+ table.add(new MccEntry(218,"ba",2)); //Bosnia and Herzegovina
+ table.add(new MccEntry(219,"hr",2)); //Croatia (Republic of)
+ table.add(new MccEntry(220,"rs",2)); //Serbia and Montenegro
+ table.add(new MccEntry(222,"it",2,"it")); //Italy
+ table.add(new MccEntry(225,"va",2,"it")); //Vatican City State
+ table.add(new MccEntry(226,"ro",2)); //Romania
+ table.add(new MccEntry(228,"ch",2,"de")); //Switzerland (Confederation of)
+ table.add(new MccEntry(230,"cz",2,"cs")); //Czech Republic
+ table.add(new MccEntry(231,"sk",2)); //Slovak Republic
+ table.add(new MccEntry(232,"at",2,"de")); //Austria
+ table.add(new MccEntry(234,"gb",2,"en")); //United Kingdom of Great Britain and Northern Ireland
+ table.add(new MccEntry(235,"gb",2,"en")); //United Kingdom of Great Britain and Northern Ireland
+ table.add(new MccEntry(238,"dk",2)); //Denmark
+ table.add(new MccEntry(240,"se",2)); //Sweden
+ table.add(new MccEntry(242,"no",2)); //Norway
+ table.add(new MccEntry(244,"fi",2)); //Finland
+ table.add(new MccEntry(246,"lt",2)); //Lithuania (Republic of)
+ table.add(new MccEntry(247,"lv",2)); //Latvia (Republic of)
+ table.add(new MccEntry(248,"ee",2)); //Estonia (Republic of)
+ table.add(new MccEntry(250,"ru",2)); //Russian Federation
+ table.add(new MccEntry(255,"ua",2)); //Ukraine
+ table.add(new MccEntry(257,"by",2)); //Belarus (Republic of)
+ table.add(new MccEntry(259,"md",2)); //Moldova (Republic of)
+ table.add(new MccEntry(260,"pl",2)); //Poland (Republic of)
+ table.add(new MccEntry(262,"de",2,"de")); //Germany (Federal Republic of)
+ table.add(new MccEntry(266,"gi",2)); //Gibraltar
+ table.add(new MccEntry(268,"pt",2)); //Portugal
+ table.add(new MccEntry(270,"lu",2)); //Luxembourg
+ table.add(new MccEntry(272,"ie",2,"en")); //Ireland
+ table.add(new MccEntry(274,"is",2)); //Iceland
+ table.add(new MccEntry(276,"al",2)); //Albania (Republic of)
+ table.add(new MccEntry(278,"mt",2)); //Malta
+ table.add(new MccEntry(280,"cy",2)); //Cyprus (Republic of)
+ table.add(new MccEntry(282,"ge",2)); //Georgia
+ table.add(new MccEntry(283,"am",2)); //Armenia (Republic of)
+ table.add(new MccEntry(284,"bg",2)); //Bulgaria (Republic of)
+ table.add(new MccEntry(286,"tr",2)); //Turkey
+ table.add(new MccEntry(288,"fo",2)); //Faroe Islands
+ table.add(new MccEntry(289,"ge",2)); //Abkhazia (Georgia)
+ table.add(new MccEntry(290,"gl",2)); //Greenland (Denmark)
+ table.add(new MccEntry(292,"sm",2)); //San Marino (Republic of)
+ table.add(new MccEntry(293,"sl",2)); //Slovenia (Republic of)
+ table.add(new MccEntry(294,"mk",2)); //The Former Yugoslav Republic of Macedonia
+ table.add(new MccEntry(295,"li",2)); //Liechtenstein (Principality of)
+ table.add(new MccEntry(297,"me",2)); //Montenegro (Republic of)
+ table.add(new MccEntry(302,"ca",3,"")); //Canada
+ table.add(new MccEntry(308,"pm",2)); //Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)
+ table.add(new MccEntry(310,"us",3,"en")); //United States of America
+ table.add(new MccEntry(311,"us",3,"en")); //United States of America
+ table.add(new MccEntry(312,"us",3,"en")); //United States of America
+ table.add(new MccEntry(313,"us",3,"en")); //United States of America
+ table.add(new MccEntry(314,"us",3,"en")); //United States of America
+ table.add(new MccEntry(315,"us",3,"en")); //United States of America
+ table.add(new MccEntry(316,"us",3,"en")); //United States of America
+ table.add(new MccEntry(330,"pr",2)); //Puerto Rico
+ table.add(new MccEntry(332,"vi",2)); //United States Virgin Islands
+ table.add(new MccEntry(334,"mx",3)); //Mexico
+ table.add(new MccEntry(338,"jm",3)); //Jamaica
+ table.add(new MccEntry(340,"gp",2)); //Guadeloupe (French Department of)
+ table.add(new MccEntry(342,"bb",3)); //Barbados
+ table.add(new MccEntry(344,"ag",3)); //Antigua and Barbuda
+ table.add(new MccEntry(346,"ky",3)); //Cayman Islands
+ table.add(new MccEntry(348,"vg",3)); //British Virgin Islands
+ table.add(new MccEntry(350,"bm",2)); //Bermuda
+ table.add(new MccEntry(352,"gd",2)); //Grenada
+ table.add(new MccEntry(354,"ms",2)); //Montserrat
+ table.add(new MccEntry(356,"kn",2)); //Saint Kitts and Nevis
+ table.add(new MccEntry(358,"lc",2)); //Saint Lucia
+ table.add(new MccEntry(360,"vc",2)); //Saint Vincent and the Grenadines
+ table.add(new MccEntry(362,"nl",2)); //Netherlands Antilles
+ table.add(new MccEntry(363,"aw",2)); //Aruba
+ table.add(new MccEntry(364,"bs",2)); //Bahamas (Commonwealth of the)
+ table.add(new MccEntry(365,"ai",3)); //Anguilla
+ table.add(new MccEntry(366,"dm",2)); //Dominica (Commonwealth of)
+ table.add(new MccEntry(368,"cu",2)); //Cuba
+ table.add(new MccEntry(370,"do",2)); //Dominican Republic
+ table.add(new MccEntry(372,"ht",2)); //Haiti (Republic of)
+ table.add(new MccEntry(374,"tt",2)); //Trinidad and Tobago
+ table.add(new MccEntry(376,"tc",2)); //Turks and Caicos Islands
+ table.add(new MccEntry(400,"az",2)); //Azerbaijani Republic
+ table.add(new MccEntry(401,"kz",2)); //Kazakhstan (Republic of)
+ table.add(new MccEntry(402,"bt",2)); //Bhutan (Kingdom of)
+ table.add(new MccEntry(404,"in",2)); //India (Republic of)
+ table.add(new MccEntry(405,"in",2)); //India (Republic of)
+ table.add(new MccEntry(410,"pk",2)); //Pakistan (Islamic Republic of)
+ table.add(new MccEntry(412,"af",2)); //Afghanistan
+ table.add(new MccEntry(413,"lk",2)); //Sri Lanka (Democratic Socialist Republic of)
+ table.add(new MccEntry(414,"mm",2)); //Myanmar (Union of)
+ table.add(new MccEntry(415,"lb",2)); //Lebanon
+ table.add(new MccEntry(416,"jo",2)); //Jordan (Hashemite Kingdom of)
+ table.add(new MccEntry(417,"sy",2)); //Syrian Arab Republic
+ table.add(new MccEntry(418,"iq",2)); //Iraq (Republic of)
+ table.add(new MccEntry(419,"kw",2)); //Kuwait (State of)
+ table.add(new MccEntry(420,"sa",2)); //Saudi Arabia (Kingdom of)
+ table.add(new MccEntry(421,"ye",2)); //Yemen (Republic of)
+ table.add(new MccEntry(422,"om",2)); //Oman (Sultanate of)
+ table.add(new MccEntry(423,"ps",2)); //Palestine
+ table.add(new MccEntry(424,"ae",2)); //United Arab Emirates
+ table.add(new MccEntry(425,"il",2)); //Israel (State of)
+ table.add(new MccEntry(426,"bh",2)); //Bahrain (Kingdom of)
+ table.add(new MccEntry(427,"qa",2)); //Qatar (State of)
+ table.add(new MccEntry(428,"mn",2)); //Mongolia
+ table.add(new MccEntry(429,"np",2)); //Nepal
+ table.add(new MccEntry(430,"ae",2)); //United Arab Emirates
+ table.add(new MccEntry(431,"ae",2)); //United Arab Emirates
+ table.add(new MccEntry(432,"ir",2)); //Iran (Islamic Republic of)
+ table.add(new MccEntry(434,"uz",2)); //Uzbekistan (Republic of)
+ table.add(new MccEntry(436,"tj",2)); //Tajikistan (Republic of)
+ table.add(new MccEntry(437,"kg",2)); //Kyrgyz Republic
+ table.add(new MccEntry(438,"tm",2)); //Turkmenistan
+ table.add(new MccEntry(440,"jp",2,"ja")); //Japan
+ table.add(new MccEntry(441,"jp",2,"ja")); //Japan
+ table.add(new MccEntry(450,"kr",2,"ko")); //Korea (Republic of)
+ table.add(new MccEntry(452,"vn",2)); //Viet Nam (Socialist Republic of)
+ table.add(new MccEntry(454,"hk",2)); //"Hong Kong, China"
+ table.add(new MccEntry(455,"mo",2)); //"Macao, China"
+ table.add(new MccEntry(456,"kh",2)); //Cambodia (Kingdom of)
+ table.add(new MccEntry(457,"la",2)); //Lao People's Democratic Republic
+ table.add(new MccEntry(460,"cn",2,"zh")); //China (People's Republic of)
+ table.add(new MccEntry(461,"cn",2,"zh")); //China (People's Republic of)
+ table.add(new MccEntry(466,"tw",2)); //"Taiwan, China"
+ table.add(new MccEntry(467,"kp",2)); //Democratic People's Republic of Korea
+ table.add(new MccEntry(470,"bd",2)); //Bangladesh (People's Republic of)
+ table.add(new MccEntry(472,"mv",2)); //Maldives (Republic of)
+ table.add(new MccEntry(502,"my",2)); //Malaysia
+ table.add(new MccEntry(505,"au",2,"en")); //Australia
+ table.add(new MccEntry(510,"id",2)); //Indonesia (Republic of)
+ table.add(new MccEntry(514,"tl",2)); //Democratic Republic of Timor-Leste
+ table.add(new MccEntry(515,"ph",2)); //Philippines (Republic of the)
+ table.add(new MccEntry(520,"th",2)); //Thailand
+ table.add(new MccEntry(525,"sg",2,"en")); //Singapore (Republic of)
+ table.add(new MccEntry(528,"bn",2)); //Brunei Darussalam
+ table.add(new MccEntry(530,"nz",2, "en")); //New Zealand
+ table.add(new MccEntry(534,"mp",2)); //Northern Mariana Islands (Commonwealth of the)
+ table.add(new MccEntry(535,"gu",2)); //Guam
+ table.add(new MccEntry(536,"nr",2)); //Nauru (Republic of)
+ table.add(new MccEntry(537,"pg",2)); //Papua New Guinea
+ table.add(new MccEntry(539,"to",2)); //Tonga (Kingdom of)
+ table.add(new MccEntry(540,"sb",2)); //Solomon Islands
+ table.add(new MccEntry(541,"vu",2)); //Vanuatu (Republic of)
+ table.add(new MccEntry(542,"fj",2)); //Fiji (Republic of)
+ table.add(new MccEntry(543,"wf",2)); //Wallis and Futuna (Territoire franais d'outre-mer)
+ table.add(new MccEntry(544,"as",2)); //American Samoa
+ table.add(new MccEntry(545,"ki",2)); //Kiribati (Republic of)
+ table.add(new MccEntry(546,"nc",2)); //New Caledonia (Territoire franais d'outre-mer)
+ table.add(new MccEntry(547,"pf",2)); //French Polynesia (Territoire franais d'outre-mer)
+ table.add(new MccEntry(548,"ck",2)); //Cook Islands
+ table.add(new MccEntry(549,"ws",2)); //Samoa (Independent State of)
+ table.add(new MccEntry(550,"fm",2)); //Micronesia (Federated States of)
+ table.add(new MccEntry(551,"mh",2)); //Marshall Islands (Republic of the)
+ table.add(new MccEntry(552,"pw",2)); //Palau (Republic of)
+ table.add(new MccEntry(602,"eg",2)); //Egypt (Arab Republic of)
+ table.add(new MccEntry(603,"dz",2)); //Algeria (People's Democratic Republic of)
+ table.add(new MccEntry(604,"ma",2)); //Morocco (Kingdom of)
+ table.add(new MccEntry(605,"tn",2)); //Tunisia
+ table.add(new MccEntry(606,"ly",2)); //Libya (Socialist People's Libyan Arab Jamahiriya)
+ table.add(new MccEntry(607,"gm",2)); //Gambia (Republic of the)
+ table.add(new MccEntry(608,"sn",2)); //Senegal (Republic of)
+ table.add(new MccEntry(609,"mr",2)); //Mauritania (Islamic Republic of)
+ table.add(new MccEntry(610,"ml",2)); //Mali (Republic of)
+ table.add(new MccEntry(611,"gn",2)); //Guinea (Republic of)
+ table.add(new MccEntry(612,"ci",2)); //Cte d'Ivoire (Republic of)
+ table.add(new MccEntry(613,"bf",2)); //Burkina Faso
+ table.add(new MccEntry(614,"ne",2)); //Niger (Republic of the)
+ table.add(new MccEntry(615,"tg",2)); //Togolese Republic
+ table.add(new MccEntry(616,"bj",2)); //Benin (Republic of)
+ table.add(new MccEntry(617,"mu",2)); //Mauritius (Republic of)
+ table.add(new MccEntry(618,"lr",2)); //Liberia (Republic of)
+ table.add(new MccEntry(619,"sl",2)); //Sierra Leone
+ table.add(new MccEntry(620,"gh",2)); //Ghana
+ table.add(new MccEntry(621,"ng",2)); //Nigeria (Federal Republic of)
+ table.add(new MccEntry(622,"td",2)); //Chad (Republic of)
+ table.add(new MccEntry(623,"cf",2)); //Central African Republic
+ table.add(new MccEntry(624,"cm",2)); //Cameroon (Republic of)
+ table.add(new MccEntry(625,"cv",2)); //Cape Verde (Republic of)
+ table.add(new MccEntry(626,"st",2)); //Sao Tome and Principe (Democratic Republic of)
+ table.add(new MccEntry(627,"gq",2)); //Equatorial Guinea (Republic of)
+ table.add(new MccEntry(628,"ga",2)); //Gabonese Republic
+ table.add(new MccEntry(629,"cg",2)); //Congo (Republic of the)
+ table.add(new MccEntry(630,"cg",2)); //Democratic Republic of the Congo
+ table.add(new MccEntry(631,"ao",2)); //Angola (Republic of)
+ table.add(new MccEntry(632,"gw",2)); //Guinea-Bissau (Republic of)
+ table.add(new MccEntry(633,"sc",2)); //Seychelles (Republic of)
+ table.add(new MccEntry(634,"sd",2)); //Sudan (Republic of the)
+ table.add(new MccEntry(635,"rw",2)); //Rwanda (Republic of)
+ table.add(new MccEntry(636,"et",2)); //Ethiopia (Federal Democratic Republic of)
+ table.add(new MccEntry(637,"so",2)); //Somali Democratic Republic
+ table.add(new MccEntry(638,"dj",2)); //Djibouti (Republic of)
+ table.add(new MccEntry(639,"ke",2)); //Kenya (Republic of)
+ table.add(new MccEntry(640,"tz",2)); //Tanzania (United Republic of)
+ table.add(new MccEntry(641,"ug",2)); //Uganda (Republic of)
+ table.add(new MccEntry(642,"bi",2)); //Burundi (Republic of)
+ table.add(new MccEntry(643,"mz",2)); //Mozambique (Republic of)
+ table.add(new MccEntry(645,"zm",2)); //Zambia (Republic of)
+ table.add(new MccEntry(646,"mg",2)); //Madagascar (Republic of)
+ table.add(new MccEntry(647,"re",2)); //Reunion (French Department of)
+ table.add(new MccEntry(648,"zw",2)); //Zimbabwe (Republic of)
+ table.add(new MccEntry(649,"na",2)); //Namibia (Republic of)
+ table.add(new MccEntry(650,"mw",2)); //Malawi
+ table.add(new MccEntry(651,"ls",2)); //Lesotho (Kingdom of)
+ table.add(new MccEntry(652,"bw",2)); //Botswana (Republic of)
+ table.add(new MccEntry(653,"sz",2)); //Swaziland (Kingdom of)
+ table.add(new MccEntry(654,"km",2)); //Comoros (Union of the)
+ table.add(new MccEntry(655,"za",2,"en")); //South Africa (Republic of)
+ table.add(new MccEntry(657,"er",2)); //Eritrea
+ table.add(new MccEntry(702,"bz",2)); //Belize
+ table.add(new MccEntry(704,"gt",2)); //Guatemala (Republic of)
+ table.add(new MccEntry(706,"sv",2)); //El Salvador (Republic of)
+ table.add(new MccEntry(708,"hn",3)); //Honduras (Republic of)
+ table.add(new MccEntry(710,"ni",2)); //Nicaragua
+ table.add(new MccEntry(712,"cr",2)); //Costa Rica
+ table.add(new MccEntry(714,"pa",2)); //Panama (Republic of)
+ table.add(new MccEntry(716,"pe",2)); //Peru
+ table.add(new MccEntry(722,"ar",3)); //Argentine Republic
+ table.add(new MccEntry(724,"br",2)); //Brazil (Federative Republic of)
+ table.add(new MccEntry(730,"cl",2)); //Chile
+ table.add(new MccEntry(732,"co",3)); //Colombia (Republic of)
+ table.add(new MccEntry(734,"ve",2)); //Venezuela (Bolivarian Republic of)
+ table.add(new MccEntry(736,"bo",2)); //Bolivia (Republic of)
+ table.add(new MccEntry(738,"gy",2)); //Guyana
+ table.add(new MccEntry(740,"ec",2)); //Ecuador
+ table.add(new MccEntry(742,"gf",2)); //French Guiana (French Department of)
+ table.add(new MccEntry(744,"py",2)); //Paraguay (Republic of)
+ table.add(new MccEntry(746,"sr",2)); //Suriname (Republic of)
+ table.add(new MccEntry(748,"uy",2)); //Uruguay (Eastern Republic of)
+ table.add(new MccEntry(750,"fk",2)); //Falkland Islands (Malvinas)
+ //table.add(new MccEntry(901,"",2)); //"International Mobile, shared code"
+
+ Collections.sort(table);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index e426e94..2957c7e 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -17,10 +17,10 @@
package com.android.internal.telephony;
import android.content.Context;
-import android.content.SharedPreferences;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
import android.os.Handler;
import android.os.Message;
-import android.preference.PreferenceManager;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
@@ -28,7 +28,6 @@ import android.telephony.SignalStrength;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.gsm.NetworkInfo;
-import com.android.internal.telephony.gsm.GsmDataConnection;
import com.android.internal.telephony.test.SimulatedRadioControl;
import java.util.List;
@@ -99,11 +98,12 @@ public interface Phone {
static final String PHONE_NAME_KEY = "phoneName";
static final String FAILURE_REASON_KEY = "reason";
static final String STATE_CHANGE_REASON_KEY = "reason";
- static final String DATA_APN_TYPES_KEY = "apnType";
+ static final String DATA_APN_TYPE_KEY = "apnType";
static final String DATA_APN_KEY = "apn";
+ static final String DATA_LINK_PROPERTIES_KEY = "linkProperties";
+ static final String DATA_LINK_CAPABILITIES_KEY = "linkCapabilities";
static final String DATA_IFACE_NAME_KEY = "iface";
- static final String DATA_GATEWAY_KEY = "gateway";
static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
static final String PHONE_IN_ECM_STATE = "phoneinECMState";
@@ -243,11 +243,19 @@ public interface Phone {
CellLocation getCellLocation();
/**
+ * Get the current for the default apn DataState. No change notification
+ * exists at this interface -- use
+ * {@link android.telephony.PhoneStateListener} instead.
+ */
+ DataState getDataConnectionState();
+
+ /**
* Get the current DataState. No change notification exists at this
* interface -- use
* {@link android.telephony.PhoneStateListener} instead.
+ * @param apnType specify for which apn to get connection state info.
*/
- DataState getDataConnectionState();
+ DataState getDataConnectionState(String apnType);
/**
* Get the current DataActivityState. No change notification exists at this
@@ -313,6 +321,16 @@ public interface Phone {
String getActiveApn();
/**
+ * Return the LinkProperties for the named apn or null if not available
+ */
+ LinkProperties getLinkProperties(String apnType);
+
+ /**
+ * Return the LinkCapabilities
+ */
+ LinkCapabilities getLinkCapabilities(String apnType);
+
+ /**
* Get current signal strength. No change notification available on this
* interface. Use <code>PhoneStateNotifier</code> or an equivalent.
* An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu).
@@ -1373,29 +1391,6 @@ public interface Phone {
boolean isDataConnectivityPossible();
/**
- * Returns the name of the network interface used by the specified APN type.
- */
- String getInterfaceName(String apnType);
-
- /**
- * Returns the IP address of the network interface used by the specified
- * APN type.
- */
- String getIpAddress(String apnType);
-
- /**
- * Returns the gateway for the network interface used by the specified APN
- * type.
- */
- String getGateway(String apnType);
-
- /**
- * Returns the DNS servers for the network interface used by the specified
- * APN type.
- */
- public String[] getDnsServers(String apnType);
-
- /**
* Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones.
*/
String getDeviceId();
@@ -1540,6 +1535,11 @@ public interface Phone {
boolean isOtaSpNumber(String dialStr);
/**
+ * Returns true if OTA Service Provisioning needs to be performed.
+ */
+ boolean needsOtaServiceProvisioning();
+
+ /**
* Register for notifications when CDMA call waiting comes
*
* @param h Handler that receives the notification message.
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 1674ad6..83080ee 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -21,6 +21,8 @@ import android.app.IActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.SharedPreferences;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Handler;
@@ -35,10 +37,8 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.internal.R;
-import com.android.internal.telephony.gsm.GsmDataConnection;
import com.android.internal.telephony.test.SimulatedRadioControl;
-import java.util.List;
import java.util.Locale;
@@ -558,11 +558,6 @@ public abstract class PhoneBase extends Handler implements Phone {
String c = carrierLocales[i].toString();
if (carrier.equals(c)) {
String l = carrierLocales[i+1].toString();
- int wifiChannels = 0;
- try {
- wifiChannels = Integer.parseInt(
- carrierLocales[i+2].toString());
- } catch (NumberFormatException e) { }
String language = l.substring(0, 2);
String country = "";
@@ -571,15 +566,15 @@ public abstract class PhoneBase extends Handler implements Phone {
}
setSystemLocale(language, country);
- if (wifiChannels != 0) {
+ if (!country.isEmpty()) {
try {
Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS);
+ Settings.Secure.WIFI_COUNTRY_CODE);
} catch (Settings.SettingNotFoundException e) {
// note this is not persisting
WifiManager wM = (WifiManager)
mContext.getSystemService(Context.WIFI_SERVICE);
- wM.setNumAllowedChannels(wifiChannels, false);
+ wM.setCountryCode(country, false);
}
}
return;
@@ -741,8 +736,22 @@ public abstract class PhoneBase extends Handler implements Phone {
mNotifier.notifyMessageWaitingChanged(this);
}
- public void notifyDataConnection(String reason) {
- mNotifier.notifyDataConnection(this, reason);
+ public void notifyDataConnection(String reason, String apnType,
+ Phone.DataState state) {
+ mNotifier.notifyDataConnection(this, reason, apnType, state);
+ }
+
+ public void notifyDataConnection(String reason, String apnType) {
+ mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
+ }
+
+ public void notifyDataConnection() {
+ String apn = getActiveApn();
+ mNotifier.notifyDataConnection(this, null, apn, getDataConnectionState(apn));
+ }
+
+ public void notifyOtaspChanged(int otaspMode) {
+ mNotifier.notifyOtaspChanged(this, otaspMode);
}
public abstract String getPhoneName();
@@ -828,9 +837,19 @@ public abstract class PhoneBase extends Handler implements Phone {
logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady");
}
+ /**
+ * Returns true if OTA Service Provisioning needs to be performed.
+ * If not overridden return false.
+ */
+ public boolean needsOtaServiceProvisioning() {
+ return false;
+ }
+
+ /**
+ * Return true if number is an OTASP number.
+ * If not overridden return false.
+ */
public boolean isOtaSpNumber(String dialStr) {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("isOtaSpNumber");
return false;
}
@@ -920,28 +939,20 @@ public abstract class PhoneBase extends Handler implements Phone {
logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse");
}
- public String getInterfaceName(String apnType) {
- return mDataConnection.getInterfaceName(apnType);
- }
-
- public String getIpAddress(String apnType) {
- return mDataConnection.getIpAddress(apnType);
- }
-
public boolean isDataConnectivityEnabled() {
return mDataConnection.getDataEnabled();
}
- public String getGateway(String apnType) {
- return mDataConnection.getGateway(apnType);
+ public String[] getActiveApnTypes() {
+ return mDataConnection.getActiveApnTypes();
}
- public String[] getDnsServers(String apnType) {
- return mDataConnection.getDnsServers(apnType);
+ public LinkProperties getLinkProperties(String apnType) {
+ return mDataConnection.getLinkProperties(apnType);
}
- public String[] getActiveApnTypes() {
- return mDataConnection.getActiveApnTypes();
+ public LinkCapabilities getLinkCapabilities(String apnType) {
+ return mDataConnection.getLinkCapabilities(apnType);
}
public String getActiveApn() {
@@ -956,6 +967,10 @@ public abstract class PhoneBase extends Handler implements Phone {
return mDataConnection.disableApnType(type);
}
+ public boolean isDataConnectivityPossible() {
+ return ((mDataConnection != null) && (mDataConnection.isDataPossible()));
+ }
+
/**
* simulateDataConnection
*
@@ -984,7 +999,7 @@ public abstract class PhoneBase extends Handler implements Phone {
}
mDataConnection.setState(dcState);
- notifyDataConnection(null);
+ notifyDataConnection(null, Phone.APN_TYPE_DEFAULT);
}
/**
@@ -1038,6 +1053,10 @@ public abstract class PhoneBase extends Handler implements Phone {
"called, CDMAPhone inactive.");
}
+ public DataState getDataConnectionState() {
+ return getDataConnectionState(APN_TYPE_DEFAULT);
+ }
+
/**
* Common error logger method for unexpected calls to GSM/WCDMA-only methods.
*/
diff --git a/telephony/java/com/android/internal/telephony/PhoneNotifier.java b/telephony/java/com/android/internal/telephony/PhoneNotifier.java
index e96eeae..28a8d22 100644
--- a/telephony/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/PhoneNotifier.java
@@ -33,10 +33,13 @@ public interface PhoneNotifier {
public void notifyCallForwardingChanged(Phone sender);
- public void notifyDataConnection(Phone sender, String reason);
+ /** TODO - reason should never be null */
+ public void notifyDataConnection(Phone sender, String reason, String apnType,
+ Phone.DataState state);
- public void notifyDataConnectionFailed(Phone sender, String reason);
+ public void notifyDataConnectionFailed(Phone sender, String reason, String apnType);
public void notifyDataActivity(Phone sender);
+ public void notifyOtaspChanged(Phone sender, int otaspMode);
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 77f1e6c..02fdf28 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -20,13 +20,12 @@ package com.android.internal.telephony;
import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
-import android.preference.PreferenceManager;
import android.telephony.CellLocation;
-import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.util.Log;
@@ -34,7 +33,6 @@ import android.util.Log;
import com.android.internal.telephony.cdma.CDMAPhone;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.gsm.NetworkInfo;
-import com.android.internal.telephony.gsm.GsmDataConnection;
import com.android.internal.telephony.test.SimulatedRadioControl;
import java.util.List;
@@ -172,7 +170,11 @@ public class PhoneProxy extends Handler implements Phone {
}
public DataState getDataConnectionState() {
- return mActivePhone.getDataConnectionState();
+ return mActivePhone.getDataConnectionState(Phone.APN_TYPE_DEFAULT);
+ }
+
+ public DataState getDataConnectionState(String apnType) {
+ return mActivePhone.getDataConnectionState(apnType);
}
public DataActivityState getDataActivityState() {
@@ -207,6 +209,14 @@ public class PhoneProxy extends Handler implements Phone {
return mActivePhone.getActiveApnTypes();
}
+ public LinkProperties getLinkProperties(String apnType) {
+ return mActivePhone.getLinkProperties(apnType);
+ }
+
+ public LinkCapabilities getLinkCapabilities(String apnType) {
+ return mActivePhone.getLinkCapabilities(apnType);
+ }
+
public String getActiveApn() {
return mActivePhone.getActiveApn();
}
@@ -664,22 +674,6 @@ public class PhoneProxy extends Handler implements Phone {
return mActivePhone.isDataConnectivityPossible();
}
- public String getInterfaceName(String apnType) {
- return mActivePhone.getInterfaceName(apnType);
- }
-
- public String getIpAddress(String apnType) {
- return mActivePhone.getIpAddress(apnType);
- }
-
- public String getGateway(String apnType) {
- return mActivePhone.getGateway(apnType);
- }
-
- public String[] getDnsServers(String apnType) {
- return mActivePhone.getDnsServers(apnType);
- }
-
public String getDeviceId() {
return mActivePhone.getDeviceId();
}
@@ -768,6 +762,10 @@ public class PhoneProxy extends Handler implements Phone {
mActivePhone.exitEmergencyCallbackMode();
}
+ public boolean needsOtaServiceProvisioning(){
+ return mActivePhone.needsOtaServiceProvisioning();
+ }
+
public boolean isOtaSpNumber(String dialStr){
return mActivePhone.isOtaSpNumber(dialStr);
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index a9a4be2..35d5564 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -285,9 +285,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
- //***** Handler implemementation
-
- public void
+ //***** Handler implementation
+ @Override public void
handleMessage(Message msg) {
RILRequest rr = (RILRequest)(msg.obj);
RILRequest req = null;
@@ -780,7 +779,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ @Deprecated public void
getPDPContextList(Message result) {
getDataCallList(result);
}
@@ -1299,10 +1298,18 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
setupDataCall(String radioTechnology, String profile, String apn,
String user, String password, String authType, Message result) {
+ setupDataCallWithProtocol(radioTechnology, profile, apn, user, password,
+ authType, "IP", result);
+ }
+
+ public void
+ setupDataCallWithProtocol(String radioTechnology, String profile,
+ String apn, String user, String password, String authType,
+ String protocolType, Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
- rr.mp.writeInt(6);
+ rr.mp.writeInt(7);
rr.mp.writeString(radioTechnology);
rr.mp.writeString(profile);
@@ -1310,11 +1317,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr.mp.writeString(user);
rr.mp.writeString(password);
rr.mp.writeString(authType);
+ rr.mp.writeString(protocolType);
if (RILJ_LOGD) riljLog(rr.serialString() + "> "
+ requestToString(rr.mRequest) + " " + radioTechnology + " "
+ profile + " " + apn + " " + user + " "
- + password + " " + authType);
+ + password + " " + authType + " " + protocolType);
send(rr);
}
@@ -2907,7 +2915,11 @@ public final class RIL extends BaseCommands implements CommandsInterface {
dataCall.active = p.readInt();
dataCall.type = p.readString();
dataCall.apn = p.readString();
- dataCall.address = p.readString();
+ String address = p.readString();
+ if (address != null) {
+ address = address.split(" ")[0];
+ }
+ dataCall.address = address;
response.add(dataCall);
}
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index 917e1d8..3a7ce47 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -255,6 +255,7 @@ public abstract class SMSDispatcher extends Handler {
mCm.unregisterForOn(this);
}
+ @Override
protected void finalize() {
Log.d(TAG, "SMSDispatcher finalized");
}
@@ -927,14 +928,14 @@ public abstract class SMSDispatcher extends Handler {
*/
static protected class SmsTracker {
// fields need to be public for derived SmsDispatchers
- public HashMap mData;
+ public HashMap<String, Object> mData;
public int mRetryCount;
public int mMessageRef;
public PendingIntent mSentIntent;
public PendingIntent mDeliveryIntent;
- SmsTracker(HashMap data, PendingIntent sentIntent,
+ SmsTracker(HashMap<String, Object> data, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
mData = data;
mSentIntent = sentIntent;
@@ -943,7 +944,7 @@ public abstract class SMSDispatcher extends Handler {
}
}
- protected SmsTracker SmsTrackerFactory(HashMap data, PendingIntent sentIntent,
+ protected SmsTracker SmsTrackerFactory(HashMap<String, Object> data, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
return new SmsTracker(data, sentIntent, deliveryIntent);
}
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index e8bbe5e..3f9ffc3 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -53,6 +53,12 @@ public abstract class ServiceStateTracker extends Handler {
public SignalStrength mSignalStrength;
+ /* The otaspMode passed to PhoneStateListener#onOtaspChanged */
+ static public final int OTASP_UNINITIALIZED = 0;
+ static public final int OTASP_UNKNOWN = 1;
+ static public final int OTASP_NEEDED = 2;
+ static public final int OTASP_NOT_NEEDED = 3;
+
/**
* A unique identifier to track requests associated with a poll
* and ignore stale responses. The value is a count-down of
@@ -268,9 +274,11 @@ public abstract class ServiceStateTracker extends Handler {
public abstract void handleMessage(Message msg);
+ protected abstract Phone getPhone();
protected abstract void handlePollStateResult(int what, AsyncResult ar);
protected abstract void updateSpnDisplay();
protected abstract void setPowerStateToDesired();
+ protected abstract void log(String s);
/**
* Clean up existing voice and data connection then turn off radio power.
diff --git a/telephony/java/com/android/internal/telephony/SmsHeader.java b/telephony/java/com/android/internal/telephony/SmsHeader.java
index 7872eec..7a65162 100644
--- a/telephony/java/com/android/internal/telephony/SmsHeader.java
+++ b/telephony/java/com/android/internal/telephony/SmsHeader.java
@@ -30,7 +30,7 @@ import java.util.ArrayList;
*/
public class SmsHeader {
- // TODO(cleanup): this datastructure is generally referred to as
+ // TODO(cleanup): this data structure is generally referred to as
// the 'user data header' or UDH, and so the class name should
// change to reflect this...
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index af6c5f8..cbd8606 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -16,7 +16,6 @@
package com.android.internal.telephony;
-import android.util.Log;
import com.android.internal.telephony.SmsHeader;
import java.util.Arrays;
@@ -366,13 +365,13 @@ public abstract class SmsMessageBase {
/**
* Try to parse this message as an email gateway message
* There are two ways specified in TS 23.040 Section 3.8 :
- * - SMS message "may have its TP-PID set for internet electronic mail - MT
+ * - SMS message "may have its TP-PID set for Internet electronic mail - MT
* SMS format: [<from-address><space>]<message> - "Depending on the
* nature of the gateway, the destination/origination address is either
* derived from the content of the SMS TP-OA or TP-DA field, or the
* TP-OA/TP-DA field contains a generic gateway address and the to/from
* address is added at the beginning as shown above." (which is supported here)
- * - Multiple addreses separated by commas, no spaces, Subject field delimited
+ * - Multiple addresses separated by commas, no spaces, Subject field delimited
* by '()' or '##' and '#' Section 9.2.3.24.11 (which are NOT supported here)
*/
protected void extractEmailAddressFromMessageBody() {
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index a113787..136d5b1 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -45,7 +45,7 @@ public interface TelephonyProperties
* CDMA networks.
*/
static final String PROPERTY_OPERATOR_ALPHA = "gsm.operator.alpha";
- //TODO: most of these proprieties are generic, substitute gsm. with phone. bug 1856959
+ //TODO: most of these properties are generic, substitute gsm. with phone. bug 1856959
/** Numeric name (MCC+MNC) of current registered operator.<p>
* Availability: when registered to a network. Result may be unreliable on
@@ -83,12 +83,12 @@ public interface TelephonyProperties
/** The MCC+MNC (mobile country code+mobile network code) of the
* provider of the SIM. 5 or 6 decimal digits.
- * Availablity: SIM state must be "READY"
+ * Availability: SIM state must be "READY"
*/
static String PROPERTY_ICC_OPERATOR_NUMERIC = "gsm.sim.operator.numeric";
/** PROPERTY_ICC_OPERATOR_ALPHA is also known as the SPN, or Service Provider Name.
- * Availablity: SIM state must be "READY"
+ * Availability: SIM state must be "READY"
*/
static String PROPERTY_ICC_OPERATOR_ALPHA = "gsm.sim.operator.alpha";
@@ -127,7 +127,7 @@ public interface TelephonyProperties
"ro.telephony.call_ring.multiple";
/**
- * The number of milli-seconds between CALL_RING notifications.
+ * The number of milliseconds between CALL_RING notifications.
*/
static final String PROPERTY_CALL_RING_DELAY = "ro.telephony.call_ring.delay";
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index f31bf24..b9d5673 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -61,6 +61,7 @@ import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.PhoneNotifier;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.PhoneSubInfo;
+import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.UUSInfo;
@@ -83,10 +84,6 @@ public class CDMAPhone extends PhoneBase {
static final String LOG_TAG = "CDMA";
private static final boolean DBG = true;
- // Min values used to by needsActivation
- private static final String UNACTIVATED_MIN2_VALUE = "000000";
- private static final String UNACTIVATED_MIN_VALUE = "1111110111";
-
// Default Emergency Callback Mode exit timer
private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 300000;
@@ -515,14 +512,6 @@ public class CDMAPhone extends PhoneBase {
return false;
}
- public boolean isDataConnectivityPossible() {
- boolean noData = mDataConnection.getDataEnabled() &&
- getDataConnectionState() == DataState.DISCONNECTED;
- return !noData && getIccCard().getState() == IccCard.State.READY &&
- getServiceState().getState() == ServiceState.STATE_IN_SERVICE &&
- (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming());
- }
-
/**
* Removes the given MMI from the pending list and notifies registrants that
* it is complete.
@@ -613,7 +602,7 @@ public class CDMAPhone extends PhoneBase {
}
}
- public DataState getDataConnectionState() {
+ public DataState getDataConnectionState(String apnType) {
DataState ret = DataState.DISCONNECTED;
if (mSST == null) {
@@ -625,6 +614,8 @@ public class CDMAPhone extends PhoneBase {
// If we're out of service, open TCP sockets may still work
// but no data will flow
ret = DataState.DISCONNECTED;
+ } else if (mDataConnection.isApnTypeEnabled(apnType) == false) {
+ ret = DataState.DISCONNECTED;
} else {
switch (mDataConnection.getState()) {
case FAILED:
@@ -878,26 +869,6 @@ public class CDMAPhone extends PhoneBase {
mRuimRecords.setVoiceMessageWaiting(1, mwi);
}
- /**
- * Returns true if CDMA OTA Service Provisioning needs to be performed.
- */
- /* package */ boolean
- needsOtaServiceProvisioning() {
- String cdmaMin = getCdmaMin();
- boolean needsProvisioning;
- if (cdmaMin == null || (cdmaMin.length() < 6)) {
- if (DBG) Log.d(LOG_TAG, "needsOtaServiceProvisioning: illegal cdmaMin='"
- + cdmaMin + "' assume provisioning needed.");
- needsProvisioning = true;
- } else {
- needsProvisioning = (cdmaMin.equals(UNACTIVATED_MIN_VALUE)
- || cdmaMin.substring(0,6).equals(UNACTIVATED_MIN2_VALUE))
- || SystemProperties.getBoolean("test_cdma_setup", false);
- }
- if (DBG) Log.d(LOG_TAG, "needsOtaServiceProvisioning: ret=" + needsProvisioning);
- return needsProvisioning;
- }
-
@Override
public void exitEmergencyCallbackMode() {
if (mWakeLock.isHeld()) {
@@ -1191,6 +1162,14 @@ public class CDMAPhone extends PhoneBase {
mSMS.setCellBroadcastConfig(configValuesArray, response);
}
+ /**
+ * Returns true if OTA Service Provisioning needs to be performed.
+ */
+ @Override
+ public boolean needsOtaServiceProvisioning() {
+ return mSST.getOtasp() != ServiceStateTracker.OTASP_NOT_NEEDED;
+ }
+
private static final String IS683A_FEATURE_CODE = "*228";
private static final int IS683A_FEATURE_CODE_NUM_DIGITS = 4;
private static final int IS683A_SYS_SEL_CODE_NUM_DIGITS = 2;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index 3669e60..325c2e1 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -354,6 +354,24 @@ public final class CdmaCallTracker extends CallTracker {
|| (foregroundCall.getState() == CdmaCall.State.ACTIVE)
|| !backgroundCall.getState().isAlive());
+ if (!ret) {
+ log(String.format("canDial is false\n" +
+ "((serviceState=%d) != ServiceState.STATE_POWER_OFF)::=%s\n" +
+ "&& pendingMO == null::=%s\n" +
+ "&& !ringingCall.isRinging()::=%s\n" +
+ "&& !disableCall.equals(\"true\")::=%s\n" +
+ "&& (!foregroundCall.getState().isAlive()::=%s\n" +
+ " || foregroundCall.getState() == CdmaCall.State.ACTIVE::=%s\n" +
+ " ||!backgroundCall.getState().isAlive())::=%s)",
+ serviceState,
+ serviceState != ServiceState.STATE_POWER_OFF,
+ pendingMO == null,
+ !ringingCall.isRinging(),
+ !disableCall.equals("true"),
+ !foregroundCall.getState().isAlive(),
+ foregroundCall.getState() == CdmaCall.State.ACTIVE,
+ !backgroundCall.getState().isAlive()));
+ }
return ret;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index 95cb1c6..8072c44 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -23,6 +23,7 @@ import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.gsm.ApnSetting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.RetryManager;
/**
* {@hide}
@@ -39,23 +40,27 @@ public class CdmaDataConnection extends DataConnection {
// ***** Constructor
- private CdmaDataConnection(CDMAPhone phone, String name) {
- super(phone, name);
+ private CdmaDataConnection(CDMAPhone phone, String name, RetryManager rm) {
+ super(phone, name, rm);
}
/**
* Create the connection object
*
- * @param phone
+ * @param phone the Phone
+ * @param id the connection id
+ * @param rm the RetryManager
* @return CdmaDataConnection that was created.
*/
- static CdmaDataConnection makeDataConnection(CDMAPhone phone) {
+ static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm) {
synchronized (mCountLock) {
mCount += 1;
}
- CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDataConnection-" + mCount);
+ CdmaDataConnection cdmaDc = new CdmaDataConnection(phone,
+ "CdmaDataConnection-" + mCount, rm);
cdmaDc.start();
if (DBG) cdmaDc.log("Made " + cdmaDc.getName());
+ cdmaDc.mId = id;
return cdmaDc;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 9f2a44b..7c652c5 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -18,23 +18,13 @@ package com.android.internal.telephony.cdma;
import android.app.AlarmManager;
import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
-import android.net.NetworkInfo;
import android.net.TrafficStats;
-import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.preference.PreferenceManager;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
@@ -48,10 +38,9 @@ import com.android.internal.telephony.DataConnection.FailCause;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.EventLogTags;
+import com.android.internal.telephony.RetryManager;
import com.android.internal.telephony.gsm.ApnSetting;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.ServiceStateTracker;
import java.util.ArrayList;
@@ -63,20 +52,11 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
private CDMAPhone mCdmaPhone;
- // Indicates baseband will not auto-attach
- private boolean noAutoAttach = false;
- private boolean mIsScreenOn = true;
-
//useful for debugging
- boolean failNextConnect = false;
+ boolean mFailNextConnect = false;
- /**
- * dataConnectionList holds all the Data connection
- */
- private ArrayList<DataConnection> dataConnectionList;
-
- /** Currently active CdmaDataConnection */
- private CdmaDataConnection mActiveDataConnection;
+ /** The DataConnection being setup */
+ private CdmaDataConnection mPendingDataConnection;
private boolean mPendingRestartRadio = false;
private static final int TIME_DELAYED_TO_RESTART_RADIO =
@@ -87,10 +67,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
*/
private static final int DATA_CONNECTION_POOL_SIZE = 1;
- private static final int POLL_CONNECTION_MILLIS = 5 * 1000;
private static final String INTENT_RECONNECT_ALARM =
- "com.android.internal.telephony.cdma-reconnect";
- private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason";
+ "com.android.internal.telephony.cdma-reconnect";
/**
* Constants for the data connection activity:
@@ -114,49 +92,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
// if we have no active Apn this is null
protected ApnSetting mActiveApn;
- // Possibly promote to base class, the only difference is
- // the INTENT_RECONNECT_ALARM action is a different string.
- // Do consider technology changes if it is promoted.
- BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_SCREEN_ON)) {
- mIsScreenOn = true;
- stopNetStatPoll();
- startNetStatPoll();
- } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
- mIsScreenOn = false;
- stopNetStatPoll();
- startNetStatPoll();
- } else if (action.equals((INTENT_RECONNECT_ALARM))) {
- Log.d(LOG_TAG, "Data reconnect alarm. Previous state was " + state);
-
- String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
- if (state == State.FAILED) {
- cleanUpConnection(false, reason);
- }
- trySetupData(reason);
- } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
- final android.net.NetworkInfo networkInfo = (NetworkInfo)
- intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
- mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
- } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
- final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
- WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
-
- if (!enabled) {
- // when wifi got disabeled, the NETWORK_STATE_CHANGED_ACTION
- // quit and wont report disconnected til next enalbing.
- mIsWifiConnected = false;
- }
- }
- }
- };
-
-
/* Constructor */
CdmaDataConnectionTracker(CDMAPhone p) {
@@ -176,79 +111,49 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
p.mCM.registerForCdmaOtaProvision(this, EVENT_CDMA_OTA_PROVISION, null);
- IntentFilter filter = new IntentFilter();
- filter.addAction(INTENT_RECONNECT_ALARM);
- filter.addAction(Intent.ACTION_SCREEN_ON);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-
- // TODO: Why is this registering the phone as the receiver of the intent
- // and not its own handler?
- p.getContext().registerReceiver(mIntentReceiver, filter, null, p);
-
mDataConnectionTracker = this;
createAllDataConnectionList();
-
- // This preference tells us 1) initial condition for "dataEnabled",
- // and 2) whether the RIL will setup the baseband to auto-PS attach.
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(phone.getContext());
-
- boolean dataEnabledSetting = true;
- try {
- dataEnabledSetting = IConnectivityManager.Stub.asInterface(ServiceManager.
- getService(Context.CONNECTIVITY_SERVICE)).getMobileDataEnabled();
- } catch (Exception e) {
- // nothing to do - use the old behavior and leave data on
- }
- dataEnabled[APN_DEFAULT_ID] =
- !sp.getBoolean(CDMAPhone.DATA_DISABLED_ON_BOOT_KEY, false) &&
- dataEnabledSetting;
- if (dataEnabled[APN_DEFAULT_ID]) {
- enabledCount++;
- }
- noAutoAttach = !dataEnabled[APN_DEFAULT_ID];
-
- if (!mRetryMgr.configure(SystemProperties.get("ro.cdma.data_retry_config"))) {
- if (!mRetryMgr.configure(DEFAULT_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple linear sequence.
- Log.e(LOG_TAG, "Could not configure using DEFAULT_DATA_RETRY_CONFIG="
- + DEFAULT_DATA_RETRY_CONFIG);
- mRetryMgr.configure(20, 2000, 1000);
- }
- }
}
+ @Override
public void dispose() {
+ super.dispose();
+
// Unregister from all events
- phone.mCM.unregisterForAvailable(this);
- phone.mCM.unregisterForOffOrNotAvailable(this);
+ mPhone.mCM.unregisterForAvailable(this);
+ mPhone.mCM.unregisterForOffOrNotAvailable(this);
mCdmaPhone.mRuimRecords.unregisterForRecordsLoaded(this);
- phone.mCM.unregisterForNVReady(this);
- phone.mCM.unregisterForDataStateChanged(this);
+ mPhone.mCM.unregisterForNVReady(this);
+ mPhone.mCM.unregisterForDataStateChanged(this);
mCdmaPhone.mCT.unregisterForVoiceCallEnded(this);
mCdmaPhone.mCT.unregisterForVoiceCallStarted(this);
mCdmaPhone.mSST.unregisterForCdmaDataConnectionAttached(this);
mCdmaPhone.mSST.unregisterForCdmaDataConnectionDetached(this);
mCdmaPhone.mSST.unregisterForRoamingOn(this);
mCdmaPhone.mSST.unregisterForRoamingOff(this);
- phone.mCM.unregisterForCdmaOtaProvision(this);
+ mPhone.mCM.unregisterForCdmaOtaProvision(this);
- phone.getContext().unregisterReceiver(this.mIntentReceiver);
destroyAllDataConnectionList();
}
+ @Override
protected void finalize() {
- if(DBG) Log.d(LOG_TAG, "CdmaDataConnectionTracker finalized");
+ if(DBG) log("CdmaDataConnectionTracker finalized");
+ }
+
+ @Override
+ protected String getActionIntentReconnectAlarm() {
+ return INTENT_RECONNECT_ALARM;
}
+ @Override
protected void setState(State s) {
if (DBG) log ("setState: " + s);
- if (state != s) {
+ if (mState != s) {
EventLog.writeEvent(EventLogTags.CDMA_DATA_STATE_CHANGE,
- state.toString(), s.toString());
- state = s;
+ mState.toString(), s.toString());
+ mState = s;
}
}
@@ -267,6 +172,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
return false;
}
+ @Override
protected String[] getActiveApnTypes() {
String[] result;
if (mActiveApn != null) {
@@ -278,6 +184,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
return result;
}
+ @Override
protected String getActiveApnString() {
return null;
}
@@ -291,84 +198,98 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
*
* @return false while no data connection if all above requirements are met.
*/
+ @Override
public boolean isDataConnectionAsDesired() {
- boolean roaming = phone.getServiceState().getRoaming();
+ boolean roaming = mPhone.getServiceState().getRoaming();
- if (((phone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY) ||
+ if (((mPhone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY) ||
mCdmaPhone.mRuimRecords.getRecordsLoaded()) &&
(mCdmaPhone.mSST.getCurrentCdmaDataConnectionState() ==
ServiceState.STATE_IN_SERVICE) &&
(!roaming || getDataOnRoamingEnabled()) &&
!mIsWifiConnected ) {
- return (state == State.CONNECTED);
+ return (mState == State.CONNECTED);
}
return true;
}
- private boolean isDataAllowed() {
- boolean roaming = phone.getServiceState().getRoaming();
- return getAnyDataEnabled() && (!roaming || getDataOnRoamingEnabled()) && mMasterDataEnabled;
+ @Override
+ protected boolean isDataAllowed() {
+ int psState = mCdmaPhone.mSST.getCurrentCdmaDataConnectionState();
+ boolean roaming = (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled());
+ boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
+
+ boolean allowed =
+ (psState == ServiceState.STATE_IN_SERVICE ||
+ mAutoAttachOnCreation) &&
+ (mPhone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY ||
+ mCdmaPhone.mRuimRecords.getRecordsLoaded()) &&
+ (mCdmaPhone.mSST.isConcurrentVoiceAndData() ||
+ mPhone.getState() == Phone.State.IDLE) &&
+ !roaming &&
+ mMasterDataEnabled &&
+ desiredPowerState &&
+ !mPendingRestartRadio &&
+ !mCdmaPhone.needsOtaServiceProvisioning();
+ if (!allowed && DBG) {
+ String reason = "";
+ if (!((psState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
+ reason += " - psState= " + psState;
+ }
+ if (!(mPhone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY ||
+ mCdmaPhone.mRuimRecords.getRecordsLoaded())) {
+ reason += " - radioState= " + mPhone.mCM.getRadioState() + " - RUIM not loaded";
+ }
+ if (mPhone.getState() != Phone.State.IDLE &&
+ mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
+ reason += " - concurrentVoiceAndData not allowed and state= " + mPhone.getState();
+ }
+ if (roaming) reason += " - Roaming";
+ if (!mMasterDataEnabled) reason += " - mMasterDataEnabled= false";
+ if (!desiredPowerState) reason += " - desiredPowerState= false";
+ if (mPendingRestartRadio) reason += " - mPendingRestartRadio= true";
+ if (mCdmaPhone.needsOtaServiceProvisioning()) reason += " - needs Provisioning";
+ log("Data not allowed due to" + reason);
+ }
+ return allowed;
}
private boolean trySetupData(String reason) {
if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason));
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
setState(State.CONNECTED);
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
+ notifyOffApnsOfAvailability(reason, true);
- Log.i(LOG_TAG, "(fix?) We're on the simulator; assuming data is connected");
+ log("(fix?) We're on the simulator; assuming data is connected");
return true;
}
int psState = mCdmaPhone.mSST.getCurrentCdmaDataConnectionState();
- boolean roaming = phone.getServiceState().getRoaming();
+ boolean roaming = mPhone.getServiceState().getRoaming();
boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
- if ((state == State.IDLE || state == State.SCANNING)
- && (psState == ServiceState.STATE_IN_SERVICE)
- && ((phone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY) ||
- mCdmaPhone.mRuimRecords.getRecordsLoaded())
- && (mCdmaPhone.mSST.isConcurrentVoiceAndData() ||
- phone.getState() == Phone.State.IDLE )
- && isDataAllowed()
- && desiredPowerState
- && !mPendingRestartRadio
- && !mCdmaPhone.needsOtaServiceProvisioning()) {
-
- return setupData(reason);
-
+ if ((mState == State.IDLE || mState == State.SCANNING) &&
+ isDataAllowed() && getAnyDataEnabled()) {
+ boolean retValue = setupData(reason);
+ notifyOffApnsOfAvailability(reason, retValue);
+ return retValue;
} else {
- if (DBG) {
- log("trySetupData: Not ready for data: " +
- " dataState=" + state +
- " PS state=" + psState +
- " radio state=" + phone.mCM.getRadioState() +
- " ruim=" + mCdmaPhone.mRuimRecords.getRecordsLoaded() +
- " concurrentVoice&Data=" + mCdmaPhone.mSST.isConcurrentVoiceAndData() +
- " phoneState=" + phone.getState() +
- " dataEnabled=" + getAnyDataEnabled() +
- " roaming=" + roaming +
- " dataOnRoamingEnable=" + getDataOnRoamingEnabled() +
- " desiredPowerState=" + desiredPowerState +
- " PendingRestartRadio=" + mPendingRestartRadio +
- " MasterDataEnabled=" + mMasterDataEnabled +
- " needsOtaServiceProvisioning=" + mCdmaPhone.needsOtaServiceProvisioning());
- }
+ notifyOffApnsOfAvailability(reason, false);
return false;
}
}
/**
- * If tearDown is true, this only tears down a CONNECTED session. Presently,
- * there is no mechanism for abandoning an INITING/CONNECTING session,
- * but would likely involve cancelling pending async requests or
- * setting a flag or new state to ignore them when they came in
- * @param tearDown true if the underlying DataConnection should be
- * disconnected.
- * @param reason reason for the clean up.
+ * Cleanup all connections.
+ *
+ * TODO: Cleanup only a specified connection passed as a parameter.
+ *
+ * @param tearDown true if the underlying DataConnection should be disconnected.
+ * @param reason for the clean up.
*/
private void cleanUpConnection(boolean tearDown, String reason) {
if (DBG) log("cleanUpConnection: reason: " + reason);
@@ -376,19 +297,21 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
// Clear the reconnect alarm, if set.
if (mReconnectIntent != null) {
AlarmManager am =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
+ (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
am.cancel(mReconnectIntent);
mReconnectIntent = null;
}
setState(State.DISCONNECTING);
+ notifyDataAvailability(reason);
boolean notificationDeferred = false;
- for (DataConnection conn : dataConnectionList) {
+ for (DataConnection conn : mDataConnections.values()) {
if(conn != null) {
if (tearDown) {
if (DBG) log("cleanUpConnection: teardown, call conn.disconnect");
- conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE, reason));
+ conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE,
+ conn.getDataConnectionId(), 0, reason));
notificationDeferred = true;
} else {
if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
@@ -407,10 +330,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
private CdmaDataConnection findFreeDataConnection() {
- for (DataConnection connBase : dataConnectionList) {
- CdmaDataConnection conn = (CdmaDataConnection) connBase;
- if (conn.isInactive()) {
- return conn;
+ for (DataConnection dc : mDataConnections.values()) {
+ if (dc.isInactive()) {
+ return (CdmaDataConnection) dc;
}
}
return null;
@@ -424,7 +346,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
return false;
}
- mActiveDataConnection = conn;
+ /** TODO: We probably want the connection being setup to a parameter passed around */
+ mPendingDataConnection = conn;
String[] types;
if (mRequestedApnType.equals(Phone.APN_TYPE_DUN)) {
types = new String[1];
@@ -440,40 +363,43 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
conn.connect(msg, mActiveApn);
setState(State.INITING);
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
return true;
}
private void notifyDefaultData(String reason) {
setState(State.CONNECTED);
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
startNetStatPoll();
mRetryMgr.resetRetryCount();
}
private void resetPollStats() {
- txPkts = -1;
- rxPkts = -1;
- sentSinceLastRecv = 0;
- netStatPollPeriod = POLL_NETSTAT_MILLIS;
+ mTxPkts = -1;
+ mRxPkts = -1;
+ mSentSinceLastRecv = 0;
+ mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
mNoRecvPollCount = 0;
}
+ @Override
protected void startNetStatPoll() {
- if (state == State.CONNECTED && netStatPollEnabled == false) {
- Log.d(LOG_TAG, "[DataConnection] Start poll NetStat");
+ if (mState == State.CONNECTED && mNetStatPollEnabled == false) {
+ log("[DataConnection] Start poll NetStat");
resetPollStats();
- netStatPollEnabled = true;
+ mNetStatPollEnabled = true;
mPollNetStat.run();
}
}
+ @Override
protected void stopNetStatPoll() {
- netStatPollEnabled = false;
+ mNetStatPollEnabled = false;
removeCallbacks(mPollNetStat);
- Log.d(LOG_TAG, "[DataConnection] Stop poll NetStat");
+ log("[DataConnection] Stop poll NetStat");
}
+ @Override
protected void restartRadio() {
if (DBG) log("Cleanup connection and wait " +
(TIME_DELAYED_TO_RESTART_RADIO / 1000) + "s to restart radio");
@@ -490,73 +416,73 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
Activity newActivity;
- preTxPkts = txPkts;
- preRxPkts = rxPkts;
+ preTxPkts = mTxPkts;
+ preRxPkts = mRxPkts;
- txPkts = TrafficStats.getMobileTxPackets();
- rxPkts = TrafficStats.getMobileRxPackets();
+ mTxPkts = TrafficStats.getMobileTxPackets();
+ mRxPkts = TrafficStats.getMobileRxPackets();
- //Log.d(LOG_TAG, "rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
+ //log("rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
- if (netStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
- sent = txPkts - preTxPkts;
- received = rxPkts - preRxPkts;
+ if (mNetStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
+ sent = mTxPkts - preTxPkts;
+ received = mRxPkts - preRxPkts;
if ( sent > 0 && received > 0 ) {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
newActivity = Activity.DATAINANDOUT;
} else if (sent > 0 && received == 0) {
- if (phone.getState() == Phone.State.IDLE) {
- sentSinceLastRecv += sent;
+ if (mPhone.getState() == Phone.State.IDLE) {
+ mSentSinceLastRecv += sent;
} else {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
}
newActivity = Activity.DATAOUT;
} else if (sent == 0 && received > 0) {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
newActivity = Activity.DATAIN;
} else if (sent == 0 && received == 0) {
- newActivity = (activity == Activity.DORMANT) ? activity : Activity.NONE;
+ newActivity = (mActivity == Activity.DORMANT) ? mActivity : Activity.NONE;
} else {
- sentSinceLastRecv = 0;
- newActivity = (activity == Activity.DORMANT) ? activity : Activity.NONE;
+ mSentSinceLastRecv = 0;
+ newActivity = (mActivity == Activity.DORMANT) ? mActivity : Activity.NONE;
}
- if (activity != newActivity) {
- activity = newActivity;
- phone.notifyDataActivity();
+ if (mActivity != newActivity && mIsScreenOn) {
+ mActivity = newActivity;
+ mPhone.notifyDataActivity();
}
}
- if (sentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) {
+ if (mSentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) {
// Packets sent without ack exceeded threshold.
if (mNoRecvPollCount == 0) {
EventLog.writeEvent(
EventLogTags.PDP_RADIO_RESET_COUNTDOWN_TRIGGERED,
- sentSinceLastRecv);
+ mSentSinceLastRecv);
}
if (mNoRecvPollCount < NO_RECV_POLL_LIMIT) {
mNoRecvPollCount++;
// Slow down the poll interval to let things happen
- netStatPollPeriod = POLL_NETSTAT_SLOW_MILLIS;
+ mNetStatPollPeriod = POLL_NETSTAT_SLOW_MILLIS;
} else {
- if (DBG) log("Sent " + String.valueOf(sentSinceLastRecv) +
+ if (DBG) log("Sent " + String.valueOf(mSentSinceLastRecv) +
" pkts since last received");
// We've exceeded the threshold. Restart the radio.
- netStatPollEnabled = false;
+ mNetStatPollEnabled = false;
stopNetStatPoll();
restartRadio();
EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, NO_RECV_POLL_LIMIT);
}
} else {
mNoRecvPollCount = 0;
- netStatPollPeriod = POLL_NETSTAT_MILLIS;
+ mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
}
- if (netStatPollEnabled) {
- mDataConnectionTracker.postDelayed(this, netStatPollPeriod);
+ if (mNetStatPollEnabled) {
+ mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
}
}
};
@@ -588,7 +514,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
private void reconnectAfterFail(FailCause lastFailCauseCode, String reason) {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
/**
* For now With CDMA we never try to reconnect on
* error and instead just continue to retry
@@ -596,15 +522,15 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
* TODO: Make this configurable?
*/
int nextReconnectDelay = mRetryMgr.getRetryTimer();
- Log.d(LOG_TAG, "Data Connection activate failed. Scheduling next attempt for "
+ log("Data Connection activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
AlarmManager am =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
+ (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(INTENT_RECONNECT_ALARM);
intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
mReconnectIntent = PendingIntent.getBroadcast(
- phone.getContext(), 0, intent, 0);
+ mPhone.getContext(), 0, intent, 0);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + nextReconnectDelay,
mReconnectIntent);
@@ -612,7 +538,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
mRetryMgr.increaseRetryCount();
if (!shouldPostNotification(lastFailCauseCode)) {
- Log.d(LOG_TAG,"NOT Posting Data Connection Unavailable notification "
+ log("NOT Posting Data Connection Unavailable notification "
+ "-- likely transient error");
} else {
notifyNoData(lastFailCauseCode);
@@ -622,24 +548,25 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
private void notifyNoData(FailCause lastFailCauseCode) {
setState(State.FAILED);
+ notifyDataAvailability(null);
}
private void gotoIdleAndNotifyDataConnection(String reason) {
if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
setState(State.IDLE);
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
mActiveApn = null;
}
protected void onRecordsLoaded() {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, null);
}
sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED));
}
protected void onNVReady() {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, null);
}
sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
@@ -650,12 +577,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
*/
@Override
protected void onEnableNewApn() {
- cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
+ cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
}
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected boolean onTrySetupData(String reason) {
return trySetupData(reason);
}
@@ -663,6 +591,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onRoamingOff() {
trySetupData(Phone.REASON_ROAMING_OFF);
}
@@ -670,6 +599,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onRoamingOn() {
if (getDataOnRoamingEnabled()) {
trySetupData(Phone.REASON_ROAMING_ON);
@@ -682,17 +612,20 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onRadioAvailable() {
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
setState(State.CONNECTED);
- phone.notifyDataConnection(null);
+ notifyDataConnection(null);
- Log.i(LOG_TAG, "We're on the simulator; assuming data is connected");
+ log("We're on the simulator; assuming data is connected");
}
- if (state != State.IDLE) {
+ notifyDataAvailability(null);
+
+ if (mState != State.IDLE) {
cleanUpConnection(true, null);
}
}
@@ -700,13 +633,14 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onRadioOffOrNotAvailable() {
mRetryMgr.resetRetryCount();
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
- Log.i(LOG_TAG, "We're on the simulator; assuming radio off is meaningless");
+ log("We're on the simulator; assuming radio off is meaningless");
} else {
if (DBG) log("Radio is off and clean up all connection");
cleanUpConnection(false, Phone.REASON_RADIO_TURNED_OFF);
@@ -716,6 +650,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onDataSetupComplete(AsyncResult ar) {
String reason = null;
if (ar.userObj instanceof String) {
@@ -723,6 +658,10 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
if (ar.exception == null) {
+ // TODO: We should clear LinkProperties/Capabilities when torn down or disconnected
+ mLinkProperties = getLinkProperties(mPendingDataConnection);
+ mLinkCapabilities = getLinkCapabilities(mPendingDataConnection);
+
// everything is setup
notifyDefaultData(reason);
} else {
@@ -741,8 +680,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
/**
* Called when EVENT_DISCONNECT_DONE is received.
*/
- protected void onDisconnectDone(AsyncResult ar) {
- if(DBG) log("EVENT_DISCONNECT_DONE");
+ @Override
+ protected void onDisconnectDone(int connId, AsyncResult ar) {
+ if(DBG) log("EVENT_DISCONNECT_DONE connId=" + connId);
String reason = null;
if (ar.userObj instanceof String) {
reason = (String) ar.userObj;
@@ -762,7 +702,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
onRestartRadio();
}
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
mActiveApn = null;
if (retryAfterDisconnected(reason)) {
trySetupData(reason);
@@ -786,25 +726,29 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onVoiceCallStarted() {
- if (state == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
+ if (mState == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
stopNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
+ notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
+ notifyDataAvailability(Phone.REASON_VOICE_CALL_STARTED);
}
}
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onVoiceCallEnded() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
if (!mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
startNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
+ notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
} else {
// clean slate after call end.
resetPollStats();
}
+ notifyDataAvailability(Phone.REASON_VOICE_CALL_ENDED);
} else {
mRetryMgr.resetRetryCount();
// in case data setup was attempted when we were on a voice call
@@ -812,39 +756,49 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
}
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
+ @Override
protected void onCleanUpConnection(boolean tearDown, String reason) {
cleanUpConnection(tearDown, reason);
}
private void createAllDataConnectionList() {
- dataConnectionList = new ArrayList<DataConnection>();
CdmaDataConnection dataConn;
- for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) {
- dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone);
- dataConnectionList.add(dataConn);
- }
+ /** TODO: Use one retry manager for all connections for now */
+ RetryManager rm = mRetryMgr;
+ if (!rm.configure(SystemProperties.get("ro.cdma.data_retry_config"))) {
+ if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
+ // Should never happen, log an error and default to a simple linear sequence.
+ log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
+ + DEFAULT_DATA_RETRY_CONFIG);
+ rm.configure(20, 2000, 1000);
+ }
+ }
+
+ for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) {
+ int id = mUniqueIdGenerator.getAndIncrement();
+
+ dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm);
+ mDataConnections.put(id, dataConn);
+ }
}
private void destroyAllDataConnectionList() {
- if(dataConnectionList != null) {
- dataConnectionList.removeAll(dataConnectionList);
+ if(mDataConnections != null) {
+ mDataConnections.clear();
}
}
private void onCdmaDataDetached() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
startNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED);
+ notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED);
} else {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED);
mRetryMgr.resetRetryCount();
- CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
+ CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.CDMA_DATA_SETUP_FAILED,
loc != null ? loc.getBaseStationId() : -1,
TelephonyManager.getDefault().getNetworkType());
@@ -871,8 +825,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
private void onRestartRadio() {
if (mPendingRestartRadio) {
- Log.d(LOG_TAG, "************TURN OFF RADIO**************");
- phone.mCM.setRadioPower(false, null);
+ log("************TURN OFF RADIO**************");
+ mPhone.mCM.setRadioPower(false, null);
/* Note: no need to call setRadioPower(true). Assuming the desired
* radio power state is still ON (as tracked by ServiceStateTracker),
* ServiceStateTracker will call setRadioPower when it receives the
@@ -885,7 +839,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
private void writeEventLogCdmaDataDrop() {
- CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
+ CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.CDMA_DATA_DROP,
loc != null ? loc.getBaseStationId() : -1,
TelephonyManager.getDefault().getNetworkType());
@@ -901,7 +855,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
return;
}
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
boolean isActiveOrDormantConnectionPresent = false;
int connectionState = DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE;
@@ -917,7 +871,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
if (!isActiveOrDormantConnectionPresent) {
// No active or dormant connection
- Log.i(LOG_TAG, "onDataStateChanged: No active connection"
+ log("onDataStateChanged: No active connection"
+ "state is CONNECTED, disconnecting/cleanup");
writeEventLogCdmaDataDrop();
cleanUpConnection(true, null);
@@ -926,59 +880,27 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
switch (connectionState) {
case DATA_CONNECTION_ACTIVE_PH_LINK_UP:
- Log.v(LOG_TAG, "onDataStateChanged: active=LINK_ACTIVE && CONNECTED, ignore");
- activity = Activity.NONE;
- phone.notifyDataActivity();
+ log("onDataStateChanged: active=LINK_ACTIVE && CONNECTED, ignore");
+ mActivity = Activity.NONE;
+ mPhone.notifyDataActivity();
startNetStatPoll();
break;
case DATA_CONNECTION_ACTIVE_PH_LINK_DOWN:
- Log.v(LOG_TAG, "onDataStateChanged active=LINK_DOWN && CONNECTED, dormant");
- activity = Activity.DORMANT;
- phone.notifyDataActivity();
+ log("onDataStateChanged active=LINK_DOWN && CONNECTED, dormant");
+ mActivity = Activity.DORMANT;
+ mPhone.notifyDataActivity();
stopNetStatPoll();
break;
default:
- Log.v(LOG_TAG, "onDataStateChanged: IGNORE unexpected DataCallState.active="
+ log("onDataStateChanged: IGNORE unexpected DataCallState.active="
+ connectionState);
}
} else {
// TODO: Do we need to do anything?
- Log.i(LOG_TAG, "onDataStateChanged: not connected, state=" + state + " ignoring");
- }
- }
-
- protected String getInterfaceName(String apnType) {
- if (mActiveDataConnection != null) {
- return mActiveDataConnection.getInterface();
- }
- return null;
- }
-
- protected String getIpAddress(String apnType) {
- if (mActiveDataConnection != null) {
- return mActiveDataConnection.getIpAddress();
- }
- return null;
- }
-
- protected String getGateway(String apnType) {
- if (mActiveDataConnection != null) {
- return mActiveDataConnection.getGatewayAddress();
+ log("onDataStateChanged: not connected, state=" + mState + " ignoring");
}
- return null;
- }
-
- protected String[] getDnsServers(String apnType) {
- if (mActiveDataConnection != null) {
- return mActiveDataConnection.getDnsServers();
- }
- return null;
- }
-
- public ArrayList<DataConnection> getAllDataConnections() {
- return dataConnectionList;
}
private void startDelayedRetry(FailCause cause, String reason) {
@@ -986,10 +908,11 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
reconnectAfterFail(cause, reason);
}
+ @Override
public void handleMessage (Message msg) {
- if (!phone.mIsTheCurrentActivePhone) {
- Log.d(LOG_TAG, "Ignore CDMA msgs since CDMA phone is inactive");
+ if (!mPhone.mIsTheCurrentActivePhone) {
+ log("Ignore CDMA msgs since CDMA phone is inactive");
return;
}
@@ -1026,7 +949,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
}
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[CdmaDataConnectionTracker] " + s);
}
+
+ @Override
+ protected void loge(String s) {
+ Log.e(LOG_TAG, "[CdmaDataConnectionTracker] " + s);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index dceff2a..37a33bc 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -70,6 +70,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
* @param ar AsyncResult passed into the message handler. ar.result should
* be a String representing the status report PDU, as ASCII hex.
*/
+ @Override
protected void handleStatusReport(AsyncResult ar) {
Log.d(TAG, "handleStatusReport is a special GSM function, should never be called in CDMA!");
}
@@ -92,6 +93,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected int dispatchMessage(SmsMessageBase smsb) {
// If sms is null, means there was a parsing error.
@@ -335,6 +337,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void sendData(String destAddr, String scAddr, int destPort,
byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
@@ -343,6 +346,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void sendText(String destAddr, String scAddr, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
@@ -351,6 +355,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void sendMultipartText(String destAddr, String scAddr,
ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
ArrayList<PendingIntent> deliveryIntents) {
@@ -359,7 +364,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
* TODO(cleanup): There is no real code difference between
* this and the GSM version, and hence it should be moved to
* the base class or consolidated somehow, provided calling
- * the proper submitpdu stuff can be arranged.
+ * the proper submit pdu stuff can be arranged.
*/
int refNumber = getNextConcatenatedRef() & 0x00FF;
@@ -432,8 +437,9 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void sendSms(SmsTracker tracker) {
- HashMap map = tracker.mData;
+ HashMap<String, Object> map = tracker.mData;
// byte smsc[] = (byte[]) map.get("smsc"); // unused for CDMA
byte pdu[] = (byte[]) map.get("pdu");
@@ -444,11 +450,13 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void sendMultipartSms (SmsTracker tracker) {
Log.d(TAG, "TODO: CdmaSMSDispatcher.sendMultipartSms not implemented");
}
/** {@inheritDoc} */
+ @Override
protected void acknowledgeLastIncomingSms(boolean success, int result, Message response){
// FIXME unit test leaves cm == null. this should change
@@ -469,16 +477,19 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void activateCellBroadcastSms(int activate, Message response) {
mCm.setCdmaBroadcastActivation((activate == 0), response);
}
/** {@inheritDoc} */
+ @Override
protected void getCellBroadcastSmsConfig(Message response) {
mCm.getCdmaBroadcastConfig(response);
}
/** {@inheritDoc} */
+ @Override
protected void setCellBroadcastConfig(int[] configValuesArray, Message response) {
mCm.setCdmaBroadcastConfig(configValuesArray, response);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index d2a4bd8..c006fcf 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -16,6 +16,17 @@
package com.android.internal.telephony.cdma;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.DataConnectionTracker;
+import com.android.internal.telephony.EventLogTags;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.MccTable;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.ServiceStateTracker;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
+
import android.app.AlarmManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -38,19 +49,8 @@ import android.telephony.cdma.CdmaCellLocation;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
-import android.util.Config;
import android.util.TimeUtils;
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
-
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
@@ -66,6 +66,13 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
CdmaCellLocation cellLoc;
CdmaCellLocation newCellLoc;
+ // Min values used to by getOtasp()
+ private static final String UNACTIVATED_MIN2_VALUE = "000000";
+ private static final String UNACTIVATED_MIN_VALUE = "1111110111";
+
+ // Current Otasp value
+ int mCurrentOtaspMode = OTASP_UNINITIALIZED;
+
/** if time between NITZ updates is less than mNitzUpdateSpacing the update may be ignored. */
private static final int NITZ_UPDATE_SPACING_DEFAULT = 1000 * 60 * 10;
private int mNitzUpdateSpacing = SystemProperties.getInt("ro.nitz_update_spacing",
@@ -447,6 +454,13 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
if (!mIsMinInfoReady) {
mIsMinInfoReady = true;
}
+ int otaspMode = getOtasp();
+ if (mCurrentOtaspMode != otaspMode) {
+ Log.d(LOG_TAG, "call phone.notifyOtaspChanged old otaspMode=" +
+ mCurrentOtaspMode + " new otaspMode=" + otaspMode);
+ mCurrentOtaspMode = otaspMode;
+ phone.notifyOtaspChanged(mCurrentOtaspMode);
+ }
phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
null);
} else {
@@ -643,6 +657,11 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
curPlmn = plmn;
}
+ @Override
+ protected Phone getPhone() {
+ return phone;
+ }
+
/**
* Handle the result of one of the pollState()-related requests
*/
@@ -1008,7 +1027,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
mNeedFixZone = false;
if (zone != null) {
- if (getAutoTime()) {
+ if (getAutoTimeZone()) {
setAndBroadcastNetworkSetTimeZone(zone.getID());
}
saveNitzTimeZone(zone.getID());
@@ -1140,7 +1159,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
if (hasCdmaDataConnectionChanged || hasNetworkTypeChanged) {
- phone.notifyDataConnection(null);
+ phone.notifyDataConnection();
}
if (hasRoamingOn) {
@@ -1460,7 +1479,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
if (zone != null) {
- if (getAutoTime()) {
+ if (getAutoTimeZone()) {
setAndBroadcastNetworkSetTimeZone(zone.getID());
}
saveNitzTimeZone(zone.getID());
@@ -1550,6 +1569,14 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
}
+ private boolean getAutoTimeZone() {
+ try {
+ return Settings.System.getInt(cr, Settings.System.AUTO_TIME_ZONE) > 0;
+ } catch (SettingNotFoundException snfe) {
+ return true;
+ }
+ }
+
private void saveNitzTimeZone(String zoneId) {
mSavedTimeZone = zoneId;
}
@@ -1634,10 +1661,6 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
return false;
}
- protected void log(String s) {
- Log.d(LOG_TAG, "[CdmaServiceStateTracker] " + s);
- }
-
public String getMdnNumber() {
return mMdn;
}
@@ -1693,6 +1716,32 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
}
+ /**
+ * Returns OTASP_UNKNOWN, OTASP_NEEDED or OTASP_NOT_NEEDED
+ */
+ int getOtasp() {
+ int provisioningState;
+ if (mMin == null || (mMin.length() < 6)) {
+ if (DBG) Log.d(LOG_TAG, "getOtasp: bad mMin='" + mMin + "'");
+ provisioningState = OTASP_UNKNOWN;
+ } else {
+ if ((mMin.equals(UNACTIVATED_MIN_VALUE)
+ || mMin.substring(0,6).equals(UNACTIVATED_MIN2_VALUE))
+ || SystemProperties.getBoolean("test_cdma_setup", false)) {
+ provisioningState = OTASP_NEEDED;
+ } else {
+ provisioningState = OTASP_NOT_NEEDED;
+ }
+ }
+ if (DBG) Log.d(LOG_TAG, "getOtasp: state=" + provisioningState);
+ return provisioningState;
+ }
+
+ @Override
+ protected void log(String s) {
+ Log.d(LOG_TAG, "[CdmaServiceStateTracker] " + s);
+ }
+
private void hangupAndPowerOff() {
// hang up all active voice calls
phone.mCT.ringingCall.hangupIfAlive();
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
index e97549d..d84b6ab 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
@@ -68,8 +68,7 @@ public class RuimSmsInterfaceManager extends IccSmsInterfaceManager {
ar = (AsyncResult)msg.obj;
synchronized (mLock) {
if (ar.exception == null) {
- mSms = (List<SmsRawData>)
- buildValidRawData((ArrayList<byte[]>) ar.result);
+ mSms = buildValidRawData((ArrayList<byte[]>) ar.result);
} else {
if(DBG) log("Cannot load Sms records");
if (mSms != null)
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index d563dc8..8accfd1 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -18,11 +18,8 @@ package com.android.internal.telephony.cdma;
import android.os.Parcel;
import android.os.SystemProperties;
-import android.text.format.Time;
import android.util.Config;
import android.util.Log;
-import com.android.internal.telephony.EncodeException;
-import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
@@ -34,7 +31,6 @@ import com.android.internal.telephony.cdma.sms.SmsEnvelope;
import com.android.internal.telephony.cdma.sms.UserData;
import com.android.internal.util.HexDump;
-import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index ab79fe9..cf06dab 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -21,7 +21,6 @@ import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
import android.util.Log;
-import android.util.SparseIntArray;
import android.telephony.SmsMessage;
@@ -30,10 +29,8 @@ import android.text.format.Time;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.cdma.sms.UserData;
import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.util.HexDump;
import com.android.internal.util.BitwiseInputStream;
import com.android.internal.util.BitwiseOutputStream;
@@ -45,13 +42,13 @@ public final class BearerData {
private final static String LOG_TAG = "SMS";
/**
- * Bearer Data Subparameter Indentifiers
+ * Bearer Data Subparameter Identifiers
* (See 3GPP2 C.S0015-B, v2.0, table 4.5-1)
* NOTE: Commented subparameter types are not implemented.
*/
private final static byte SUBPARAM_MESSAGE_IDENTIFIER = 0x00;
private final static byte SUBPARAM_USER_DATA = 0x01;
- private final static byte SUBPARAM_USER_REPONSE_CODE = 0x02;
+ private final static byte SUBPARAM_USER_RESPONSE_CODE = 0x02;
private final static byte SUBPARAM_MESSAGE_CENTER_TIME_STAMP = 0x03;
private final static byte SUBPARAM_VALIDITY_PERIOD_ABSOLUTE = 0x04;
private final static byte SUBPARAM_VALIDITY_PERIOD_RELATIVE = 0x05;
@@ -697,7 +694,7 @@ public final class BearerData {
/*
* TODO(cleanup): CdmaSmsAddress encoding should make use of
* CdmaSmsAddress.parse provided that DTMF encoding is unified,
- * and the difference in 4bit vs 8bit is resolved.
+ * and the difference in 4-bit vs. 8-bit is resolved.
*/
private static void encodeCdmaSmsAddress(CdmaSmsAddress addr) throws CodingException {
@@ -805,6 +802,7 @@ public final class BearerData {
* (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
*
* @param bData an instance of BearerData.
+ *
* @return byte array of raw encoded SMS bearer data.
*/
public static byte[] encode(BearerData bData) {
@@ -915,7 +913,7 @@ public final class BearerData {
private static String decodeUtf16(byte[] data, int offset, int numFields)
throws CodingException
{
- // Start reading from the next 16-bit aligned boundry after offset.
+ // Start reading from the next 16-bit aligned boundary after offset.
int padding = offset % 2;
numFields -= (offset + padding) / 2;
try {
@@ -961,7 +959,7 @@ public final class BearerData {
private static String decode7bitGsm(byte[] data, int offset, int numFields)
throws CodingException
{
- // Start reading from the next 7-bit aligned boundry after offset.
+ // Start reading from the next 7-bit aligned boundary after offset.
int offsetBits = offset * 8;
int offsetSeptets = (offsetBits + 6) / 7;
numFields -= offsetSeptets;
@@ -1554,7 +1552,7 @@ public final class BearerData {
case SUBPARAM_USER_DATA:
decodeSuccess = decodeUserData(bData, inStream);
break;
- case SUBPARAM_USER_REPONSE_CODE:
+ case SUBPARAM_USER_RESPONSE_CODE:
decodeSuccess = decodeUserResponseCode(bData, inStream);
break;
case SUBPARAM_REPLY_OPTION:
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
index 4f00163..4a60231 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
@@ -19,7 +19,7 @@ package com.android.internal.telephony.cdma.sms;
import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
-public final class SmsEnvelope{
+public final class SmsEnvelope {
/**
* Message Types
* (See 3GPP2 C.S0015-B 3.4.1)
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index 3959c67..fc03d1a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -287,7 +287,7 @@ public class GSMPhone extends PhoneBase {
return mPendingMMIs;
}
- public DataState getDataConnectionState() {
+ public DataState getDataConnectionState(String apnType) {
DataState ret = DataState.DISCONNECTED;
if (mSST == null) {
@@ -300,6 +300,8 @@ public class GSMPhone extends PhoneBase {
// If we're out of service, open TCP sockets may still work
// but no data will flow
ret = DataState.DISCONNECTED;
+ } else if (mDataConnection.isApnTypeEnabled(apnType) == false) {
+ ret = DataState.DISCONNECTED;
} else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */
switch (mDataConnection.getState()) {
case FAILED:
@@ -401,8 +403,8 @@ public class GSMPhone extends PhoneBase {
}
/*package*/ void
- notifyDataConnectionFailed(String reason) {
- mNotifier.notifyDataConnectionFailed(this, reason);
+ notifyDataConnectionFailed(String reason, String apnType) {
+ mNotifier.notifyDataConnectionFailed(this, reason, apnType);
}
/*package*/ void
@@ -1091,27 +1093,6 @@ public class GSMPhone extends PhoneBase {
}
/**
- * The only circumstances under which we report that data connectivity is not
- * possible are
- * <ul>
- * <li>Data roaming is disallowed and we are roaming.</li>
- * <li>The current data state is {@code DISCONNECTED} for a reason other than
- * having explicitly disabled connectivity. In other words, data is not available
- * because the phone is out of coverage or some like reason.</li>
- * </ul>
- * @return {@code true} if data connectivity is possible, {@code false} otherwise.
- */
- public boolean isDataConnectivityPossible() {
- // TODO: Currently checks if any GPRS connection is active. Should it only
- // check for "default"?
- boolean noData = mDataConnection.getDataEnabled() &&
- getDataConnectionState() == DataState.DISCONNECTED;
- return !noData && getIccCard().getState() == SimCard.State.READY &&
- getServiceState().getState() == ServiceState.STATE_IN_SERVICE &&
- (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming());
- }
-
- /**
* Removes the given MMI from the pending list and notifies
* registrants that it is complete.
* @param mmi MMI that is done
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 09d46dd..d428099 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -23,6 +23,7 @@ import android.util.Patterns;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.RetryManager;
/**
* {@hide}
@@ -53,23 +54,27 @@ public class GsmDataConnection extends DataConnection {
private ApnSetting apn;
//***** Constructor
- private GsmDataConnection(GSMPhone phone, String name) {
- super(phone, name);
+ private GsmDataConnection(GSMPhone phone, String name, RetryManager rm) {
+ super(phone, name, rm);
}
/**
* Create the connection object
*
- * @param phone
+ * @param phone the Phone
+ * @param id the connection id
+ * @param rm the RetryManager
* @return GsmDataConnection that was created.
*/
- static GsmDataConnection makeDataConnection(GSMPhone phone) {
+ static GsmDataConnection makeDataConnection(GSMPhone phone, int id, RetryManager rm) {
synchronized (mCountLock) {
mCount += 1;
}
- GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDataConnection-" + mCount);
+ GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDataConnection-" + mCount, rm);
gsmDc.start();
if (DBG) gsmDc.log("Made " + gsmDc.getName());
+ gsmDc.mId = id;
+ gsmDc.mRetryMgr = rm;
return gsmDc;
}
@@ -180,8 +185,8 @@ public class GsmDataConnection extends DataConnection {
@Override
protected boolean isDnsOk(String[] domainNameServers) {
- if (NULL_IP.equals(dnsServers[0]) && NULL_IP.equals(dnsServers[1])
- && !((GSMPhone) phone).isDnsCheckDisabled()) {
+ if (NULL_IP.equals(domainNameServers[0]) && NULL_IP.equals(domainNameServers[1])
+ && !((GSMPhone) phone).isDnsCheckDisabled()) {
// Work around a race condition where QMI does not fill in DNS:
// Deactivate PDP and let DataConnectionTracker retry.
// Do not apply the race condition workaround for MMS APN
@@ -189,6 +194,9 @@ public class GsmDataConnection extends DataConnection {
// Otherwise, the default APN will not be restored anymore.
if (!apn.types[0].equals(Phone.APN_TYPE_MMS)
|| !isIpAddress(apn.mmsProxy)) {
+ log(String.format(
+ "isDnsOk: return false apn.types[0]=%s APN_TYPE_MMS=%s isIpAddress(%s)=%s",
+ apn.types[0], Phone.APN_TYPE_MMS, apn.mmsProxy, isIpAddress(apn.mmsProxy)));
return false;
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index e7d57bc..2aca9ad 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -18,28 +18,19 @@ package com.android.internal.telephony.gsm;
import android.app.AlarmManager;
import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
-import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
-import android.net.NetworkInfo;
+import android.net.ProxyProperties;
import android.net.TrafficStats;
import android.net.Uri;
-import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Telephony;
import android.telephony.ServiceState;
@@ -58,7 +49,11 @@ import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.DataConnection.FailCause;
import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.HashMap;
/**
* {@hide}
@@ -83,9 +78,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
//***** Instance Variables
- // Indicates baseband will not auto-attach
- private boolean noAutoAttach = false;
-
private boolean mReregisterOnReconnectFailure = false;
private ContentResolver mResolver;
@@ -93,13 +85,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// Count of PDP reset attempts; reset when we see incoming,
// call reRegisterNetwork, or pingTest succeeds.
private int mPdpResetCount = 0;
- private boolean mIsScreenOn = true;
/** Delay between APN attempts */
protected static final int APN_DELAY_MILLIS = 5000;
//useful for debugging
- boolean failNextConnect = false;
+ boolean mFailNextConnect = false;
/**
* allApns holds all apns for this sim spn, retrieved from
@@ -107,104 +98,49 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
*
* Create once after simcard info is loaded
*/
- private ArrayList<ApnSetting> allApns = null;
+ private ArrayList<ApnSetting> mAllApns = null;
/**
* waitingApns holds all apns that are waiting to be connected
*
* It is a subset of allApns and has the same format
*/
- private ArrayList<ApnSetting> waitingApns = null;
+ private ArrayList<ApnSetting> mWaitingApns = null;
- private ApnSetting preferredApn = null;
+ private ApnSetting mPreferredApn = null;
/* Currently active APN */
protected ApnSetting mActiveApn;
- /**
- * pdpList holds all the PDP connection, i.e. IP Link in GPRS
- */
- private ArrayList<DataConnection> pdpList;
+ /** The DataConnection being setup */
+ private GsmDataConnection mPendingDataConnection;
- /** Currently active DataConnection */
- private GsmDataConnection mActivePdp;
+ /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
+ private HashMap<String, Integer> mApnToDataConnectionId =
+ new HashMap<String, Integer>();
/** Is packet service restricted by network */
private boolean mIsPsRestricted = false;
//***** Constants
- // TODO: Increase this to match the max number of simultaneous
- // PDP contexts we plan to support.
- /**
- * Pool size of DataConnection objects.
- */
- private static final int PDP_CONNECTION_POOL_SIZE = 1;
-
private static final int POLL_PDP_MILLIS = 5 * 1000;
private static final String INTENT_RECONNECT_ALARM = "com.android.internal.telephony.gprs-reconnect";
- private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason";
static final Uri PREFERAPN_URI = Uri.parse("content://telephony/carriers/preferapn");
static final String APN_ID = "apn_id";
private boolean canSetPreferApn = false;
- // for tracking retries on the default APN
- private RetryManager mDefaultRetryManager;
- // for tracking retries on a secondary APN
- private RetryManager mSecondaryRetryManager;
-
- BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_SCREEN_ON)) {
- mIsScreenOn = true;
- stopNetStatPoll();
- startNetStatPoll();
- } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
- mIsScreenOn = false;
- stopNetStatPoll();
- startNetStatPoll();
- } else if (action.equals((INTENT_RECONNECT_ALARM))) {
- Log.d(LOG_TAG, "GPRS reconnect alarm. Previous state was " + state);
-
- String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
- if (state == State.FAILED) {
- Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
- msg.arg1 = 0; // tearDown is false
- msg.obj = (String) reason;
- sendMessage(msg);
- }
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
- } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
- final android.net.NetworkInfo networkInfo = (NetworkInfo)
- intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
- mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
- } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
- final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
- WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
-
- if (!enabled) {
- // when wifi got disabled, the NETWORK_STATE_CHANGED_ACTION
- // quit and won't report disconnected til next enabling.
- mIsWifiConnected = false;
- }
- }
- }
- };
-
/** Watches for changes to the APN db. */
- private ApnChangeObserver apnObserver;
+ private ApnChangeObserver mApnObserver;
//***** Constructor
GsmDataConnectionTracker(GSMPhone p) {
super(p);
mGsmPhone = p;
+
p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
p.mSIMRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
@@ -218,73 +154,26 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
p.mSST.registerForPsRestrictedEnabled(this, EVENT_PS_RESTRICT_ENABLED, null);
p.mSST.registerForPsRestrictedDisabled(this, EVENT_PS_RESTRICT_DISABLED, null);
- IntentFilter filter = new IntentFilter();
- filter.addAction(INTENT_RECONNECT_ALARM);
- filter.addAction(Intent.ACTION_SCREEN_ON);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-
- // TODO: Why is this registering the phone as the receiver of the intent
- // and not its own handler?
- p.getContext().registerReceiver(mIntentReceiver, filter, null, p);
-
-
mDataConnectionTracker = this;
- mResolver = phone.getContext().getContentResolver();
+ mResolver = mPhone.getContext().getContentResolver();
- apnObserver = new ApnChangeObserver();
+ mApnObserver = new ApnChangeObserver();
p.getContext().getContentResolver().registerContentObserver(
- Telephony.Carriers.CONTENT_URI, true, apnObserver);
-
- createAllPdpList();
-
- // This preference tells us 1) initial condition for "dataEnabled",
- // and 2) whether the RIL will setup the baseband to auto-PS attach.
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(phone.getContext());
- boolean dataEnabledSetting = true;
- try {
- dataEnabledSetting = IConnectivityManager.Stub.asInterface(ServiceManager.
- getService(Context.CONNECTIVITY_SERVICE)).getMobileDataEnabled();
- } catch (Exception e) {
- // nothing to do - use the old behavior and leave data on
- }
- dataEnabled[APN_DEFAULT_ID] = !sp.getBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, false) &&
- dataEnabledSetting;
- if (dataEnabled[APN_DEFAULT_ID]) {
- enabledCount++;
- }
- noAutoAttach = !dataEnabled[APN_DEFAULT_ID];
-
- if (!mRetryMgr.configure(SystemProperties.get("ro.gsm.data_retry_config"))) {
- if (!mRetryMgr.configure(DEFAULT_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple linear sequence.
- Log.e(LOG_TAG, "Could not configure using DEFAULT_DATA_RETRY_CONFIG="
- + DEFAULT_DATA_RETRY_CONFIG);
- mRetryMgr.configure(20, 2000, 1000);
- }
- }
-
- mDefaultRetryManager = mRetryMgr;
- mSecondaryRetryManager = new RetryManager();
+ Telephony.Carriers.CONTENT_URI, true, mApnObserver);
- if (!mSecondaryRetryManager.configure(SystemProperties.get(
- "ro.gsm.2nd_data_retry_config"))) {
- if (!mSecondaryRetryManager.configure(SECONDARY_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple sequence.
- Log.e(LOG_TAG, "Could note configure using SECONDARY_DATA_RETRY_CONFIG="
- + SECONDARY_DATA_RETRY_CONFIG);
- mSecondaryRetryManager.configure("max_retries=3, 333, 333, 333");
- }
- }
+ /** Create the default connection */
+ createDataConnection(Phone.APN_TYPE_DEFAULT);
}
+ @Override
public void dispose() {
+ super.dispose();
+
//Unregister for all events
- phone.mCM.unregisterForAvailable(this);
- phone.mCM.unregisterForOffOrNotAvailable(this);
+ mPhone.mCM.unregisterForAvailable(this);
+ mPhone.mCM.unregisterForOffOrNotAvailable(this);
mGsmPhone.mSIMRecords.unregisterForRecordsLoaded(this);
- phone.mCM.unregisterForDataStateChanged(this);
+ mPhone.mCM.unregisterForDataStateChanged(this);
mGsmPhone.mCT.unregisterForVoiceCallEnded(this);
mGsmPhone.mCT.unregisterForVoiceCallStarted(this);
mGsmPhone.mSST.unregisterForGprsAttached(this);
@@ -294,29 +183,36 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
mGsmPhone.mSST.unregisterForPsRestrictedEnabled(this);
mGsmPhone.mSST.unregisterForPsRestrictedDisabled(this);
- phone.getContext().unregisterReceiver(this.mIntentReceiver);
- phone.getContext().getContentResolver().unregisterContentObserver(this.apnObserver);
+ mPhone.getContext().getContentResolver().unregisterContentObserver(this.mApnObserver);
- destroyAllPdpList();
+ destroyDataConnections();
}
+ @Override
protected void finalize() {
- if(DBG) Log.d(LOG_TAG, "GsmDataConnectionTracker finalized");
+ if(DBG) log("finalize");
}
+ @Override
+ protected String getActionIntentReconnectAlarm() {
+ return INTENT_RECONNECT_ALARM;
+ }
+
+ @Override
protected void setState(State s) {
if (DBG) log ("setState: " + s);
- if (state != s) {
- EventLog.writeEvent(EventLogTags.GSM_DATA_STATE_CHANGE, state.toString(), s.toString());
- state = s;
+ if (mState != s) {
+ EventLog.writeEvent(EventLogTags.GSM_DATA_STATE_CHANGE, mState.toString(), s.toString());
+ mState = s;
}
- if (state == State.FAILED) {
- if (waitingApns != null)
- waitingApns.clear(); // when teardown the connection and set to IDLE
+ if (mState == State.FAILED) {
+ if (mWaitingApns != null)
+ mWaitingApns.clear(); // when tear down the connection and set to IDLE
}
}
+ @Override
public String[] getActiveApnTypes() {
String[] result;
if (mActiveApn != null) {
@@ -328,6 +224,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return result;
}
+ @Override
protected String getActiveApnString() {
String result = null;
if (mActiveApn != null) {
@@ -345,15 +242,16 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
*
* @return false while no data connection if all above requirements are met.
*/
+ @Override
public boolean isDataConnectionAsDesired() {
- boolean roaming = phone.getServiceState().getRoaming();
+ boolean roaming = mPhone.getServiceState().getRoaming();
if (mGsmPhone.mSIMRecords.getRecordsLoaded() &&
mGsmPhone.mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE &&
(!roaming || getDataOnRoamingEnabled()) &&
!mIsWifiConnected &&
!mIsPsRestricted ) {
- return (state == State.CONNECTED);
+ return (mState == State.CONNECTED);
}
return true;
}
@@ -370,8 +268,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return (fetchDunApn() != null);
}
- if (allApns != null) {
- for (ApnSetting apn : allApns) {
+ if (mAllApns != null) {
+ for (ApnSetting apn : mAllApns) {
if (apn.canHandleType(type)) {
return true;
}
@@ -380,20 +278,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return false;
}
- /**
- * Formerly this method was ArrayList<GsmDataConnection> getAllPdps()
- */
- public ArrayList<DataConnection> getAllDataConnections() {
- ArrayList<DataConnection> pdps = (ArrayList<DataConnection>)pdpList.clone();
- return pdps;
- }
-
- private boolean isDataAllowed() {
- boolean roaming = phone.getServiceState().getRoaming();
- return getAnyDataEnabled() && (!roaming || getDataOnRoamingEnabled()) &&
- mMasterDataEnabled;
- }
-
//****** Called from ServiceStateTracker
/**
* Invoked when ServiceStateTracker observes a transition from GPRS
@@ -405,15 +289,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
* when GPRS detaches, but we should stop the network polling.
*/
stopNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_GPRS_DETACHED);
+ notifyDataConnection(Phone.REASON_GPRS_DETACHED);
}
private void onGprsAttached() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
startNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_GPRS_ATTACHED);
+ notifyDataConnection(Phone.REASON_GPRS_ATTACHED);
} else {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, Phone.REASON_GPRS_ATTACHED);
mRetryMgr.resetRetryCount();
}
@@ -421,74 +305,91 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
+ @Override
+ protected boolean isDataAllowed() {
+ int gprsState = mGsmPhone.mSST.getCurrentGprsState();
+ boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState();
+
+ boolean allowed =
+ (gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
+ mGsmPhone.mSIMRecords.getRecordsLoaded() &&
+ mPhone.getState() == Phone.State.IDLE &&
+ mMasterDataEnabled &&
+ (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
+ !mIsPsRestricted &&
+ desiredPowerState;
+ if (!allowed && DBG) {
+ String reason = "";
+ if (!((gprsState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
+ reason += " - gprs= " + gprsState;
+ }
+ if (!mGsmPhone.mSIMRecords.getRecordsLoaded()) reason += " - SIM not loaded";
+ if (mPhone.getState() != Phone.State.IDLE) {
+ reason += " - PhoneState= " + mPhone.getState();
+ }
+ if (!mMasterDataEnabled) reason += " - mMasterDataEnabled= false";
+ if (mPhone.getServiceState().getRoaming() && getDataOnRoamingEnabled()) {
+ reason += " - Roaming";
+ }
+ if (mIsPsRestricted) reason += " - mIsPsRestricted= true";
+ if (!desiredPowerState) reason += " - desiredPowerState= false";
+ log("Data not allowed due to" + reason);
+ }
+ return allowed;
+ }
+
private boolean trySetupData(String reason) {
if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason));
- Log.d(LOG_TAG, "[DSAC DEB] " + "trySetupData with mIsPsRestricted=" + mIsPsRestricted);
+ log("[DSAC DEB] " + "trySetupData with mIsPsRestricted=" + mIsPsRestricted);
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
setState(State.CONNECTED);
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
- Log.i(LOG_TAG, "(fix?) We're on the simulator; assuming data is connected");
+ log("(fix?) We're on the simulator; assuming data is connected");
return true;
}
int gprsState = mGsmPhone.mSST.getCurrentGprsState();
boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState();
- if ((state == State.IDLE || state == State.SCANNING)
- && (gprsState == ServiceState.STATE_IN_SERVICE || noAutoAttach)
- && mGsmPhone.mSIMRecords.getRecordsLoaded()
- && phone.getState() == Phone.State.IDLE
- && isDataAllowed()
- && !mIsPsRestricted
- && desiredPowerState ) {
-
- if (state == State.IDLE) {
- waitingApns = buildWaitingApns();
- if (waitingApns.isEmpty()) {
+ if (((mState == State.IDLE) || (mState == State.SCANNING)) &&
+ isDataAllowed() && getAnyDataEnabled()) {
+
+ if (mState == State.IDLE) {
+ mWaitingApns = buildWaitingApns(mRequestedApnType);
+ if (mWaitingApns.isEmpty()) {
if (DBG) log("No APN found");
notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
+ notifyOffApnsOfAvailability(reason, false);
return false;
} else {
- log ("Create from allApns : " + apnListToString(allApns));
+ log ("Create from allApns : " + apnListToString(mAllApns));
}
}
if (DBG) {
- log ("Setup waitngApns : " + apnListToString(waitingApns));
+ log ("Setup waitngApns : " + apnListToString(mWaitingApns));
}
- return setupData(reason);
+ boolean retValue = setupData(reason);
+ notifyOffApnsOfAvailability(reason, retValue);
+ return retValue;
} else {
- if (DBG)
- log("trySetupData: Not ready for data: " +
- " dataState=" + state +
- " gprsState=" + gprsState +
- " sim=" + mGsmPhone.mSIMRecords.getRecordsLoaded() +
- " UMTS=" + mGsmPhone.mSST.isConcurrentVoiceAndData() +
- " phoneState=" + phone.getState() +
- " isDataAllowed=" + isDataAllowed() +
- " dataEnabled=" + getAnyDataEnabled() +
- " roaming=" + phone.getServiceState().getRoaming() +
- " dataOnRoamingEnable=" + getDataOnRoamingEnabled() +
- " ps restricted=" + mIsPsRestricted +
- " desiredPowerState=" + desiredPowerState +
- " MasterDataEnabled=" + mMasterDataEnabled);
+ notifyOffApnsOfAvailability(reason, false);
return false;
}
}
/**
- * If tearDown is true, this only tears down a CONNECTED session. Presently,
- * there is no mechanism for abandoning an INITING/CONNECTING session,
- * but would likely involve cancelling pending async requests or
- * setting a flag or new state to ignore them when they came in
- * @param tearDown true if the underlying GsmDataConnection should be
- * disconnected.
- * @param reason reason for the clean up.
+ * Cleanup all connections.
+ *
+ * TODO: Cleanup only a specified connection passed as a parameter.
+ *
+ * @param tearDown true if the underlying DataConnection should be disconnected.
+ * @param reason for the clean up.
*/
private void cleanUpConnection(boolean tearDown, String reason) {
if (DBG) log("Clean up connection due to " + reason);
@@ -496,7 +397,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// Clear the reconnect alarm, if set.
if (mReconnectIntent != null) {
AlarmManager am =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
+ (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
am.cancel(mReconnectIntent);
mReconnectIntent = null;
}
@@ -504,10 +405,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
setState(State.DISCONNECTING);
boolean notificationDeferred = false;
- for (DataConnection conn : pdpList) {
+ for (DataConnection conn : mDataConnections.values()) {
if (tearDown) {
if (DBG) log("cleanUpConnection: teardown, call conn.disconnect");
- conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE, reason));
+ conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE,
+ conn.getDataConnectionId(), 0, reason));
notificationDeferred = true;
} else {
if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
@@ -565,87 +467,49 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return result;
}
- private GsmDataConnection findFreePdp() {
- for (DataConnection conn : pdpList) {
- GsmDataConnection pdp = (GsmDataConnection) conn;
- if (pdp.isInactive()) {
- return pdp;
+ private GsmDataConnection findFreeDataConnection() {
+ for (DataConnection dc : mDataConnections.values()) {
+ if (dc.isInactive()) {
+ log("found free GsmDataConnection");
+ return (GsmDataConnection) dc;
}
}
+ log("NO free GsmDataConnection");
return null;
}
private boolean setupData(String reason) {
ApnSetting apn;
- GsmDataConnection pdp;
+ GsmDataConnection gdc;
apn = getNextApn();
if (apn == null) return false;
- pdp = findFreePdp();
- if (pdp == null) {
+ gdc = findFreeDataConnection();
+ if (gdc == null) {
if (DBG) log("setupData: No free GsmDataConnection found!");
return false;
}
mActiveApn = apn;
- mActivePdp = pdp;
+ mPendingDataConnection = gdc;
Message msg = obtainMessage();
msg.what = EVENT_DATA_SETUP_COMPLETE;
msg.obj = reason;
- pdp.connect(msg, apn);
+ gdc.connect(msg, apn);
setState(State.INITING);
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
return true;
}
- protected String getInterfaceName(String apnType) {
- if (mActivePdp != null &&
- (apnType == null ||
- (mActiveApn != null && mActiveApn.canHandleType(apnType)))) {
- return mActivePdp.getInterface();
- }
- return null;
- }
-
- protected String getIpAddress(String apnType) {
- if (mActivePdp != null &&
- (apnType == null ||
- (mActiveApn != null && mActiveApn.canHandleType(apnType)))) {
- return mActivePdp.getIpAddress();
- }
- return null;
- }
-
- public String getGateway(String apnType) {
- if (mActivePdp != null &&
- (apnType == null ||
- (mActiveApn != null && mActiveApn.canHandleType(apnType)))) {
- return mActivePdp.getGatewayAddress();
- }
- return null;
- }
-
- protected String[] getDnsServers(String apnType) {
- if (mActivePdp != null &&
- (apnType == null ||
- (mActiveApn != null && mActiveApn.canHandleType(apnType)))) {
- return mActivePdp.getDnsServers();
- }
- return null;
- }
-
- private boolean
- pdpStatesHasCID (ArrayList<DataCallState> states, int cid) {
+ private boolean dataCallStatesHasCID (ArrayList<DataCallState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
if (states.get(i).cid == cid) return true;
}
-
return false;
}
- private boolean
- pdpStatesHasActiveCID (ArrayList<DataCallState> states, int cid) {
+ private boolean dataCallStatesHasActiveCID (ArrayList<DataCallState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
if ((states.get(i).cid == cid) && (states.get(i).active != 0)) {
return true;
@@ -661,7 +525,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
private void onApnChanged() {
boolean isConnected;
- isConnected = (state != State.IDLE && state != State.FAILED);
+ isConnected = (mState != State.IDLE && mState != State.FAILED);
// The "current" may no longer be valid. MMS depends on this to send properly.
mGsmPhone.updateCurrentCarrierInProvider();
@@ -669,7 +533,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// TODO: It'd be nice to only do this if the changed entrie(s)
// match the current operator.
createAllApnList();
- if (state != State.DISCONNECTING) {
+ if (mState != State.DISCONNECTING) {
cleanUpConnection(isConnected, Phone.REASON_APN_CHANGED);
if (!isConnected) {
// reset reconnect timer
@@ -686,10 +550,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
* via an unsolicited response (which could have happened at any
* previous state
*/
- protected void onPdpStateChanged (AsyncResult ar, boolean explicitPoll) {
- ArrayList<DataCallState> pdpStates;
+ private void onDataStateChanged (AsyncResult ar, boolean explicitPoll) {
+ ArrayList<DataCallState> dataCallStates;
- pdpStates = (ArrayList<DataCallState>)(ar.result);
+ dataCallStates = (ArrayList<DataCallState>)(ar.result);
if (ar.exception != null) {
// This is probably "radio not available" or something
@@ -698,42 +562,42 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return;
}
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
// The way things are supposed to work, the PDP list
// should not contain the CID after it disconnects.
// However, the way things really work, sometimes the PDP
// context is still listed with active = false, which
// makes it hard to distinguish an activating context from
// an activated-and-then deactivated one.
- if (!pdpStatesHasCID(pdpStates, cidActive)) {
+ if (!dataCallStatesHasCID(dataCallStates, mCidActive)) {
// It looks like the PDP context has deactivated.
// Tear everything down and try to reconnect.
- Log.i(LOG_TAG, "PDP connection has dropped. Reconnecting");
+ log("PDP connection has dropped. Reconnecting");
// Add an event log when the network drops PDP
- GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
+ GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP,
loc != null ? loc.getCid() : -1,
TelephonyManager.getDefault().getNetworkType());
cleanUpConnection(true, null);
return;
- } else if (!pdpStatesHasActiveCID(pdpStates, cidActive)) {
+ } else if (!dataCallStatesHasActiveCID(dataCallStates, mCidActive)) {
// Here, we only consider this authoritative if we asked for the
// PDP list. If it was an unsolicited response, we poll again
// to make sure everyone agrees on the initial state.
if (!explicitPoll) {
// We think it disconnected but aren't sure...poll from our side
- phone.mCM.getPDPContextList(
+ mPhone.mCM.getPDPContextList(
this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
} else {
- Log.i(LOG_TAG, "PDP connection has dropped (active=false case). "
+ log("PDP connection has dropped (active=false case). "
+ " Reconnecting");
// Log the network drop on the event log.
- GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
+ GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP,
loc != null ? loc.getCid() : -1,
TelephonyManager.getDefault().getNetworkType());
@@ -746,7 +610,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
private void notifyDefaultData(String reason) {
setState(State.CONNECTED);
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
startNetStatPoll();
// reset reconnect timer
mRetryMgr.resetRetryCount();
@@ -756,42 +620,30 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
private void gotoIdleAndNotifyDataConnection(String reason) {
if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
setState(State.IDLE);
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
mActiveApn = null;
}
- /**
- * This is a kludge to deal with the fact that
- * the PDP state change notification doesn't always work
- * with certain RIL impl's/basebands
- *
- */
- private void startPeriodicPdpPoll() {
- removeMessages(EVENT_POLL_PDP);
-
- sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS);
- }
-
private void resetPollStats() {
- txPkts = -1;
- rxPkts = -1;
- sentSinceLastRecv = 0;
- netStatPollPeriod = POLL_NETSTAT_MILLIS;
+ mTxPkts = -1;
+ mRxPkts = -1;
+ mSentSinceLastRecv = 0;
+ mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
mNoRecvPollCount = 0;
}
private void doRecovery() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
int maxPdpReset = Settings.Secure.getInt(mResolver,
Settings.Secure.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT,
DEFAULT_MAX_PDP_RESET_FAIL);
if (mPdpResetCount < maxPdpReset) {
mPdpResetCount++;
- EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, sentSinceLastRecv);
+ EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, mSentSinceLastRecv);
cleanUpConnection(true, Phone.REASON_PDP_RESET);
} else {
mPdpResetCount = 0;
- EventLog.writeEvent(EventLogTags.PDP_REREGISTER_NETWORK, sentSinceLastRecv);
+ EventLog.writeEvent(EventLogTags.PDP_REREGISTER_NETWORK, mSentSinceLastRecv);
mGsmPhone.mSST.reRegisterNetwork(null);
}
// TODO: Add increasingly drastic recovery steps, eg,
@@ -799,23 +651,26 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
+ @Override
protected void startNetStatPoll() {
- if (state == State.CONNECTED && mPingTestActive == false && netStatPollEnabled == false) {
- Log.d(LOG_TAG, "[DataConnection] Start poll NetStat");
+ if (mState == State.CONNECTED && mPingTestActive == false && mNetStatPollEnabled == false) {
+ log("[DataConnection] Start poll NetStat");
resetPollStats();
- netStatPollEnabled = true;
+ mNetStatPollEnabled = true;
mPollNetStat.run();
}
}
+ @Override
protected void stopNetStatPoll() {
- netStatPollEnabled = false;
+ mNetStatPollEnabled = false;
removeCallbacks(mPollNetStat);
- Log.d(LOG_TAG, "[DataConnection] Stop poll NetStat");
+ log("[DataConnection] Stop poll NetStat");
}
+ @Override
protected void restartRadio() {
- Log.d(LOG_TAG, "************TURN OFF RADIO**************");
+ log("************TURN OFF RADIO**************");
cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
mGsmPhone.mSST.powerOffRadioSafely();
/* Note: no need to call setRadioPower(true). Assuming the desired
@@ -839,43 +694,43 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
Activity newActivity;
- preTxPkts = txPkts;
- preRxPkts = rxPkts;
+ preTxPkts = mTxPkts;
+ preRxPkts = mRxPkts;
- txPkts = TrafficStats.getMobileTxPackets();
- rxPkts = TrafficStats.getMobileRxPackets();
+ mTxPkts = TrafficStats.getMobileTxPackets();
+ mRxPkts = TrafficStats.getMobileRxPackets();
- //Log.d(LOG_TAG, "rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
+ //log("rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
- if (netStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
- sent = txPkts - preTxPkts;
- received = rxPkts - preRxPkts;
+ if (mNetStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
+ sent = mTxPkts - preTxPkts;
+ received = mRxPkts - preRxPkts;
if ( sent > 0 && received > 0 ) {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
newActivity = Activity.DATAINANDOUT;
mPdpResetCount = 0;
} else if (sent > 0 && received == 0) {
- if (phone.getState() == Phone.State.IDLE) {
- sentSinceLastRecv += sent;
+ if (mPhone.getState() == Phone.State.IDLE) {
+ mSentSinceLastRecv += sent;
} else {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
}
newActivity = Activity.DATAOUT;
} else if (sent == 0 && received > 0) {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
newActivity = Activity.DATAIN;
mPdpResetCount = 0;
} else if (sent == 0 && received == 0) {
newActivity = Activity.NONE;
} else {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
newActivity = Activity.NONE;
}
- if (activity != newActivity && mIsScreenOn) {
- activity = newActivity;
- phone.notifyDataActivity();
+ if (mActivity != newActivity && mIsScreenOn) {
+ mActivity = newActivity;
+ mPhone.notifyDataActivity();
}
}
@@ -883,11 +738,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
NUMBER_SENT_PACKETS_OF_HANG);
- if (sentSinceLastRecv >= watchdogTrigger) {
+ if (mSentSinceLastRecv >= watchdogTrigger) {
// we already have NUMBER_SENT_PACKETS sent without ack
if (mNoRecvPollCount == 0) {
EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET_COUNTDOWN_TRIGGERED,
- sentSinceLastRecv);
+ mSentSinceLastRecv);
}
int noRecvPollLimit = Settings.Secure.getInt(mResolver,
@@ -897,21 +752,22 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// It's possible the PDP context went down and we weren't notified.
// Start polling the context list in an attempt to recover.
if (DBG) log("no DATAIN in a while; polling PDP");
- phone.mCM.getDataCallList(obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
+ mPhone.mCM.getDataCallList(obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
mNoRecvPollCount++;
// Slow down the poll interval to let things happen
- netStatPollPeriod = Settings.Secure.getInt(mResolver,
+ mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
Settings.Secure.PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS,
POLL_NETSTAT_SLOW_MILLIS);
} else {
- if (DBG) log("Sent " + String.valueOf(sentSinceLastRecv) +
+ if (DBG) log("Sent " + String.valueOf(mSentSinceLastRecv) +
" pkts since last received");
// We've exceeded the threshold. Run ping test as a final check;
// it will proceed with recovery if ping fails.
stopNetStatPoll();
Thread pingTest = new Thread() {
+ @Override
public void run() {
runPingTest();
}
@@ -922,17 +778,17 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
} else {
mNoRecvPollCount = 0;
if (mIsScreenOn) {
- netStatPollPeriod = Settings.Secure.getInt(mResolver,
+ mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
Settings.Secure.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
} else {
- netStatPollPeriod = Settings.Secure.getInt(mResolver,
+ mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
Settings.Secure.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
POLL_NETSTAT_SCREEN_OFF_MILLIS);
}
}
- if (netStatPollEnabled) {
- mDataConnectionTracker.postDelayed(this, netStatPollPeriod);
+ if (mNetStatPollEnabled) {
+ mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
}
}
};
@@ -951,9 +807,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
status = p.waitFor();
}
} catch (IOException e) {
- Log.w(LOG_TAG, "ping failed: IOException");
+ loge("ping failed: IOException");
} catch (Exception e) {
- Log.w(LOG_TAG, "exception trying to ping");
+ loge("exception trying to ping");
}
if (status == 0) {
@@ -994,20 +850,21 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
private void reconnectAfterFail(FailCause lastFailCauseCode, String reason) {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
+ /** TODO: Retrieve retry manager from connection itself */
if (!mRetryMgr.isRetryNeeded()) {
if (!mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
// if no more retries on a secondary APN attempt, tell the world and revert.
- phone.notifyDataConnection(Phone.REASON_APN_FAILED);
+ notifyDataConnection(Phone.REASON_APN_FAILED);
onEnableApn(apnTypeToId(mRequestedApnType), DISABLED);
return;
}
if (mReregisterOnReconnectFailure) {
- // We've re-registerd once now just retry forever.
+ // We've re-registered once now just retry forever.
mRetryMgr.retryForeverUsingLastTimeout();
} else {
// Try to re-register to the network.
- Log.d(LOG_TAG, "PDP activate failed, Reregistering to the network");
+ log("PDP activate failed, Reregistering to the network");
mReregisterOnReconnectFailure = true;
mGsmPhone.mSST.reRegisterNetwork(null);
mRetryMgr.resetRetryCount();
@@ -1016,15 +873,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
int nextReconnectDelay = mRetryMgr.getRetryTimer();
- Log.d(LOG_TAG, "PDP activate failed. Scheduling next attempt for "
+ log("PDP activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
AlarmManager am =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
+ (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(INTENT_RECONNECT_ALARM);
intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
mReconnectIntent = PendingIntent.getBroadcast(
- phone.getContext(), 0, intent, 0);
+ mPhone.getContext(), 0, intent, 0);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + nextReconnectDelay,
mReconnectIntent);
@@ -1032,7 +889,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
mRetryMgr.increaseRetryCount();
if (!shouldPostNotification(lastFailCauseCode)) {
- Log.d(LOG_TAG,"NOT Posting GPRS Unavailable notification "
+ log("NOT Posting GPRS Unavailable notification "
+ "-- likely transient error");
} else {
notifyNoData(lastFailCauseCode);
@@ -1044,9 +901,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
setState(State.FAILED);
}
- protected void onRecordsLoaded() {
+ private void onRecordsLoaded() {
createAllApnList();
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, null);
}
sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED));
@@ -1054,19 +911,29 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
@Override
protected void onEnableNewApn() {
+ log("onEnableNewApn E");
// change our retry manager to use the appropriate numbers for the new APN
if (mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
- mRetryMgr = mDefaultRetryManager;
+ log("onEnableNewApn default type");
+ mRetryMgr = mPendingDataConnection.getRetryMgr();
+ mRetryMgr.resetRetryCount();
+ } else if (mApnToDataConnectionId.get(mRequestedApnType) == null) {
+ log("onEnableNewApn mRequestedApnType=" + mRequestedApnType +
+ " missing, make a new connection");
+ int id = createDataConnection(mRequestedApnType);
+ mRetryMgr = mDataConnections.get(id).getRetryMgr();
+ mRetryMgr.resetRetryCount();
} else {
- mRetryMgr = mSecondaryRetryManager;
+ log("oneEnableNewApn connection already exists, nothing to setup");
}
- mRetryMgr.resetRetryCount();
// TODO: To support simultaneous PDP contexts, this should really only call
// cleanUpConnection if it needs to free up a GsmDataConnection.
cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
+ log("onEnableNewApn X");
}
+ @Override
protected boolean onTrySetupData(String reason) {
return trySetupData(reason);
}
@@ -1086,31 +953,33 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
+ @Override
protected void onRadioAvailable() {
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
setState(State.CONNECTED);
- phone.notifyDataConnection(null);
+ notifyDataConnection(null);
- Log.i(LOG_TAG, "We're on the simulator; assuming data is connected");
+ log("We're on the simulator; assuming data is connected");
}
- if (state != State.IDLE) {
+ if (mState != State.IDLE) {
cleanUpConnection(true, null);
}
}
+ @Override
protected void onRadioOffOrNotAvailable() {
// Make sure our reconnect delay starts at the initial value
// next time the radio comes on
mRetryMgr.resetRetryCount();
mReregisterOnReconnectFailure = false;
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
- Log.i(LOG_TAG, "We're on the simulator; assuming radio off is meaningless");
+ log("We're on the simulator; assuming radio off is meaningless");
} else {
if (DBG) log("Radio is off and clean up all connection");
// TODO: Should we reset mRequestedApnType to "default"?
@@ -1118,20 +987,43 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
+ @Override
protected void onDataSetupComplete(AsyncResult ar) {
+ /** TODO: Which connection is completing should be a parameter */
String reason = null;
if (ar.userObj instanceof String) {
reason = (String) ar.userObj;
}
if (ar.exception == null) {
+ // TODO: We should clear LinkProperties/Capabilities when torn down or disconnected
+ mLinkProperties = getLinkProperties(mPendingDataConnection);
+ mLinkCapabilities = getLinkCapabilities(mPendingDataConnection);
+
+ ApnSetting apn = mPendingDataConnection.getApn();
+ if (apn.proxy != null && apn.proxy.length() != 0) {
+ try {
+ ProxyProperties proxy = new ProxyProperties();
+ proxy.setSocketAddress(new InetSocketAddress(InetAddress.getByName(apn.proxy),
+ Integer.parseInt(apn.port)));
+ mLinkProperties.setHttpProxy(proxy);
+ } catch (UnknownHostException e) {
+ loge("UnknownHostException making ProxyProperties: " + e);
+ } catch (SecurityException e) {
+ loge("SecurityException making ProxyProperties: " + e);
+ } catch (NumberFormatException e) {
+ loge("NumberFormatException making ProxyProperties (" + apn.port +
+ "): " + e);
+ }
+ }
+
// everything is setup
if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
SystemProperties.set("gsm.defaultpdpcontext.active", "true");
- if (canSetPreferApn && preferredApn == null) {
- Log.d(LOG_TAG, "PREFERRED APN is null");
- preferredApn = mActiveApn;
- setPreferredApn(preferredApn.id);
+ if (canSetPreferApn && mPreferredApn == null) {
+ log("PREFERRED APN is null");
+ mPreferredApn = mActiveApn;
+ setPreferredApn(mPreferredApn.id);
}
} else {
SystemProperties.set("gsm.defaultpdpcontext.active", "false");
@@ -1148,22 +1040,23 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if(DBG) log("PDP setup failed " + cause);
// Log this failure to the Event Logs.
if (cause.isEventLoggable()) {
- GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
+ GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
cause.ordinal(), loc != null ? loc.getCid() : -1,
TelephonyManager.getDefault().getNetworkType());
}
- // No try for permanent failure
+ // Do not retry on permanent failure
+ // TODO: We should not fail permanently if more Apns to try!
if (cause.isPermanentFail()) {
notifyNoData(cause);
- phone.notifyDataConnection(Phone.REASON_APN_FAILED);
+ notifyDataConnection(Phone.REASON_APN_FAILED);
onEnableApn(apnTypeToId(mRequestedApnType), DISABLED);
return;
}
- waitingApns.remove(0);
- if (waitingApns.isEmpty()) {
+ mWaitingApns.remove(0);
+ if (mWaitingApns.isEmpty()) {
// No more to try, start delayed retry
startDelayedRetry(cause, reason);
} else {
@@ -1179,14 +1072,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
/**
* Called when EVENT_DISCONNECT_DONE is received.
*/
- protected void onDisconnectDone(AsyncResult ar) {
+ @Override
+ protected void onDisconnectDone(int connId, AsyncResult ar) {
+ if(DBG) log("EVENT_DISCONNECT_DONE connId=" + connId);
String reason = null;
- if(DBG) log("EVENT_DISCONNECT_DONE");
if (ar.userObj instanceof String) {
reason = (String) ar.userObj;
}
setState(State.IDLE);
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
mActiveApn = null;
if (retryAfterDisconnected(reason)) {
trySetupData(reason);
@@ -1207,25 +1101,27 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
protected void onPollPdp() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
// only poll when connected
- phone.mCM.getPDPContextList(this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
+ mPhone.mCM.getPDPContextList(this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS);
}
}
+ @Override
protected void onVoiceCallStarted() {
- if (state == State.CONNECTED && ! mGsmPhone.mSST.isConcurrentVoiceAndData()) {
+ if (mState == State.CONNECTED && ! mGsmPhone.mSST.isConcurrentVoiceAndData()) {
stopNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
+ notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
}
}
+ @Override
protected void onVoiceCallEnded() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
if (!mGsmPhone.mSST.isConcurrentVoiceAndData()) {
startNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
+ notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
} else {
// clean slate after call end.
resetPollStats();
@@ -1239,74 +1135,92 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
+ @Override
protected void onCleanUpConnection(boolean tearDown, String reason) {
cleanUpConnection(tearDown, reason);
}
/**
- * Based on the sim operator numeric, create a list for all possible pdps
- * with all apns associated with that pdp
- *
- *
+ * Based on the sim operator numeric, create a list for all possible
+ * Data Connections and setup the preferredApn.
*/
private void createAllApnList() {
- allApns = new ArrayList<ApnSetting>();
+ mAllApns = new ArrayList<ApnSetting>();
String operator = mGsmPhone.mSIMRecords.getSIMOperatorNumeric();
if (operator != null) {
String selection = "numeric = '" + operator + "'";
- Cursor cursor = phone.getContext().getContentResolver().query(
+ Cursor cursor = mPhone.getContext().getContentResolver().query(
Telephony.Carriers.CONTENT_URI, null, selection, null, null);
if (cursor != null) {
if (cursor.getCount() > 0) {
- allApns = createApnList(cursor);
- // TODO: Figure out where this fits in. This basically just
- // writes the pap-secrets file. No longer tied to GsmDataConnection
- // object. Not used on current platform (no ppp).
- //GsmDataConnection pdp = pdpList.get(pdp_name);
- //if (pdp != null && pdp.dataLink != null) {
- // pdp.dataLink.setPasswordInfo(cursor);
- //}
+ mAllApns = createApnList(cursor);
}
cursor.close();
}
}
- if (allApns.isEmpty()) {
+ if (mAllApns.isEmpty()) {
if (DBG) log("No APN found for carrier: " + operator);
- preferredApn = null;
+ mPreferredApn = null;
notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
} else {
- preferredApn = getPreferredApn();
- Log.d(LOG_TAG, "Get PreferredAPN");
- if (preferredApn != null && !preferredApn.numeric.equals(operator)) {
- preferredApn = null;
+ mPreferredApn = getPreferredApn();
+ log("Get PreferredAPN");
+ if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
+ mPreferredApn = null;
setPreferredApn(-1);
}
}
}
- private void createAllPdpList() {
- pdpList = new ArrayList<DataConnection>();
- DataConnection pdp;
+ /** Return the id for a new data connection */
+ private int createDataConnection(String apnType) {
+ log("createDataConnection(" + apnType + ") E");
+ RetryManager rm = new RetryManager();
- for (int i = 0; i < PDP_CONNECTION_POOL_SIZE; i++) {
- pdp = GsmDataConnection.makeDataConnection(mGsmPhone);
- pdpList.add(pdp);
- }
+ if (apnType.equals(Phone.APN_TYPE_DEFAULT)) {
+ if (!rm.configure(SystemProperties.get("ro.gsm.data_retry_config"))) {
+ if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
+ // Should never happen, log an error and default to a simple linear sequence.
+ log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
+ + DEFAULT_DATA_RETRY_CONFIG);
+ rm.configure(20, 2000, 1000);
+ }
+ }
+ } else {
+ if (!rm.configure(SystemProperties.get("ro.gsm.2nd_data_retry_config"))) {
+ if (!rm.configure(SECONDARY_DATA_RETRY_CONFIG)) {
+ // Should never happen, log an error and default to a simple sequence.
+ log("Could note configure using SECONDARY_DATA_RETRY_CONFIG="
+ + SECONDARY_DATA_RETRY_CONFIG);
+ rm.configure("max_retries=3, 333, 333, 333");
+ }
+ }
+ }
+
+ int id = mUniqueIdGenerator.getAndIncrement();
+ DataConnection conn = GsmDataConnection.makeDataConnection(mGsmPhone, id, rm);
+ mDataConnections.put(id, conn);
+ mApnToDataConnectionId.put(apnType, id);
+
+ log("createDataConnection(" + apnType + ") X id=" + id);
+ return id;
}
- private void destroyAllPdpList() {
- if(pdpList != null) {
- GsmDataConnection pdp;
- pdpList.removeAll(pdpList);
+ private void destroyDataConnections() {
+ if(mDataConnections != null) {
+ log("destroyDataConnectionList clear mDataConnectionList");
+ mDataConnections.clear();
+ } else {
+ log("destroyDataConnectionList mDataConnecitonList is empty, ignore");
}
}
private ApnSetting fetchDunApn() {
- Context c = phone.getContext();
+ Context c = mPhone.getContext();
String apnData = Settings.Secure.getString(c.getContentResolver(),
Settings.Secure.TETHER_DUN_APN);
ApnSetting dunSetting = ApnSetting.fromString(apnData);
@@ -1317,14 +1231,16 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
/**
+ * Build a list of APNs to be used to create PDP's.
*
+ * @param requestedApnType
* @return waitingApns list to be used to create PDP
* error when waitingApns.isEmpty()
*/
- private ArrayList<ApnSetting> buildWaitingApns() {
+ private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType) {
ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
- if (mRequestedApnType.equals(Phone.APN_TYPE_DUN)) {
+ if (requestedApnType.equals(Phone.APN_TYPE_DUN)) {
ApnSetting dun = fetchDunApn();
if (dun != null) apnList.add(dun);
return apnList;
@@ -1332,24 +1248,24 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
String operator = mGsmPhone.mSIMRecords.getSIMOperatorNumeric();
- if (mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
- if (canSetPreferApn && preferredApn != null) {
- Log.i(LOG_TAG, "Preferred APN:" + operator + ":"
- + preferredApn.numeric + ":" + preferredApn);
- if (preferredApn.numeric.equals(operator)) {
- Log.i(LOG_TAG, "Waiting APN set to preferred APN");
- apnList.add(preferredApn);
+ if (requestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
+ if (canSetPreferApn && mPreferredApn != null) {
+ log("Preferred APN:" + operator + ":"
+ + mPreferredApn.numeric + ":" + mPreferredApn);
+ if (mPreferredApn.numeric.equals(operator)) {
+ log("Waiting APN set to preferred APN");
+ apnList.add(mPreferredApn);
return apnList;
} else {
setPreferredApn(-1);
- preferredApn = null;
+ mPreferredApn = null;
}
}
}
- if (allApns != null) {
- for (ApnSetting apn : allApns) {
- if (apn.canHandleType(mRequestedApnType)) {
+ if (mAllApns != null) {
+ for (ApnSetting apn : mAllApns) {
+ if (apn.canHandleType(requestedApnType)) {
apnList.add(apn);
}
}
@@ -1362,7 +1278,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
* @return the first apn found in waitingApns, null if none
*/
private ApnSetting getNextApn() {
- ArrayList<ApnSetting> list = waitingApns;
+ ArrayList<ApnSetting> list = mWaitingApns;
ApnSetting apn = null;
if (list != null) {
@@ -1393,7 +1309,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return;
}
- ContentResolver resolver = phone.getContext().getContentResolver();
+ ContentResolver resolver = mPhone.getContext().getContentResolver();
resolver.delete(PREFERAPN_URI, null, null);
if (pos >= 0) {
@@ -1404,11 +1320,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
private ApnSetting getPreferredApn() {
- if (allApns.isEmpty()) {
+ if (mAllApns.isEmpty()) {
return null;
}
- Cursor cursor = phone.getContext().getContentResolver().query(
+ Cursor cursor = mPhone.getContext().getContentResolver().query(
PREFERAPN_URI, new String[] { "_id", "name", "apn" },
null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
@@ -1422,7 +1338,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
int pos;
cursor.moveToFirst();
pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
- for(ApnSetting p:allApns) {
+ for(ApnSetting p:mAllApns) {
if (p.id == pos && p.canHandleType(mRequestedApnType)) {
cursor.close();
return p;
@@ -1437,11 +1353,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return null;
}
+ @Override
public void handleMessage (Message msg) {
- if (DBG) Log.d(LOG_TAG,"GSMDataConnTrack handleMessage "+msg);
+ if (DBG) log("GSMDataConnTrack handleMessage "+msg);
if (!mGsmPhone.mIsTheCurrentActivePhone) {
- Log.d(LOG_TAG, "Ignore GSM msgs since GSM phone is inactive");
+ log("Ignore GSM msgs since GSM phone is inactive");
return;
}
@@ -1459,11 +1376,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
break;
case EVENT_DATA_STATE_CHANGED:
- onPdpStateChanged((AsyncResult) msg.obj, false);
+ onDataStateChanged((AsyncResult) msg.obj, false);
break;
case EVENT_GET_PDP_LIST_COMPLETE:
- onPdpStateChanged((AsyncResult) msg.obj, true);
+ onDataStateChanged((AsyncResult) msg.obj, true);
break;
case EVENT_POLL_PDP:
@@ -1491,7 +1408,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
* PDP context and notify us with PDP_CONTEXT_CHANGED.
* But we should stop the network polling and prevent reset PDP.
*/
- Log.d(LOG_TAG, "[DSAC DEB] " + "EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
+ log("[DSAC DEB] " + "EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
stopNetStatPoll();
mIsPsRestricted = true;
break;
@@ -1501,12 +1418,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
* When PS restrict is removed, we need setup PDP connection if
* PDP connection is down.
*/
- Log.d(LOG_TAG, "[DSAC DEB] " + "EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
+ log("[DSAC DEB] " + "EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
mIsPsRestricted = false;
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
startNetStatPoll();
} else {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, Phone.REASON_PS_RESTRICT_ENABLED);
mRetryMgr.resetRetryCount();
mReregisterOnReconnectFailure = false;
@@ -1522,7 +1439,13 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[GsmDataConnectionTracker] " + s);
}
+
+ @Override
+ protected void loge(String s) {
+ Log.e(LOG_TAG, "[GsmDataConnectionTracker] " + s);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 3079a64..ed7066b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -56,6 +56,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
* @param ar AsyncResult passed into the message handler. ar.result should
* be a String representing the status report PDU, as ASCII hex.
*/
+ @Override
protected void handleStatusReport(AsyncResult ar) {
String pduString = (String) ar.result;
SmsMessage sms = SmsMessage.newFromCDS(pduString);
@@ -84,6 +85,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
/** {@inheritDoc} */
+ @Override
protected int dispatchMessage(SmsMessageBase smsb) {
// If sms is null, means there was a parsing error.
@@ -151,6 +153,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void sendData(String destAddr, String scAddr, int destPort,
byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
@@ -159,6 +162,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void sendText(String destAddr, String scAddr, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
@@ -167,6 +171,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void sendMultipartText(String destinationAddress, String scAddress,
ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
ArrayList<PendingIntent> deliveryIntents) {
@@ -306,8 +311,9 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void sendSms(SmsTracker tracker) {
- HashMap map = tracker.mData;
+ HashMap<String, Object> map = tracker.mData;
byte smsc[] = (byte[]) map.get("smsc");
byte pdu[] = (byte[]) map.get("pdu");
@@ -322,12 +328,13 @@ final class GsmSMSDispatcher extends SMSDispatcher {
*
* @param tracker holds the multipart Sms tracker ready to be sent
*/
+ @Override
protected void sendMultipartSms (SmsTracker tracker) {
ArrayList<String> parts;
ArrayList<PendingIntent> sentIntents;
ArrayList<PendingIntent> deliveryIntents;
- HashMap map = tracker.mData;
+ HashMap<String, Object> map = tracker.mData;
String destinationAddress = (String) map.get("destination");
String scAddress = (String) map.get("scaddress");
@@ -342,6 +349,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void acknowledgeLastIncomingSms(boolean success, int result, Message response){
// FIXME unit test leaves cm == null. this should change
if (mCm != null) {
@@ -350,6 +358,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void activateCellBroadcastSms(int activate, Message response) {
// Unless CBS is implemented for GSM, this point should be unreachable.
Log.e(TAG, "Error! The functionality cell broadcast sms is not implemented for GSM.");
@@ -357,6 +366,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void getCellBroadcastSmsConfig(Message response){
// Unless CBS is implemented for GSM, this point should be unreachable.
Log.e(TAG, "Error! The functionality cell broadcast sms is not implemented for GSM.");
@@ -364,6 +374,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
+ @Override
protected void setCellBroadcastConfig(int[] configValuesArray, Message response) {
// Unless CBS is implemented for GSM, this point should be unreachable.
Log.e(TAG, "Error! The functionality cell broadcast sms is not implemented for GSM.");
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 6ddb312..632615d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -16,6 +16,18 @@
package com.android.internal.telephony.gsm;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.DataConnectionTracker;
+import com.android.internal.telephony.EventLogTags;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.MccTable;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.ServiceStateTracker;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
+
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -47,17 +59,6 @@ import android.util.EventLog;
import android.util.Log;
import android.util.TimeUtils;
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
-
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
@@ -226,6 +227,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_LOCALE_CHANGED);
phone.getContext().registerReceiver(mIntentReceiver, filter);
+
+ // Gsm doesn't support OTASP so its not needed
+ phone.notifyOtaspChanged(OTASP_NOT_NEEDED);
}
public void dispose() {
@@ -246,6 +250,11 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
if(DBG) Log.d(LOG_TAG, "GsmServiceStateTracker finalized");
}
+ @Override
+ protected Phone getPhone() {
+ return phone;
+ }
+
/**
* Registration point for transition into GPRS attached.
* @param h handler to notify
@@ -1001,7 +1010,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
mNeedFixZone = false;
if (zone != null) {
- if (getAutoTime()) {
+ if (getAutoTimeZone()) {
setAndBroadcastNetworkSetTimeZone(zone.getID());
}
saveNitzTimeZone(zone.getID());
@@ -1024,7 +1033,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
if (hasNetworkTypeChanged) {
- phone.notifyDataConnection(null);
+ phone.notifyDataConnection();
}
if (hasRoamingOn) {
@@ -1481,7 +1490,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
if (zone != null) {
- if (getAutoTime()) {
+ if (getAutoTimeZone()) {
setAndBroadcastNetworkSetTimeZone(zone.getID());
}
saveNitzTimeZone(zone.getID());
@@ -1551,6 +1560,15 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
}
+ private boolean getAutoTimeZone() {
+ try {
+ return Settings.System.getInt(phone.getContext().getContentResolver(),
+ Settings.System.AUTO_TIME_ZONE) > 0;
+ } catch (SettingNotFoundException snfe) {
+ return true;
+ }
+ }
+
private void saveNitzTimeZone(String zoneId) {
mSavedTimeZone = zoneId;
}
@@ -1666,7 +1684,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
}
- private void log(String s) {
+ @Override
+ protected void log(String s) {
Log.d(LOG_TAG, "[GsmServiceStateTracker] " + s);
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
index 67ecc77..aab359f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
@@ -87,6 +87,7 @@ public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
public void dispose() {
}
+ @Override
protected void finalize() {
try {
super.finalize();
@@ -192,6 +193,7 @@ public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
return mSms;
}
+ @Override
protected void log(String msg) {
Log.d(LOG_TAG, "[SimSmsInterfaceManager] " + msg);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 9a3c476..e24613f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -26,7 +26,6 @@ import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
@@ -34,6 +33,7 @@ import java.io.UnsupportedEncodingException;
import static android.telephony.SmsMessage.ENCODING_7BIT;
import static android.telephony.SmsMessage.ENCODING_8BIT;
import static android.telephony.SmsMessage.ENCODING_16BIT;
+import static android.telephony.SmsMessage.ENCODING_KSC5601;
import static android.telephony.SmsMessage.ENCODING_UNKNOWN;
import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
@@ -45,7 +45,7 @@ import static android.telephony.SmsMessage.MessageClass;
* A Short Message Service message.
*
*/
-public class SmsMessage extends SmsMessageBase{
+public class SmsMessage extends SmsMessageBase {
static final String LOG_TAG = "GSM";
private MessageClass messageClass;
@@ -311,7 +311,7 @@ public class SmsMessage extends SmsMessageBase{
// the receiver's SIM card. You can then send messages to yourself
// (on a phone with this change) and they'll end up on the SIM card.
bo.write(0x00);
- } else { //assume UCS-2
+ } else { // assume UCS-2
if ((0xff & userData[0]) > MAX_USER_DATA_BYTES) {
// Message too long
return null;
@@ -377,7 +377,7 @@ public class SmsMessage extends SmsMessageBase{
* @param destinationAddress the address of the destination for the message
* @param destinationPort the port to deliver the message to at the
* destination
- * @param data the dat for the message
+ * @param data the data for the message
* @return a <code>SubmitPdu</code> containing the encoded SC
* address, if applicable, and the encoded message.
* Returns null on encode error.
@@ -482,7 +482,7 @@ public class SmsMessage extends SmsMessageBase{
return bo;
}
- static class PduParser {
+ private static class PduParser {
byte pdu[];
int cur;
SmsHeader userDataHeader;
@@ -490,10 +490,6 @@ public class SmsMessage extends SmsMessageBase{
int mUserDataSeptetPadding;
int mUserDataSize;
- PduParser(String s) {
- this(IccUtils.hexStringToBytes(s));
- }
-
PduParser(byte[] pdu) {
this.pdu = pdu;
cur = 0;
@@ -545,7 +541,7 @@ public class SmsMessage extends SmsMessageBase{
GsmSmsAddress ret;
// "The Address-Length field is an integer representation of
- // the number field, i.e. excludes any semi octet containing only
+ // the number field, i.e. excludes any semi-octet containing only
// fill bits."
// The TOA field is not included as part of this
int addressLength = pdu[cur] & 0xff;
@@ -573,7 +569,7 @@ public class SmsMessage extends SmsMessageBase{
int second = IccUtils.gsmBcdByteToInt(pdu[cur++]);
// For the timezone, the most significant bit of the
- // least signficant nibble is the sign byte
+ // least significant nibble is the sign byte
// (meaning the max range of this field is 79 quarter-hours,
// which is more than enough)
@@ -632,7 +628,7 @@ public class SmsMessage extends SmsMessageBase{
/*
* Here we just create the user data length to be the remainder of
* the pdu minus the user data header, since userDataLength means
- * the number of uncompressed sepets.
+ * the number of uncompressed septets.
*/
bufferLen = pdu.length - offset;
} else {
@@ -671,10 +667,10 @@ public class SmsMessage extends SmsMessageBase{
}
/**
- * Returns the number of padding bits at the begining of the user data
+ * Returns the number of padding bits at the beginning of the user data
* array before the start of the septets.
*
- * @return the number of padding bits at the begining of the user data
+ * @return the number of padding bits at the beginning of the user data
* array before the start of the septets
*/
int getUserDataSeptetPadding() {
@@ -694,7 +690,7 @@ public class SmsMessage extends SmsMessageBase{
XXX Not sure what this one is supposed to be doing, and no one is using
it.
String getUserDataGSM8bit() {
- // System.out.println("remainder of pud:" +
+ // System.out.println("remainder of pdu:" +
// HexDump.dumpHexString(pdu, cur, pdu.length - cur));
int count = pdu[cur++] & 0xff;
int size = pdu[cur++];
@@ -781,6 +777,27 @@ public class SmsMessage extends SmsMessageBase{
return ret;
}
+ /**
+ * Interprets the user data payload as KSC-5601 characters, and
+ * decodes them into a String.
+ *
+ * @param byteCount the number of bytes in the user data payload
+ * @return a String with the decoded characters
+ */
+ String getUserDataKSC5601(int byteCount) {
+ String ret;
+
+ try {
+ ret = new String(pdu, cur, byteCount, "KSC5601");
+ } catch (UnsupportedEncodingException ex) {
+ ret = "";
+ Log.e(LOG_TAG, "implausible UnsupportedEncodingException", ex);
+ }
+
+ cur += byteCount;
+ return ret;
+ }
+
boolean moreDataPresent() {
return (pdu.length > cur);
}
@@ -827,11 +844,13 @@ public class SmsMessage extends SmsMessageBase{
}
/** {@inheritDoc} */
+ @Override
public int getProtocolIdentifier() {
return protocolIdentifier;
}
/** {@inheritDoc} */
+ @Override
public boolean isReplace() {
return (protocolIdentifier & 0xc0) == 0x40
&& (protocolIdentifier & 0x3f) > 0
@@ -839,12 +858,14 @@ public class SmsMessage extends SmsMessageBase{
}
/** {@inheritDoc} */
+ @Override
public boolean isCphsMwiMessage() {
return ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageClear()
|| ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageSet();
}
/** {@inheritDoc} */
+ @Override
public boolean isMWIClearMessage() {
if (isMwi && (mwiSense == false)) {
return true;
@@ -855,6 +876,7 @@ public class SmsMessage extends SmsMessageBase{
}
/** {@inheritDoc} */
+ @Override
public boolean isMWISetMessage() {
if (isMwi && (mwiSense == true)) {
return true;
@@ -865,6 +887,7 @@ public class SmsMessage extends SmsMessageBase{
}
/** {@inheritDoc} */
+ @Override
public boolean isMwiDontStore() {
if (isMwi && mwiDontStore) {
return true;
@@ -884,31 +907,34 @@ public class SmsMessage extends SmsMessageBase{
}
/** {@inheritDoc} */
+ @Override
public int getStatus() {
return status;
}
/** {@inheritDoc} */
+ @Override
public boolean isStatusReportMessage() {
return isStatusReportMessage;
}
/** {@inheritDoc} */
+ @Override
public boolean isReplyPathPresent() {
return replyPathPresent;
}
/**
- * TS 27.005 3.1, <pdu> definition "In the case of SMS: 3GPP TS 24.011 [6]
+ * TS 27.005 3.1, &lt;pdu&gt; definition "In the case of SMS: 3GPP TS 24.011 [6]
* SC address followed by 3GPP TS 23.040 [3] TPDU in hexadecimal format:
* ME/TA converts each octet of TP data unit into two IRA character long
- * hexad number (e.g. octet with integer value 42 is presented to TE as two
+ * hex number (e.g. octet with integer value 42 is presented to TE as two
* characters 2A (IRA 50 and 65))" ...in the case of cell broadcast,
* something else...
*/
private void parsePdu(byte[] pdu) {
mPdu = pdu;
- // Log.d(LOG_TAG, "raw sms mesage:");
+ // Log.d(LOG_TAG, "raw sms message:");
// Log.d(LOG_TAG, s);
PduParser p = new PduParser(pdu);
@@ -1107,6 +1133,16 @@ public class SmsMessage extends SmsMessageBase{
Log.w(LOG_TAG, "MWI for fax, email, or other "
+ (dataCodingScheme & 0xff));
}
+ } else if ((dataCodingScheme & 0xC0) == 0x80) {
+ // 3GPP TS 23.038 V7.0.0 (2006-03) section 4
+ // 0x80..0xBF == Reserved coding groups
+ if (dataCodingScheme == 0x84) {
+ // This value used for KSC5601 by carriers in Korea.
+ encodingType = ENCODING_KSC5601;
+ } else {
+ Log.w(LOG_TAG, "5 - Unsupported SMS data coding scheme "
+ + (dataCodingScheme & 0xff));
+ }
} else {
Log.w(LOG_TAG, "3 - Unsupported SMS data coding scheme "
+ (dataCodingScheme & 0xff));
@@ -1131,6 +1167,10 @@ public class SmsMessage extends SmsMessageBase{
case ENCODING_16BIT:
messageBody = p.getUserDataUCS2(count);
break;
+
+ case ENCODING_KSC5601:
+ messageBody = p.getUserDataKSC5601(count);
+ break;
}
if (Config.LOGV) Log.v(LOG_TAG, "SMS message body (raw): '" + messageBody + "'");
@@ -1162,6 +1202,7 @@ public class SmsMessage extends SmsMessageBase{
/**
* {@inheritDoc}
*/
+ @Override
public MessageClass getMessageClass() {
return messageClass;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
index b642541..41f3b23 100755
--- a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
@@ -27,8 +27,6 @@ import com.android.internal.telephony.IccConstants;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.PhoneBase;
-import org.apache.harmony.luni.lang.reflect.ListOfTypes;
-
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
diff --git a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
index 154a334..c83f696 100644
--- a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
@@ -19,6 +19,7 @@ package com.android.internal.telephony.sip;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.UUSInfo;
import android.net.sip.SipAudioCall;
import android.os.SystemClock;
@@ -171,4 +172,10 @@ abstract class SipConnectionBase extends Connection {
// TODO: add PRESENTATION_URL
return Connection.PRESENTATION_ALLOWED;
}
+
+ @Override
+ public UUSInfo getUUSInfo() {
+ // FIXME: what's this for SIP?
+ return null;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index b154c91..ef31ddd 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -36,7 +36,6 @@ import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.UUSInfo;
import java.text.ParseException;
import java.util.List;
@@ -70,6 +69,14 @@ public class SipPhone extends SipPhoneBase {
mSipManager = SipManager.newInstance(context);
}
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof SipPhone)) return false;
+ SipPhone that = (SipPhone) o;
+ return mProfile.getUriString().equals(that.mProfile.getUriString());
+ }
+
public String getPhoneName() {
return "SIP:" + getUriString(mProfile);
}
@@ -145,10 +152,6 @@ public class SipPhone extends SipPhoneBase {
}
}
- public Connection dial(String dialString, UUSInfo uusinfo) throws CallStateException {
- return dial(dialString);
- }
-
public Connection dial(String dialString) throws CallStateException {
synchronized (SipPhone.class) {
return dialInternal(dialString);
@@ -832,10 +835,6 @@ public class SipPhone extends SipPhoneBase {
}
}
- @Override
- public UUSInfo getUUSInfo() {
- return null;
- }
}
private static Call.State getCallStateFrom(SipAudioCall sipAudioCall) {
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
index 5499966..afd4d0c 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -17,6 +17,7 @@
package com.android.internal.telephony.sip;
import android.content.Context;
+import android.net.LinkProperties;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
@@ -42,6 +43,7 @@ import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.PhoneNotifier;
import com.android.internal.telephony.PhoneSubInfo;
import com.android.internal.telephony.TelephonyProperties;
+import com.android.internal.telephony.UUSInfo;
import java.util.ArrayList;
import java.util.List;
@@ -62,6 +64,12 @@ abstract class SipPhoneBase extends PhoneBase {
public abstract Call getRingingCall();
+ public Connection dial(String dialString, UUSInfo uusInfo)
+ throws CallStateException {
+ // ignore UUSInfo
+ return dial(dialString);
+ }
+
void migrateFrom(SipPhoneBase from) {
migrate(mRingbackRegistrants, from.mRingbackRegistrants);
migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants);
@@ -419,6 +427,18 @@ abstract class SipPhoneBase extends PhoneBase {
Log.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
}
+ //@Override
+ public boolean needsOtaServiceProvisioning() {
+ // FIXME: what's this for SIP?
+ return false;
+ }
+
+ //@Override
+ public LinkProperties getLinkProperties(String apnType) {
+ // FIXME: what's this for SIP?
+ return null;
+ }
+
void updatePhoneState() {
State oldState = state;
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
index 9c72e5a..fdcf78d 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -16,7 +16,6 @@
package com.android.internal.telephony.test;
-
import android.os.AsyncResult;
import android.os.HandlerThread;
import android.os.Looper;
@@ -27,7 +26,6 @@ import com.android.internal.telephony.BaseCommands;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataCallState;
-import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.UUSInfo;
import com.android.internal.telephony.gsm.CallFailCause;
@@ -335,7 +333,7 @@ public final class SimulatedCommands extends BaseCommands
/**
* (AsyncResult)response.obj).result will be an Integer representing
- * the sum of enabled serivice classes (sum of SERVICE_CLASS_*)
+ * the sum of enabled service classes (sum of SERVICE_CLASS_*)
*
* @param facility one of CB_FACILTY_*
* @param pin password or "" if not required
@@ -441,7 +439,7 @@ public final class SimulatedCommands extends BaseCommands
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result contains a List of DriverCall
* The ar.result List is sorted by DriverCall.index
*/
@@ -468,7 +466,7 @@ public final class SimulatedCommands extends BaseCommands
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result contains a List of DataCallState
*/
public void getDataCallList(Message result) {
@@ -479,7 +477,7 @@ public final class SimulatedCommands extends BaseCommands
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*
* CLIR_DEFAULT == on "use subscription default value"
@@ -496,7 +494,7 @@ public final class SimulatedCommands extends BaseCommands
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*
* CLIR_DEFAULT == on "use subscription default value"
@@ -513,7 +511,7 @@ public final class SimulatedCommands extends BaseCommands
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is String containing IMSI on success
*/
public void getIMSI(Message result) {
@@ -524,7 +522,7 @@ public final class SimulatedCommands extends BaseCommands
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is String containing IMEI on success
*/
public void getIMEI(Message result) {
@@ -535,7 +533,7 @@ public final class SimulatedCommands extends BaseCommands
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is String containing IMEISV on success
*/
public void getIMEISV(Message result) {
@@ -547,7 +545,7 @@ public final class SimulatedCommands extends BaseCommands
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*
* 3GPP 22.030 6.5.5
@@ -572,7 +570,7 @@ public final class SimulatedCommands extends BaseCommands
* "Releases all held calls or sets User Determined User Busy (UDUB)
* for a waiting call."
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void hangupWaitingOrBackground (Message result) {
@@ -593,7 +591,7 @@ public final class SimulatedCommands extends BaseCommands
* the other (held or waiting) call."
*
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void hangupForegroundResumeBackground (Message result) {
@@ -614,7 +612,7 @@ public final class SimulatedCommands extends BaseCommands
* the other (held or waiting) call."
*
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void switchWaitingOrHoldingAndActive (Message result) {
@@ -634,7 +632,7 @@ public final class SimulatedCommands extends BaseCommands
* "Adds a held call to the conversation"
*
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void conference (Message result) {
@@ -654,7 +652,7 @@ public final class SimulatedCommands extends BaseCommands
* "Connects the two calls and disconnects the subscriber from both calls"
*
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void explicitCallTransfer (Message result) {
@@ -690,7 +688,7 @@ public final class SimulatedCommands extends BaseCommands
/**
*
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void acceptCall (Message result) {
@@ -708,7 +706,7 @@ public final class SimulatedCommands extends BaseCommands
/**
* also known as UDUB
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void rejectCall (Message result) {
@@ -785,7 +783,7 @@ public final class SimulatedCommands extends BaseCommands
*
* @param result is callback message
* ((AsyncResult)response.obj).result is an int[] with every
- * element representing one avialable BM_*_BAND
+ * element representing one available BM_*_BAND
*/
public void queryAvailableBandMode (Message result) {
int ret[] = new int [4];
@@ -894,7 +892,7 @@ public final class SimulatedCommands extends BaseCommands
/**
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void sendDtmf(char c, Message result) {
@@ -903,7 +901,7 @@ public final class SimulatedCommands extends BaseCommands
/**
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void startDtmf(char c, Message result) {
@@ -912,7 +910,7 @@ public final class SimulatedCommands extends BaseCommands
/**
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void stopDtmf(Message result) {
@@ -921,7 +919,7 @@ public final class SimulatedCommands extends BaseCommands
/**
* ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
+ * ar.userObject contains the original value of result.obj
* ar.result is null on success and failure
*/
public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
@@ -956,6 +954,7 @@ public final class SimulatedCommands extends BaseCommands
unimplemented(response);
}
+ @Deprecated
public void setupDefaultPDP(String apn, String user, String password, Message result) {
unimplemented(result);
}
@@ -967,9 +966,7 @@ public final class SimulatedCommands extends BaseCommands
public void deactivateDataCall(int cid, Message result) {unimplemented(result);}
- /**
- * @deprecated
- */
+ @Deprecated
public void deactivateDefaultPDP(int cid, Message result) {unimplemented(result);}
public void setPreferredNetworkType(int networkType , Message result) {
@@ -1046,7 +1043,7 @@ public final class SimulatedCommands extends BaseCommands
}
/**
- * parameters equivilient to 27.007 AT+CRSM command
+ * parameters equivalent to 27.007 AT+CRSM command
* response.obj will be an AsyncResult
* response.obj.userObj will be a SimIoResult on success
*/