summaryrefslogtreecommitdiffstats
path: root/telephony
diff options
context:
space:
mode:
Diffstat (limited to 'telephony')
-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.java3
-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.java21
-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.java133
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionTracker.java187
-rw-r--r--telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java37
-rw-r--r--telephony/java/com/android/internal/telephony/GsmAlphabet.java51
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl6
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl8
-rw-r--r--telephony/java/com/android/internal/telephony/IccUtils.java24
-rw-r--r--telephony/java/com/android/internal/telephony/MccTable.java866
-rw-r--r--telephony/java/com/android/internal/telephony/Phone.java58
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java57
-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/SipPhoneNotifier.java37
-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.java52
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java133
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java15
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java35
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java3
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/SmsMessage.java8
-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.java7
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java151
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java15
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java38
-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.java2
-rwxr-xr-xtelephony/java/com/android/internal/telephony/sip/SipPhone.java17
-rwxr-xr-xtelephony/java/com/android/internal/telephony/sip/SipPhoneBase.java17
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedCommands.java51
-rw-r--r--telephony/mockril/Android.mk30
-rw-r--r--telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java135
-rw-r--r--telephony/tests/telephonymockriltests/Android.mk14
-rw-r--r--telephony/tests/telephonymockriltests/AndroidManifest.xml40
-rw-r--r--telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java64
-rw-r--r--telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java63
-rw-r--r--telephony/tests/telephonytests/Android.mk2
-rw-r--r--telephony/tests/telephonytests/AndroidManifest.xml7
-rw-r--r--telephony/tests/telephonytests/src/android/telephony/PhoneNumberWatcherTest.java65
-rw-r--r--telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java93
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java26
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java2
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java2
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java (renamed from telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java)40
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java214
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java8
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java12
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java6
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java197
66 files changed, 2532 insertions, 1195 deletions
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 ddfc520..e37733c 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;
@@ -1741,7 +1872,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) {
@@ -1761,7 +1892,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
@@ -1883,12 +2014,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,
@@ -1900,18 +2031,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
*/
@@ -2046,7 +2177,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..38f44d8 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
@@ -284,7 +285,7 @@ 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();
}
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..2370add 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -912,4 +912,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 cf89848..6e13690 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -70,6 +70,7 @@ public class CallerInfo {
*/
public String name;
public String phoneNumber;
+ public String nomalizedNumber;
public String cnapName;
public int numberPresentation;
@@ -150,6 +151,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 25ca559..a967850 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;
@@ -232,7 +233,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..3030481 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -21,11 +21,19 @@ import com.android.internal.telephony.gsm.ApnSetting;
import com.android.internal.util.HierarchicalState;
import com.android.internal.util.HierarchicalStateMachine;
+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.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+
/**
* {@hide}
*
@@ -255,10 +263,8 @@ public abstract class DataConnection extends HierarchicalStateMachine {
protected int mTag;
protected PhoneBase phone;
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;
@@ -283,8 +289,6 @@ public abstract class DataConnection extends HierarchicalStateMachine {
if (DBG) log("DataConnection constructor E");
this.phone = phone;
this.cid = -1;
- this.dnsServers = new String[2];
-
clearSettings();
setDbg(false);
@@ -377,11 +381,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 +416,68 @@ 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");
- 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;
- } else {
- result = SetupResult.ERR_BadDns;
+ linkProperties.setInterface(NetworkInterface.getByName(interfaceName));
+
+ // TODO: Get gateway and dns via RIL interface not property?
+ String gatewayAddress = SystemProperties.get(prefix + "gw");
+ linkProperties.setGateway(InetAddress.getByName(gatewayAddress));
+
+ if (response.length > 2) {
+ String ipAddress = response[2];
+ linkProperties.addAddress(InetAddress.getByName(ipAddress));
+
+ // 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 (isDnsOk(dnsServers)) {
+ 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 +639,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;
@@ -873,31 +915,22 @@ public abstract class DataConnection extends HierarchicalStateMachine {
}
/**
- * @return the interface name as a string.
- */
- public String getInterface() {
- return interfaceName;
- }
-
- /**
- * @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 3b9e6cc..d753973 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -17,10 +17,11 @@
package com.android.internal.telephony;
import android.app.PendingIntent;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
-import android.os.RemoteException;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
@@ -28,6 +29,7 @@ import android.util.Log;
import java.util.ArrayList;
+
/**
* {@hide}
*
@@ -188,7 +190,16 @@ public abstract class DataConnectionTracker extends Handler {
/** CID of active data connection */
protected int cidActive;
- /**
+ /** indication of our availability (preconditions to trysetupData are met) **/
+ protected boolean mAvailability = false;
+
+ /** The link properties (dns, gateway, ip, etc) */
+ protected LinkProperties mLinkProperties = new LinkProperties();
+
+ /** The link capabilities */
+ protected LinkCapabilities mLinkCapabilities = new LinkCapabilities();
+
+ /**
* Default constructor
*/
protected DataConnectionTracker(PhoneBase phone) {
@@ -411,17 +422,125 @@ public abstract class DataConnectionTracker extends Handler {
public abstract ArrayList<DataConnection> getAllDataConnections();
- protected abstract String getInterfaceName(String apnType);
+ protected abstract void setState(State s);
- protected abstract String getIpAddress(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 getGateway(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[] getDnsServers(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 void setState(State s);
+ /**
+ * 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 synchronized boolean isEnabled(int id) {
+ // 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]) {
+ phone.notifyDataConnection(reason, apnIdToType(id));
+ }
+ }
+ notifyDataAvailability(reason);
+ }
+
+ // 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 (state) {
+ case IDLE:
+ case INITING:
+ break;
+ case CONNECTING:
+ case SCANNING:
+ phone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
+ break;
+ case CONNECTED:
+ case DISCONNECTING:
+ phone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
+ phone.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) {
+ phone.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() && (state == State.FAILED || state == State.IDLE)));
+ if (!possible && DBG && isDataAllowed()) {
+ log("Data not possible. No coverage: dataState = " + state);
+ }
+ return possible;
+ }
+
+ protected abstract boolean isDataAllowed();
+
+ public boolean isApnTypeEnabled(String apnType) {
+ return isApnIdEnabled(apnTypeToId(apnType));
+ }
+
+ protected synchronized boolean isApnIdEnabled(int id) {
if (id != APN_INVALID_ID) {
return dataEnabled[id];
}
@@ -444,22 +563,21 @@ 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.d(LOG_TAG, "enableApnType(" + type + "), isApnTypeActive = "
+ + isApnTypeActive(type) + ", isApnIdEnabled =" + isApnIdEnabled(id) +
+ " and state = " + state);
+ }
if (!isApnTypeAvailable(type)) {
if (DBG) Log.d(LOG_TAG, "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;
}
@@ -478,7 +596,7 @@ public abstract class DataConnectionTracker extends Handler {
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 +613,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.d(LOG_TAG, "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);
@@ -507,9 +626,8 @@ 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.d(LOG_TAG, " dataEnabled = " + dataEnabled[apnId] + ", enabledCount = "
+ + enabledCount + ", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));
}
if (enabled == ENABLED) {
if (!dataEnabled[apnId]) {
@@ -520,6 +638,8 @@ public abstract class DataConnectionTracker extends Handler {
if (!isApnTypeActive(type)) {
mRequestedApnType = type;
onEnableNewApn();
+ } else {
+ notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnId);
}
} else {
// disable
@@ -528,8 +648,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();
}
@@ -574,9 +703,7 @@ public abstract class DataConnectionTracker extends Handler {
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..6a163dd 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,45 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
}
}
- public void notifyDataConnection(Phone sender, String reason) {
+ public void notifyDataConnection(Phone sender, String reason, String apnType) {
+ doNotifyDataConnection(sender, reason, apnType, sender.getDataConnectionState(apnType));
+ }
+
+ 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
}
diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
index 7edf065..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
@@ -171,7 +174,7 @@ public class GsmAlphabet {
* array cannot contain more than 255 septets.
*
* @param data The text string to encode.
- * @param header Optional header (includeing length byte) that precedes
+ * @param header Optional header (including length byte) that precedes
* the encoded data, padded to septet boundary.
* @return Byte array containing header and encoded data.
*/
@@ -204,7 +207,7 @@ public class GsmAlphabet {
* the packed septets. The returned array cannot contain more than 255
* septets.
*
- * @param data the data string to endcode
+ * @param data the data string to encode
* @throws EncodeException if String is too large to encode
*/
public static byte[] stringToGsm7BitPacked(String data)
@@ -223,7 +226,7 @@ public class GsmAlphabet {
*
* @param data the text to convert to septets
* @param startingSeptetOffset the number of padding septets to put before
- * the character data at the begining of the array
+ * the character data at the beginning of the array
* @param throwException If true, throws EncodeException on invalid char.
* If false, replaces unencodable char with GSM alphabet space char.
*
@@ -257,7 +260,7 @@ public class GsmAlphabet {
}
/**
- * Pack a 7-bit char into its appropirate place in a byte array
+ * Pack a 7-bit char into its appropriate place in a byte array
*
* @param bitOffset the bit offset that the septet should be packed at
* (septet index * 7)
@@ -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/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 2328717..7a1587b 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -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..6407a4e 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,8 @@ 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);
}
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 b73c2f7..9b0aa3c 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, '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,200 +38,153 @@ 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/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", "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;
+ int wifiChannels;
- /**
- * 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, 0x6e6c6c68, 0x62650400, 0x667204b5, 0x6d630400, 0x61640400,
- 0x657304a4, 0x68750400, 0x62610400, 0x68720400, 0x72730400, 0x697404d6,
- 0x766104d6, 0x726f0400, 0x63680502, 0x637a6cc1, 0x736b0400, 0x61746ce2,
- 0x67626c93, 0x67626c93, 0x646b0400, 0x73650400, 0x6e6f0400, 0x66690400,
- 0x6c740400, 0x6c760400, 0x65650400, 0x72750400, 0x75610400, 0x62790400,
- 0x6d640400, 0x706c04f0, 0x64656c72, 0x67690400, 0x70740400, 0x6c750400,
- 0x69650483, 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, 0x6a707447, 0x6a707447,
- 0x6b720400, 0x766e0400, 0x686b0400, 0x6d6f0400, 0x6b680400, 0x6c610400,
- 0x636e6c29, 0x636e6c29, 0x74770400, 0x6b700400, 0x62640400, 0x6d760400,
- 0x6d790400, 0x61755c53, 0x69640400, 0x746c0400, 0x70680400, 0x74680400,
- 0x73675c33, 0x626e0400, 0x6e7a0513, 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(mnc, iso, smallestDigitsMCC, language, 0);
+ }
+
+ MccEntry(int mnc, String iso, int smallestDigitsMCC, String language, int wifiChannels) {
+ this.mcc = mnc;
+ this.iso = iso;
+ this.smallestDigitsMnc = smallestDigitsMCC;
+ this.language = language;
+ this.wifiChannels = wifiChannels;
+ }
+
+
+ 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) {
+ public static int
+ smallestDigitsMccForMnc(int mcc)
+ {
+ MccEntry entry;
+
+ entry = entryForMcc(mcc);
+
+ if (entry == null) {
return 2;
+ } else {
+ return entry.smallestDigitsMnc;
}
- int indCode = IND_CODES[index];
- int smDig = (indCode >>> 9) & 0x0003;
- return smDig;
}
/**
* 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) {
+ public static int
+ wifiChannelsForMcc(int mcc) {
+ MccEntry entry;
+
+ entry = entryForMcc(mcc);
+
+ if (entry == null) {
return 0;
+ } else {
+ return entry.wifiChannels;
}
- int indCode = IND_CODES[index];
- int wifi = (indCode >>> 11) & 0x000F;
- return wifi;
}
/**
@@ -656,4 +276,262 @@ public final class MccTable
wM.setNumAllowedChannels(wifiChannels, 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",13)); //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",13)); //Czech Republic
+ table.add(new MccEntry(231,"sk",2)); //Slovak Republic
+ table.add(new MccEntry(232,"at",2,"de",13)); //Austria
+ table.add(new MccEntry(234,"gb",2,"en",13)); //United Kingdom of Great Britain and Northern Ireland
+ table.add(new MccEntry(235,"gb",2,"en",13)); //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",13)); //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,"",11)); //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",11)); //United States of America
+ table.add(new MccEntry(311,"us",3,"en",11)); //United States of America
+ table.add(new MccEntry(312,"us",3,"en",11)); //United States of America
+ table.add(new MccEntry(313,"us",3,"en",11)); //United States of America
+ table.add(new MccEntry(314,"us",3,"en",11)); //United States of America
+ table.add(new MccEntry(315,"us",3,"en",11)); //United States of America
+ table.add(new MccEntry(316,"us",3,"en",11)); //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",14)); //Japan
+ table.add(new MccEntry(441,"jp",2,"ja",14)); //Japan
+ table.add(new MccEntry(450,"kr",2,"ko",13)); //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",13)); //China (People's Republic of)
+ table.add(new MccEntry(461,"cn",2,"zh",13)); //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",11)); //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",11)); //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 3dd9a01..ec6c023 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).
@@ -1368,29 +1386,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();
@@ -1535,6 +1530,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 1da9d4d..5412768 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;
@@ -737,8 +737,13 @@ 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);
}
public abstract String getPhoneName();
@@ -824,9 +829,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;
}
@@ -916,28 +931,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() {
@@ -952,6 +959,10 @@ public abstract class PhoneBase extends Handler implements Phone {
return mDataConnection.disableApnType(type);
}
+ public boolean isDataConnectivityPossible() {
+ return ((mDataConnection != null) && (mDataConnection.isDataPossible()));
+ }
+
/**
* simulateDataConnection
*
@@ -980,7 +991,7 @@ public abstract class PhoneBase extends Handler implements Phone {
}
mDataConnection.setState(dcState);
- notifyDataConnection(null);
+ notifyDataConnection(null, Phone.APN_TYPE_DEFAULT);
}
/**
@@ -1034,6 +1045,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..691271f 100644
--- a/telephony/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/PhoneNotifier.java
@@ -33,9 +33,12 @@ public interface PhoneNotifier {
public void notifyCallForwardingChanged(Phone sender);
- public void notifyDataConnection(Phone sender, String reason);
+ public void notifyDataConnection(Phone sender, String reason, String apnType);
- public void notifyDataConnectionFailed(Phone sender, String reason);
+ public void notifyDataConnection(Phone sender, String reason, String apnType,
+ Phone.DataState state);
+
+ public void notifyDataConnectionFailed(Phone sender, String reason, String apnType);
public void notifyDataActivity(Phone sender);
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 5e7dcb0..9e0c087 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();
}
@@ -660,22 +670,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();
}
@@ -764,6 +758,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 569ac5c..8c2280b 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);
}
@@ -2902,7 +2910,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/SipPhoneNotifier.java b/telephony/java/com/android/internal/telephony/SipPhoneNotifier.java
index 4092c69..4c4e718 100644
--- a/telephony/java/com/android/internal/telephony/SipPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/SipPhoneNotifier.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;
@@ -94,26 +96,45 @@ public class SipPhoneNotifier implements PhoneNotifier {
}
}
- public void notifyDataConnection(Phone sender, String reason) {
+ public void notifyDataConnection(Phone sender, String reason, String apnType) {
+ doNotifyDataConnection(sender, reason, apnType, sender.getDataConnectionState(apnType));
+ }
+
+ 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
}
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..6e53ec5 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -515,14 +515,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 +605,7 @@ public class CDMAPhone extends PhoneBase {
}
}
- public DataState getDataConnectionState() {
+ public DataState getDataConnectionState(String apnType) {
DataState ret = DataState.DISCONNECTED;
if (mSST == null) {
@@ -625,6 +617,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 +872,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 +1165,26 @@ public class CDMAPhone extends PhoneBase {
mSMS.setCellBroadcastConfig(configValuesArray, response);
}
+ /**
+ * Returns true if OTA Service Provisioning needs to be performed.
+ */
+ @Override
+ public 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;
+ }
+
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/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 9f2a44b..e499e95 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -23,14 +23,12 @@ 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;
@@ -50,8 +48,6 @@ import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.EventLogTags;
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;
@@ -305,9 +301,40 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
return true;
}
- private boolean isDataAllowed() {
- boolean roaming = phone.getServiceState().getRoaming();
- return getAnyDataEnabled() && (!roaming || getDataOnRoamingEnabled()) && mMasterDataEnabled;
+ protected boolean isDataAllowed() {
+ int psState = mCdmaPhone.mSST.getCurrentCdmaDataConnectionState();
+ boolean roaming = (phone.getServiceState().getRoaming() && !getDataOnRoamingEnabled());
+ boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
+
+ boolean allowed = (psState == ServiceState.STATE_IN_SERVICE &&
+ (phone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY ||
+ mCdmaPhone.mRuimRecords.getRecordsLoaded()) &&
+ (mCdmaPhone.mSST.isConcurrentVoiceAndData() ||
+ phone.getState() == Phone.State.IDLE) &&
+ !roaming &&
+ mMasterDataEnabled &&
+ desiredPowerState &&
+ !mPendingRestartRadio &&
+ !mCdmaPhone.needsOtaServiceProvisioning());
+ if (!allowed && DBG) {
+ String reason = "";
+ if (psState != ServiceState.STATE_IN_SERVICE) reason += " - psState= " + psState;
+ if (phone.mCM.getRadioState() != CommandsInterface.RadioState.NV_READY &&
+ !mCdmaPhone.mRuimRecords.getRecordsLoaded()) {
+ reason += " - radioState= " + phone.mCM.getRadioState() + " - RUIM not loaded";
+ }
+ if (phone.getState() != Phone.State.IDLE &&
+ mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
+ reason += " - concurrentVoiceAndData not allowed and state= " + phone.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) {
@@ -317,7 +344,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
// 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");
return true;
@@ -327,36 +355,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
boolean roaming = phone.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 ((state == State.IDLE || state == 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;
}
}
@@ -382,6 +387,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
setState(State.DISCONNECTING);
+ notifyDataAvailability(reason);
boolean notificationDeferred = false;
for (DataConnection conn : dataConnectionList) {
@@ -440,13 +446,13 @@ 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();
}
@@ -622,12 +628,13 @@ 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;
}
@@ -687,11 +694,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
// 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");
}
+ notifyDataAvailability(null);
+
if (state != State.IDLE) {
cleanUpConnection(true, null);
}
@@ -723,6 +732,10 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
if (ar.exception == null) {
+ // TODO: We should clear LinkProperties/Capabilities when torn down or disconnected
+ mLinkProperties = getLinkProperties(mActiveDataConnection);
+ mLinkCapabilities = getLinkCapabilities(mActiveDataConnection);
+
// everything is setup
notifyDefaultData(reason);
} else {
@@ -762,7 +775,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
onRestartRadio();
}
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
mActiveApn = null;
if (retryAfterDisconnected(reason)) {
trySetupData(reason);
@@ -789,7 +802,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
protected void onVoiceCallStarted() {
if (state == 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);
}
}
@@ -800,11 +814,12 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
if (state == 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
@@ -838,7 +853,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
private void onCdmaDataDetached() {
if (state == State.CONNECTED) {
startNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED);
+ notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED);
} else {
if (state == State.FAILED) {
cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED);
@@ -949,34 +964,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
}
- 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();
- }
- return null;
- }
-
- protected String[] getDnsServers(String apnType) {
- if (mActiveDataConnection != null) {
- return mActiveDataConnection.getDnsServers();
- }
- return null;
- }
-
public ArrayList<DataConnection> getAllDataConnections() {
return dataConnectionList;
}
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 2cad6cc..b71cf13 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -16,6 +16,16 @@
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.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 +48,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;
@@ -987,7 +986,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
mNeedFixZone = false;
if (zone != null) {
- if (getAutoTime()) {
+ if (getAutoTimeZone()) {
setAndBroadcastNetworkSetTimeZone(zone.getID());
}
saveNitzTimeZone(zone.getID());
@@ -1119,7 +1118,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
if (hasCdmaDataConnectionChanged || hasNetworkTypeChanged) {
- phone.notifyDataConnection(null);
+ phone.notifyDataConnection(null, null);
}
if (hasRoamingOn) {
@@ -1439,7 +1438,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
if (zone != null) {
- if (getAutoTime()) {
+ if (getAutoTimeZone()) {
setAndBroadcastNetworkSetTimeZone(zone.getID());
}
saveNitzTimeZone(zone.getID());
@@ -1529,6 +1528,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;
}
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 0f3b8ff..e95b2f9 100755
--- 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;
@@ -33,7 +30,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;
@@ -58,7 +54,7 @@ import static android.telephony.SmsMessage.MessageClass;
/**
* TODO(cleanup): internally returning null in many places makes
* debugging very hard (among many other reasons) and should be made
- * more meaningful (replaced with execptions for example). Null
+ * more meaningful (replaced with exceptions for example). Null
* returns should only occur at the very outside of the module/class
* scope.
*/
@@ -614,7 +610,7 @@ public class SmsMessage extends SmsMessageBase {
* incrementing within the range 1..65535 remembering the state
* via a persistent system property. (See C.S0015-B, v2.0,
* 4.3.1.5) Since this routine is expected to be accessed via via
- * binder-call, and hence should be threadsafe, it has been
+ * binder-call, and hence should be thread-safe, it has been
* synchronized.
*/
private synchronized static int getNextMessageId() {
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 0dcacc1..a67327a 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
@@ -17,7 +17,7 @@
package com.android.internal.telephony.cdma.sms;
-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 43971ff..30a6324 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..1572f09 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -180,8 +180,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 +189,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..66da6e8 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -27,15 +27,14 @@ 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;
@@ -58,6 +57,9 @@ 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;
/**
@@ -388,12 +390,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
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,13 +401,13 @@ 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) {
startNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_GPRS_ATTACHED);
+ notifyDataConnection(Phone.REASON_GPRS_ATTACHED);
} else {
if (state == State.FAILED) {
cleanUpConnection(false, Phone.REASON_GPRS_ATTACHED);
@@ -421,6 +417,35 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
+ protected boolean isDataAllowed() {
+ int gprsState = mGsmPhone.mSST.getCurrentGprsState();
+ boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState();
+
+ boolean allowed = ((gprsState == ServiceState.STATE_IN_SERVICE || noAutoAttach) &&
+ mGsmPhone.mSIMRecords.getRecordsLoaded() &&
+ phone.getState() == Phone.State.IDLE &&
+ mMasterDataEnabled &&
+ (!phone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
+ !mIsPsRestricted &&
+ desiredPowerState);
+ if (!allowed && DBG) {
+ String reason = "";
+ if (gprsState != ServiceState.STATE_IN_SERVICE) reason += " - gprs= " + gprsState;
+ if (!mGsmPhone.mSIMRecords.getRecordsLoaded()) reason += " - SIM not loaded";
+ if (phone.getState() != Phone.State.IDLE) {
+ reason += " - PhoneState= " + phone.getState();
+ }
+ if (!mMasterDataEnabled) reason += " - mMasterDataEnabled= false";
+ if (phone.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));
@@ -430,7 +455,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// 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");
return true;
@@ -439,19 +464,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
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) || (state == State.SCANNING)) &&
+ isDataAllowed() && getAnyDataEnabled()) {
if (state == State.IDLE) {
waitingApns = buildWaitingApns();
if (waitingApns.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));
@@ -461,22 +482,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (DBG) {
log ("Setup waitngApns : " + apnListToString(waitingApns));
}
- 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;
}
}
@@ -595,46 +605,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
pdp.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) {
for (int i = 0, s = states.size() ; i < s ; i++) {
@@ -746,7 +720,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,7 +730,7 @@ 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;
}
@@ -998,7 +972,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
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;
}
@@ -1091,7 +1065,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// 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");
}
@@ -1125,6 +1099,27 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
if (ar.exception == null) {
+ // TODO: We should clear LinkProperties/Capabilities when torn down or disconnected
+ mLinkProperties = getLinkProperties(mActivePdp);
+ mLinkCapabilities = getLinkCapabilities(mActivePdp);
+
+ ApnSetting apn = mActivePdp.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) {
+ Log.e(LOG_TAG, "UnknownHostException making ProxyProperties: " + e);
+ } catch (SecurityException e) {
+ Log.e(LOG_TAG, "SecurityException making ProxyProperties: " + e);
+ } catch (NumberFormatException e) {
+ Log.e(LOG_TAG, "NumberFormatException making ProxyProperties (" + apn.port +
+ "): " + e);
+ }
+ }
+
// everything is setup
if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
SystemProperties.set("gsm.defaultpdpcontext.active", "true");
@@ -1157,7 +1152,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// No try for permanent failure
if (cause.isPermanentFail()) {
notifyNoData(cause);
- phone.notifyDataConnection(Phone.REASON_APN_FAILED);
+ notifyDataConnection(Phone.REASON_APN_FAILED);
onEnableApn(apnTypeToId(mRequestedApnType), DISABLED);
return;
}
@@ -1186,7 +1181,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
reason = (String) ar.userObj;
}
setState(State.IDLE);
- phone.notifyDataConnection(reason);
+ notifyDataConnection(reason);
mActiveApn = null;
if (retryAfterDisconnected(reason)) {
trySetupData(reason);
@@ -1217,7 +1212,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
protected void onVoiceCallStarted() {
if (state == State.CONNECTED && ! mGsmPhone.mSST.isConcurrentVoiceAndData()) {
stopNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
+ notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
}
}
@@ -1225,7 +1220,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (state == 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();
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 90ecbd7..83ad552 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -16,6 +16,17 @@
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.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 +58,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;
@@ -995,7 +995,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
mNeedFixZone = false;
if (zone != null) {
- if (getAutoTime()) {
+ if (getAutoTimeZone()) {
setAndBroadcastNetworkSetTimeZone(zone.getID());
}
saveNitzTimeZone(zone.getID());
@@ -1018,7 +1018,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
if (hasNetworkTypeChanged) {
- phone.notifyDataConnection(null);
+ // TODO - do we really want this?
+ phone.notifyDataConnection(null, null);
}
if (hasRoamingOn) {
@@ -1475,7 +1476,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
if (zone != null) {
- if (getAutoTime()) {
+ if (getAutoTimeZone()) {
setAndBroadcastNetworkSetTimeZone(zone.getID());
}
saveNitzTimeZone(zone.getID());
@@ -1545,6 +1546,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;
}
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 6c989b4..f5d84eb 100644
--- a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
@@ -238,11 +238,9 @@ abstract class SipConnectionBase extends Connection {
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 bceceda..e0eac74 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -61,7 +61,6 @@ import com.android.internal.telephony.PhoneNotifier;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.PhoneSubInfo;
import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.UUSInfo;
import java.io.IOException;
import java.text.ParseException;
@@ -102,6 +101,14 @@ public class SipPhone extends SipPhoneBase {
// new Integer(Phone.PHONE_TYPE_GSM).toString());
}
+ @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);
}
@@ -168,10 +175,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);
@@ -821,10 +824,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 9098e6f..5f26af4 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -19,6 +19,7 @@ package com.android.internal.telephony.sip;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
+import android.net.LinkProperties;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Handler;
@@ -65,7 +66,7 @@ import com.android.internal.telephony.PhoneNotifier;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.PhoneSubInfo;
import com.android.internal.telephony.TelephonyProperties;
-//import com.android.internal.telephony.UUSInfo;
+import com.android.internal.telephony.UUSInfo;
import java.io.IOException;
import java.util.ArrayList;
@@ -102,13 +103,11 @@ 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);
@@ -533,6 +532,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
*/
diff --git a/telephony/mockril/Android.mk b/telephony/mockril/Android.mk
new file mode 100644
index 0000000..95ae84c
--- /dev/null
+++ b/telephony/mockril/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+
+LOCAL_PATH:=$(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := core framework
+
+LOCAL_STATIC_JAVA_LIBRARIES := librilproto-java
+
+LOCAL_MODULE := mockrilcontroller
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java b/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java
new file mode 100644
index 0000000..a5139bd
--- /dev/null
+++ b/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.mockril;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.internal.communication.MsgHeader;
+import com.android.internal.communication.Msg;
+import com.android.internal.telephony.RilChannel;
+import com.android.internal.telephony.ril_proto.RilCtrlCmds;
+import com.android.internal.telephony.ril_proto.RilCmds;
+import com.google.protobuf.micro.MessageMicro;
+
+import java.io.IOException;
+
+/**
+ * Contain a list of commands to control Mock RIL. Before using these commands the devices
+ * needs to be set with Mock RIL. Refer to hardware/ril/mockril/README.txt for details.
+ *
+ */
+public class MockRilController {
+ private static final String TAG = "MockRILController";
+ private RilChannel mRilChannel = null;
+ private Msg mMessage = null;
+
+ public MockRilController() throws IOException {
+ mRilChannel = RilChannel.makeRilChannel();
+ }
+
+ /**
+ * Close the channel after the communication is done.
+ * This method has to be called after the test is finished.
+ */
+ public void closeChannel() {
+ mRilChannel.close();
+ }
+
+ /**
+ * Send commands and return true on success
+ * @param cmd for MsgHeader
+ * @param token for MsgHeader
+ * @param status for MsgHeader
+ * @param pbData for Msg data
+ * @return true if command is sent successfully, false if it fails
+ */
+ private boolean sendCtrlCommand(int cmd, long token, int status, MessageMicro pbData) {
+ try {
+ Msg.send(mRilChannel, cmd, token, status, pbData);
+ } catch (IOException e) {
+ Log.v(TAG, "send command : %d failed: " + e.getStackTrace());
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Get control response
+ * @return Msg if response is received, else return null.
+ */
+ private Msg getCtrlResponse() {
+ Msg response = null;
+ try {
+ response = Msg.recv(mRilChannel);
+ } catch (IOException e) {
+ Log.v(TAG, "receive response for getRadioState() error: " + e.getStackTrace());
+ return null;
+ }
+ return response;
+ }
+
+ /**
+ * @return the radio state if it is valid, otherwise return -1
+ */
+ public int getRadioState() {
+ if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_GET_RADIO_STATE, 0, 0, null)) {
+ return -1;
+ }
+ Msg response = getCtrlResponse();
+ if (response == null) {
+ Log.v(TAG, "failed to get response");
+ return -1;
+ }
+ response.printHeader(TAG);
+ RilCtrlCmds.CtrlRspRadioState resp =
+ response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
+ int state = resp.getState();
+ if ((state >= RilCmds.RADIOSTATE_OFF) && (state <= RilCmds.RADIOSTATE_NV_READY))
+ return state;
+ else
+ return -1;
+ }
+
+ /**
+ * Set the radio state of mock ril to the given state
+ * @param state for given radio state
+ * @return true if the state is set successful, false if it fails
+ */
+ public boolean setRadioState(int state) {
+ RilCtrlCmds.CtrlReqRadioState req = new RilCtrlCmds.CtrlReqRadioState();
+ if (state < 0 || state > RilCmds.RADIOSTATE_NV_READY) {
+ Log.v(TAG, "the give radio state is not valid.");
+ return false;
+ }
+ req.setState(state);
+ if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, req)) {
+ Log.v(TAG, "send set radio state request failed.");
+ return false;
+ }
+ Msg response = getCtrlResponse();
+ if (response == null) {
+ Log.v(TAG, "failed to get response for setRadioState");
+ return false;
+ }
+ response.printHeader(TAG);
+ RilCtrlCmds.CtrlRspRadioState resp =
+ response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
+ int curstate = resp.getState();
+ return curstate == state;
+ }
+}
diff --git a/telephony/tests/telephonymockriltests/Android.mk b/telephony/tests/telephonymockriltests/Android.mk
new file mode 100644
index 0000000..9731d0d
--- /dev/null
+++ b/telephony/tests/telephonymockriltests/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_STATIC_JAVA_LIBRARIES := mockrilcontroller
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := TelephonyMockRilTests
+
+include $(BUILD_PACKAGE)
diff --git a/telephony/tests/telephonymockriltests/AndroidManifest.xml b/telephony/tests/telephonymockriltests/AndroidManifest.xml
new file mode 100644
index 0000000..63f44a2
--- /dev/null
+++ b/telephony/tests/telephonymockriltests/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.telephonymockriltests">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity android:label="TelephonyMockRilTest"
+ android:name="TelephonyMockRilTest">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation android:name=".TelephonyMockTestRunner"
+ android:targetPackage="com.android.telephonymockriltests"
+ android:label="Test runner for Telephony Tests Using Mock RIL"
+ />
+
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+ <uses-permission android:name="android.permission.INTERNET" />
+
+</manifest>
diff --git a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java b/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java
new file mode 100644
index 0000000..78ee738
--- /dev/null
+++ b/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephonymockriltests;
+
+import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+import com.android.internal.telephony.mockril.MockRilController;
+import android.util.Log;
+
+import com.android.telephonymockriltests.functional.SimpleTestUsingMockRil;
+
+import java.io.IOException;
+import junit.framework.TestSuite;
+import junit.framework.TestCase;
+
+/**
+ * Test runner for telephony tests that using Mock RIL
+ *
+ */
+public class TelephonyMockTestRunner extends InstrumentationTestRunner {
+ private static final String TAG="TelephonyMockTestRunner";
+ public MockRilController mController;
+
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(SimpleTestUsingMockRil.class);
+ return suite;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ try {
+ mController = new MockRilController();
+ } catch (IOException e) {
+ e.printStackTrace();
+ TestCase.assertTrue("Create Mock RIl Controller failed", false);
+ }
+ TestCase.assertNotNull(mController);
+ super.onCreate(icicle);
+ }
+
+ @Override
+ public void finish(int resultCode, Bundle results) {
+ if (mController != null)
+ mController.closeChannel();
+ super.finish(resultCode, results);
+ }
+}
diff --git a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java b/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java
new file mode 100644
index 0000000..3ea1cf2
--- /dev/null
+++ b/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephonymockriltests.functional;
+
+import com.android.internal.telephony.mockril.MockRilController;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import com.android.telephonymockriltests.TelephonyMockTestRunner;
+
+/**
+ * A simple test that using Mock RIL Controller
+ */
+public class SimpleTestUsingMockRil extends InstrumentationTestCase {
+ private static final String TAG = "SimpleTestUsingMockRil";
+ private MockRilController mMockRilCtrl = null;
+ private TelephonyMockTestRunner mRunner;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mRunner = (TelephonyMockTestRunner)getInstrumentation();
+ mMockRilCtrl = mRunner.mController;
+ assertNotNull(mMockRilCtrl);
+ }
+
+ /**
+ * Get the current radio state of RIL
+ */
+ public void testGetRadioState() {
+ int state = mMockRilCtrl.getRadioState();
+ Log.v(TAG, "testGetRadioState: " + state);
+ assertTrue(state >= 0 && state <= 9);
+ }
+
+ /**
+ * Set the current radio state of RIL
+ * and verify the radio state is set correctly
+ */
+ public void testSetRadioState() {
+ for (int state = 0; state <= 9; state++) {
+ Log.v(TAG, "set radio state to be " + state);
+ assertTrue("set radio state: " + state + " failed.",
+ mMockRilCtrl.setRadioState(state));
+ }
+ assertFalse("use an invalid radio state", mMockRilCtrl.setRadioState(-1));
+ assertFalse("the radio state doesn't exist", mMockRilCtrl.setRadioState(10));
+ }
+}
diff --git a/telephony/tests/telephonytests/Android.mk b/telephony/tests/telephonytests/Android.mk
index 45e265a..98e4403 100644
--- a/telephony/tests/telephonytests/Android.mk
+++ b/telephony/tests/telephonytests/Android.mk
@@ -5,6 +5,8 @@ LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_STATIC_JAVA_LIBRARIES := librilproto-java
+
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_PACKAGE_NAME := FrameworksTelephonyTests
diff --git a/telephony/tests/telephonytests/AndroidManifest.xml b/telephony/tests/telephonytests/AndroidManifest.xml
index 6a97423..ba1d957 100644
--- a/telephony/tests/telephonytests/AndroidManifest.xml
+++ b/telephony/tests/telephonytests/AndroidManifest.xml
@@ -32,6 +32,13 @@
android:targetPackage="com.android.frameworks.telephonytests"
android:label="Frameworks Telephony Tests">
</instrumentation>
+
+ <instrumentation android:name=".TelephonyMockRilTestRunner"
+ android:targetPackage="com.android.frameworks.telephonytests"
+ android:label="Test Runner for Mock Ril Tests"
+ />
+
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
+ <uses-permission android:name="android.permission.INTERNET" />
</manifest>
diff --git a/telephony/tests/telephonytests/src/android/telephony/PhoneNumberWatcherTest.java b/telephony/tests/telephonytests/src/android/telephony/PhoneNumberWatcherTest.java
deleted file mode 100644
index 88eaecd..0000000
--- a/telephony/tests/telephonytests/src/android/telephony/PhoneNumberWatcherTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.telephony.PhoneNumberFormattingTextWatcher;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.Selection;
-import android.text.SpannableStringBuilder;
-import android.text.TextWatcher;
-
-import junit.framework.TestCase;
-
-public class PhoneNumberWatcherTest extends TestCase {
- @SmallTest
- public void testHyphenation() throws Exception {
- SpannableStringBuilder number = new SpannableStringBuilder();
- TextWatcher tw = new PhoneNumberFormattingTextWatcher();
- number.append("555-1212");
- // Move the cursor to the left edge
- Selection.setSelection(number, 0);
- tw.beforeTextChanged(number, 0, 0, 1);
- // Insert an 8 at the beginning
- number.insert(0, "8");
- tw.afterTextChanged(number);
- assertEquals("855-512-12", number.toString());
- }
-
- @SmallTest
- public void testHyphenDeletion() throws Exception {
- SpannableStringBuilder number = new SpannableStringBuilder();
- TextWatcher tw = new PhoneNumberFormattingTextWatcher();
- number.append("555-1212");
- // Move the cursor to after the hyphen
- Selection.setSelection(number, 4);
- // Delete the hyphen
- tw.beforeTextChanged(number, 3, 1, 0);
- number.delete(3, 4);
- tw.afterTextChanged(number);
- // Make sure that it deleted the character before the hyphen
- assertEquals("551-212", number.toString());
-
- // Make sure it deals with left edge boundary case
- number.insert(0, "-");
- Selection.setSelection(number, 1);
- tw.beforeTextChanged(number, 0, 1, 0);
- number.delete(0, 1);
- tw.afterTextChanged(number);
- // Make sure that it deleted the character before the hyphen
- assertEquals("551-212", number.toString());
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java b/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java
new file mode 100644
index 0000000..9192f57
--- /dev/null
+++ b/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.frameworks.telephonytests;
+
+import android.os.Bundle;
+
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+import android.util.Log;
+
+import java.io.IOException;
+
+import com.android.internal.telephony.RilChannel;
+import com.android.internal.telephony.mockril.MockRilTest;
+
+import junit.framework.TestSuite;
+
+public class TelephonyMockRilTestRunner extends InstrumentationTestRunner {
+
+ public RilChannel mMockRilChannel;
+
+ @Override
+ public TestSuite getAllTests() {
+ log("getAllTests E");
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(MockRilTest.class);
+ log("getAllTests X");
+ return suite;
+ }
+
+ @Override
+ public ClassLoader getLoader() {
+ log("getLoader EX");
+ return TelephonyMockRilTestRunner.class.getClassLoader();
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ log("onCreate E");
+ try {
+ mMockRilChannel = RilChannel.makeRilChannel();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ log("onCreate X");
+
+ super.onCreate(icicle);
+ }
+
+ @Override
+ public void onDestroy() {
+ // I've not seen this called
+ log("onDestroy EX");
+ super.onDestroy();
+ }
+
+ @Override
+ public void onStart() {
+ // Called when the instrumentation thread is started.
+ // At the moment we don't need the thread so return
+ // which will shut down this unused thread.
+ log("onStart EX");
+ super.onStart();
+ }
+
+ @Override
+ public void finish(int resultCode, Bundle results) {
+ // Called when complete so I ask the mMockRilChannel to quit.
+ log("finish E");
+ mMockRilChannel.close();
+ log("finish X");
+ super.finish(resultCode, results);
+ }
+
+ private void log(String s) {
+ Log.e("TelephonyMockRilTestRunner", s);
+ }
+}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java
index 3a9c511..7011aeb 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.GsmAlphabet;
+
import junit.framework.TestCase;
import android.test.suitebuilder.annotation.LargeTest;
@@ -51,7 +53,7 @@ public class GsmAlphabetTest extends TestCase {
// '@' maps to char 0
assertEquals(0, GsmAlphabet.charToGsm('@'));
- // `a (a with grave accent) maps to last GSM charater
+ // `a (a with grave accent) maps to last GSM character
assertEquals(0x7f, GsmAlphabet.charToGsm('\u00e0'));
//
@@ -307,4 +309,26 @@ public class GsmAlphabetTest extends TestCase {
assertEquals("a",
GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1));
}
+
+ @SmallTest
+ public void testGsm8BitUpackedWithEuckr() throws Exception {
+ // Some feature phones in Korea store contacts as euc-kr.
+ // Test this situations.
+ byte unpacked[];
+
+ // Test general alphabet strings.
+ unpacked = IccUtils.hexStringToBytes("61626320646566FF");
+ assertEquals("abc def",
+ GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
+
+ // Test korean strings.
+ unpacked = IccUtils.hexStringToBytes("C5D7BDBAC6AEFF");
+ assertEquals("\uD14C\uC2A4\uD2B8",
+ GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
+
+ // Test gsm Extented Characters.
+ unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars);
+ assertEquals(sGsmExtendedChars,
+ GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
+ }
}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
index 3103fc1..215c6ce 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
@@ -24,8 +24,6 @@ import com.android.internal.util.HexDump;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
public class GsmSmsTest extends AndroidTestCase {
@SmallTest
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
index 2d6977c..7eb3df8 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
@@ -28,7 +28,7 @@ public class MccTableTest extends AndroidTestCase {
@SmallTest
public void testTimeZone() throws Exception {
- assertEquals(MccTable.defaultTimeZoneForMcc(208), "Europe/Paris");
+ assertEquals(MccTable.defaultTimeZoneForMcc(208), "ECT");
assertEquals(MccTable.defaultTimeZoneForMcc(232), "Europe/Vienna");
assertEquals(MccTable.defaultTimeZoneForMcc(655), "Africa/Johannesburg");
assertEquals(MccTable.defaultTimeZoneForMcc(440), "Asia/Tokyo");
diff --git a/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index de59b81..c4a6f53 100644
--- a/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -20,10 +20,6 @@ import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.SpannableStringBuilder;
import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.content.Context;
-
-import junit.framework.TestCase;
public class PhoneNumberUtilsTest extends AndroidTestCase {
@@ -503,4 +499,40 @@ public class PhoneNumberUtilsTest extends AndroidTestCase {
assertTrue(PhoneNumberUtils.isVoiceMailNumber(mVoiceMailNumber));
*/
}
+
+ @SmallTest
+ public void testFormatNumberToE164() {
+ assertEquals("+16502910000", PhoneNumberUtils.formatNumberToE164("650 2910000", "us"));
+ assertNull(PhoneNumberUtils.formatNumberToE164("1234567", "us"));
+ assertEquals("+18004664114", PhoneNumberUtils.formatNumberToE164("800-GOOG-114", "us"));
+ }
+
+ @SmallTest
+ public void testFormatNumber() {
+ assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("650 2910000", "us"));
+ assertEquals("123-4567", PhoneNumberUtils.formatNumber("1234567", "us"));
+ assertEquals("(800) 466-4114", PhoneNumberUtils.formatNumber("800-GOOG-114", "us"));
+
+ }
+
+ @SmallTest
+ public void testNormalizeNumber() {
+ assertEquals("6502910000", PhoneNumberUtils.normalizeNumber("650 2910000"));
+ assertEquals("1234567", PhoneNumberUtils.normalizeNumber("12,3#4*567"));
+ assertEquals("8004664114", PhoneNumberUtils.normalizeNumber("800-GOOG-114"));
+ assertEquals("+16502910000", PhoneNumberUtils.normalizeNumber("+1 650 2910000"));
+ }
+
+ @SmallTest
+ public void testFormatDailabeNumber() {
+ // Using the phoneNumberE164's country code
+ assertEquals("(650) 291-0000",
+ PhoneNumberUtils.formatNumber("6502910000", "+16502910000", "CN"));
+ // The phoneNumberE164 is null
+ assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("6502910000", null, "US"));
+ // The given number has a country code.
+ assertEquals("+1 650-291-0000", PhoneNumberUtils.formatNumber("+16502910000", null, "CN"));
+ // The given number was formatted.
+ assertEquals("650-291-0000", PhoneNumberUtils.formatNumber("650-291-0000", null, "US"));
+ }
}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
new file mode 100644
index 0000000..d2e573c
--- /dev/null
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.telephony;
+
+import android.telephony.PhoneNumberFormattingTextWatcher;
+import android.test.AndroidTestCase;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.SpannableStringBuilder;
+import android.text.TextWatcher;
+
+public class PhoneNumberWatcherTest extends AndroidTestCase {
+ public void testAppendChars() {
+ final String multiChars = "65012345";
+ final String formatted1 = "(650) 123-45";
+ TextWatcher textWatcher = getTextWatcher();
+ SpannableStringBuilder number = new SpannableStringBuilder();
+ // Append more than one chars
+ textWatcher.beforeTextChanged(number, 0, 0, multiChars.length());
+ number.append(multiChars);
+ Selection.setSelection(number, number.length());
+ textWatcher.onTextChanged(number, 0, 0, number.length());
+ textWatcher.afterTextChanged(number);
+ assertEquals(formatted1, number.toString());
+ assertEquals(formatted1.length(), Selection.getSelectionEnd(number));
+ // Append one chars
+ final char appendChar = '6';
+ final String formatted2 = "(650) 123-456";
+ int len = number.length();
+ textWatcher.beforeTextChanged(number, number.length(), 0, 1);
+ number.append(appendChar);
+ Selection.setSelection(number, number.length());
+ textWatcher.onTextChanged(number, len, 0, 1);
+ textWatcher.afterTextChanged(number);
+ assertEquals(formatted2, number.toString());
+ assertEquals(formatted2.length(), Selection.getSelectionEnd(number));
+ }
+
+ public void testRemoveLastChars() {
+ final String init = "65012345678";
+ final String result1 = "(650) 123-4567";
+ TextWatcher textWatcher = getTextWatcher();
+ // Remove the last char.
+ SpannableStringBuilder number = new SpannableStringBuilder(init);
+ int len = number.length();
+ textWatcher.beforeTextChanged(number, len - 1, 1, 0);
+ number.delete(len - 1, len);
+ Selection.setSelection(number, number.length());
+ textWatcher.onTextChanged(number, number.length() - 1, 1, 0);
+ textWatcher.afterTextChanged(number);
+ assertEquals(result1, number.toString());
+ assertEquals(result1.length(), Selection.getSelectionEnd(number));
+ // Remove last 5 chars
+ final String result2 = "(650) 123";
+ textWatcher.beforeTextChanged(number, number.length() - 4, 4, 0);
+ number.delete(number.length() - 5, number.length());
+ Selection.setSelection(number, number.length());
+ textWatcher.onTextChanged(number, number.length(), 4, 0);
+ textWatcher.afterTextChanged(number);
+ assertEquals(result2, number.toString());
+ assertEquals(result2.length(), Selection.getSelectionEnd(number));
+ }
+
+ public void testInsertChars() {
+ final String init = "(650) 23";
+ final String expected1 = "(650) 123";
+ TextWatcher textWatcher = getTextWatcher();
+
+ // Insert one char
+ SpannableStringBuilder number = new SpannableStringBuilder(init);
+ textWatcher.beforeTextChanged(number, 4, 0, 1);
+ number.insert(4, "1"); // (6501) 23
+ Selection.setSelection(number, 5); // make the cursor at right of 1
+ textWatcher.onTextChanged(number, 4, 0, 1);
+ textWatcher.afterTextChanged(number);
+ assertEquals(expected1, number.toString());
+ // the cursor should still at the right of '1'
+ assertEquals(7, Selection.getSelectionEnd(number));
+
+ // Insert multiple chars
+ final String expected2 = "(650) 145-6723";
+ textWatcher.beforeTextChanged(number, 7, 0, 4);
+ number.insert(7, "4567"); // change to (650) 1456723
+ Selection.setSelection(number, 11); // the cursor is at the right of '7'.
+ textWatcher.onTextChanged(number, 7, 0, 4);
+ textWatcher.afterTextChanged(number);
+ assertEquals(expected2, number.toString());
+ // the cursor should be still at the right of '7'
+ assertEquals(12, Selection.getSelectionEnd(number));
+ }
+
+ public void testStopFormatting() {
+ final String init = "(650) 123";
+ final String expected1 = "(650) 123 4";
+ TextWatcher textWatcher = getTextWatcher();
+
+ // Append space
+ SpannableStringBuilder number = new SpannableStringBuilder(init);
+ textWatcher.beforeTextChanged(number, 9, 0, 2);
+ number.insert(9, " 4"); // (6501) 23 4
+ Selection.setSelection(number, number.length()); // make the cursor at right of 4
+ textWatcher.onTextChanged(number, 9, 0, 2);
+ textWatcher.afterTextChanged(number);
+ assertEquals(expected1, number.toString());
+ // the cursor should still at the right of '1'
+ assertEquals(expected1.length(), Selection.getSelectionEnd(number));
+
+ // Delete a ')'
+ final String expected2 ="(650 123";
+ textWatcher = getTextWatcher();
+ number = new SpannableStringBuilder(init);
+ textWatcher.beforeTextChanged(number, 4, 1, 0);
+ number.delete(4, 5); // (6501 23 4
+ Selection.setSelection(number, 5); // make the cursor at right of 1
+ textWatcher.onTextChanged(number, 4, 1, 0);
+ textWatcher.afterTextChanged(number);
+ assertEquals(expected2, number.toString());
+ // the cursor should still at the right of '1'
+ assertEquals(5, Selection.getSelectionEnd(number));
+
+ // Insert a hyphen
+ final String expected3 ="(650) 12-3";
+ textWatcher = getTextWatcher();
+ number = new SpannableStringBuilder(init);
+ textWatcher.beforeTextChanged(number, 8, 0, 1);
+ number.insert(8, "-"); // (650) 12-3
+ Selection.setSelection(number, 9); // make the cursor at right of -
+ textWatcher.onTextChanged(number, 8, 0, 1);
+ textWatcher.afterTextChanged(number);
+ assertEquals(expected3, number.toString());
+ // the cursor should still at the right of '-'
+ assertEquals(9, Selection.getSelectionEnd(number));
+ }
+
+ public void testRestartFormatting() {
+ final String init = "(650) 123";
+ final String expected1 = "(650) 123 4";
+ TextWatcher textWatcher = getTextWatcher();
+
+ // Append space
+ SpannableStringBuilder number = new SpannableStringBuilder(init);
+ textWatcher.beforeTextChanged(number, 9, 0, 2);
+ number.insert(9, " 4"); // (650) 123 4
+ Selection.setSelection(number, number.length()); // make the cursor at right of 4
+ textWatcher.onTextChanged(number, 9, 0, 2);
+ textWatcher.afterTextChanged(number);
+ assertEquals(expected1, number.toString());
+ // the cursor should still at the right of '4'
+ assertEquals(expected1.length(), Selection.getSelectionEnd(number));
+
+ // Clear the current string, and start formatting again.
+ int len = number.length();
+ textWatcher.beforeTextChanged(number, 0, len, 0);
+ number.delete(0, len);
+ textWatcher.onTextChanged(number, 0, len, 0);
+ textWatcher.afterTextChanged(number);
+
+ final String expected2 = "(650) 123-4";
+ number = new SpannableStringBuilder(init);
+ textWatcher.beforeTextChanged(number, 9, 0, 1);
+ number.insert(9, "4"); // (650) 1234
+ Selection.setSelection(number, number.length()); // make the cursor at right of 4
+ textWatcher.onTextChanged(number, 9, 0, 1);
+ textWatcher.afterTextChanged(number);
+ assertEquals(expected2, number.toString());
+ // the cursor should still at the right of '4'
+ assertEquals(expected2.length(), Selection.getSelectionEnd(number));
+ }
+
+ public void testTextChangedByOtherTextWatcher() {
+ final TextWatcher cleanupTextWatcher = new TextWatcher() {
+ public void afterTextChanged(Editable s) {
+ s.clear();
+ }
+
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {
+ }
+
+ public void onTextChanged(CharSequence s, int start, int before,
+ int count) {
+ }
+ };
+ final String init = "(650) 123";
+ final String expected1 = "";
+ TextWatcher textWatcher = getTextWatcher();
+
+ SpannableStringBuilder number = new SpannableStringBuilder(init);
+ textWatcher.beforeTextChanged(number, 5, 0, 1);
+ number.insert(5, "4"); // (6504) 123
+ Selection.setSelection(number, 5); // make the cursor at right of 4
+ textWatcher.onTextChanged(number, 5, 0, 1);
+ number.setSpan(cleanupTextWatcher, 0, number.length(), 0);
+ textWatcher.afterTextChanged(number);
+ assertEquals(expected1, number.toString());
+ }
+
+ private TextWatcher getTextWatcher() {
+ return new PhoneNumberFormattingTextWatcher("US");
+ }
+}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java
index db38ede..ef62d85 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java
@@ -28,7 +28,7 @@ public class SimUtilsTest extends TestCase {
public void testBasic() throws Exception {
byte[] data, data2;
- /*
+ /*
* bcdToString()
*/
@@ -40,9 +40,13 @@ public class SimUtilsTest extends TestCase {
assertEquals("0126045001448486", IccUtils.bcdToString(data, 1, data.length - 2));
// Stops on invalid BCD value
- data = IccUtils.hexStringToBytes("98F062400510444868f2");
+ data = IccUtils.hexStringToBytes("98E062400510444868f2");
assertEquals("890", IccUtils.bcdToString(data, 0, data.length));
+ // skip the high nibble 'F' since some PLMNs have it
+ data = IccUtils.hexStringToBytes("98F062400510444868f2");
+ assertEquals("890260450014484862", IccUtils.bcdToString(data, 0, data.length));
+
/*
* gsmBcdByteToInt()
*/
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
index 427795b..8cb05cc 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.Phone;
+
/**
* Stub class used for unit tests
*/
@@ -32,7 +34,7 @@ public class TestPhoneNotifier implements PhoneNotifier {
public void notifyCellLocation(Phone sender) {
}
-
+
public void notifySignalStrength(Phone sender) {
}
@@ -42,10 +44,14 @@ public class TestPhoneNotifier implements PhoneNotifier {
public void notifyCallForwardingChanged(Phone sender) {
}
- public void notifyDataConnection(Phone sender, String reason) {
+ public void notifyDataConnection(Phone sender, String reason, String apnType) {
+ }
+
+ 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) {
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java
index b96743a..485542b 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java
@@ -18,27 +18,21 @@ package com.android.internal.telephony.gsm;
import android.os.AsyncResult;
import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
import android.os.Message;
-import android.os.Process;
import android.telephony.ServiceState;
import android.test.AndroidTestCase;
import android.test.PerformanceTestCase;
-import android.util.Log;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.MmiCode;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.TestPhoneNotifier;
import com.android.internal.telephony.gsm.CallFailCause;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.gsm.GSMTestHandler;
import com.android.internal.telephony.gsm.GsmMmiCode;
import com.android.internal.telephony.gsm.SuppServiceNotification;
-import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.test.SimulatedRadioControl;
import java.util.List;
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java
new file mode 100644
index 0000000..f0d5b31
--- /dev/null
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.mockril;
+
+import android.util.Log;
+import android.test.InstrumentationTestCase;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import com.android.internal.communication.MsgHeader;
+import com.android.internal.communication.Msg;
+import com.android.internal.telephony.RilChannel;
+import com.android.internal.telephony.ril_proto.RilCtrlCmds;
+import com.android.internal.telephony.ril_proto.RilCmds;
+
+import com.android.frameworks.telephonytests.TelephonyMockRilTestRunner;
+import com.google.protobuf.micro.InvalidProtocolBufferMicroException;
+
+// Test suite for test ril
+public class MockRilTest extends InstrumentationTestCase {
+ private static final String TAG = "MockRilTest";
+
+ RilChannel mMockRilChannel;
+ TelephonyMockRilTestRunner mRunner;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mRunner = (TelephonyMockRilTestRunner)getInstrumentation();
+ mMockRilChannel = mRunner.mMockRilChannel;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ static void log(String s) {
+ Log.v(TAG, s);
+ }
+
+ /**
+ * Test protobuf serialization and deserialization
+ * @throws InvalidProtocolBufferMicroException
+ */
+ public void testProtobufSerDes() throws InvalidProtocolBufferMicroException {
+ log("testProtobufSerdes E");
+
+ RilCtrlCmds.CtrlRspRadioState rs = new RilCtrlCmds.CtrlRspRadioState();
+ assertTrue(String.format("expected rs.state == 0 was %d", rs.getState()),
+ rs.getState() == 0);
+ rs.setState(1);
+ assertTrue(String.format("expected rs.state == 1 was %d", rs.getState()),
+ rs.getState() == 1);
+
+ byte[] rs_ser = rs.toByteArray();
+ RilCtrlCmds.CtrlRspRadioState rsNew = RilCtrlCmds.CtrlRspRadioState.parseFrom(rs_ser);
+ assertTrue(String.format("expected rsNew.state == 1 was %d", rs.getState()),
+ rs.getState() == 1);
+
+ log("testProtobufSerdes X");
+ }
+
+ /**
+ * Test echo command works using writeMsg & readMsg
+ */
+ public void testEchoMsg() throws IOException {
+ log("testEchoMsg E");
+
+ MsgHeader mh = new MsgHeader();
+ mh.setCmd(0);
+ mh.setToken(1);
+ mh.setStatus(2);
+ ByteBuffer data = ByteBuffer.allocate(3);
+ data.put((byte)3);
+ data.put((byte)4);
+ data.put((byte)5);
+ Msg.send(mMockRilChannel, mh, data);
+
+ Msg respMsg = Msg.recv(mMockRilChannel);
+ assertTrue(String.format("expected mhd.header.cmd == 0 was %d",respMsg.getCmd()),
+ respMsg.getCmd() == 0);
+ assertTrue(String.format("expected mhd.header.token == 1 was %d",respMsg.getToken()),
+ respMsg.getToken() == 1);
+ assertTrue(String.format("expected mhd.header.status == 2 was %d", respMsg.getStatus()),
+ respMsg.getStatus() == 2);
+ assertTrue(String.format("expected mhd.data[0] == 3 was %d", respMsg.getData(0)),
+ respMsg.getData(0) == 3);
+ assertTrue(String.format("expected mhd.data[1] == 4 was %d", respMsg.getData(1)),
+ respMsg.getData(1) == 4);
+ assertTrue(String.format("expected mhd.data[2] == 5 was %d", respMsg.getData(2)),
+ respMsg.getData(2) == 5);
+
+ log("testEchoMsg X");
+ }
+
+ /**
+ * Test get as
+ */
+ public void testGetAs() {
+ log("testGetAs E");
+
+ // Use a message header as the protobuf data content
+ MsgHeader mh = new MsgHeader();
+ mh.setCmd(12345);
+ mh.setToken(9876);
+ mh.setStatus(7654);
+ mh.setLengthData(4321);
+ byte[] data = mh.toByteArray();
+ MsgHeader mhResult = Msg.getAs(MsgHeader.class, data);
+
+ assertTrue(String.format("expected cmd == 12345 was %d", mhResult.getCmd()),
+ mhResult.getCmd() == 12345);
+ assertTrue(String.format("expected token == 9876 was %d", mhResult.getToken()),
+ mhResult.getToken() == 9876);
+ assertTrue(String.format("expected status == 7654 was %d", mhResult.getStatus()),
+ mhResult.getStatus() == 7654);
+ assertTrue(String.format("expected lengthData == 4321 was %d", mhResult.getLengthData()),
+ mhResult.getLengthData() == 4321);
+
+ Msg msg = Msg.obtain();
+ msg.setData(ByteBuffer.wrap(data));
+
+ mhResult = msg.getDataAs(MsgHeader.class);
+
+ assertTrue(String.format("expected cmd == 12345 was %d", mhResult.getCmd()),
+ mhResult.getCmd() == 12345);
+ assertTrue(String.format("expected token == 9876 was %d", mhResult.getToken()),
+ mhResult.getToken() == 9876);
+ assertTrue(String.format("expected status == 7654 was %d", mhResult.getStatus()),
+ mhResult.getStatus() == 7654);
+ assertTrue(String.format("expected lengthData == 4321 was %d", mhResult.getLengthData()),
+ mhResult.getLengthData() == 4321);
+
+ log("testGetAs X");
+ }
+
+ public void testGetRadioState() throws IOException {
+ log("testGetRadioState E");
+
+ Msg.send(mMockRilChannel, 1, 9876, 0, null);
+
+ Msg resp = Msg.recv(mMockRilChannel);
+ //resp.printHeader("testGetRadioState");
+
+ assertTrue(String.format("expected cmd == 1 was %d", resp.getCmd()),
+ resp.getCmd() == 1);
+ assertTrue(String.format("expected token == 9876 was %d", resp.getToken()),
+ resp.getToken() == 9876);
+ assertTrue(String.format("expected status == 0 was %d", resp.getStatus()),
+ resp.getStatus() == 0);
+
+ RilCtrlCmds.CtrlRspRadioState rsp = resp.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
+
+ int state = rsp.getState();
+ log("testGetRadioState state=" + state);
+ assertTrue(String.format("expected RadioState >= 0 && RadioState <= 9 was %d", state),
+ ((state >= 0) && (state <= 9)));
+
+ log("testGetRadioState X");
+ }
+
+ public void testSetRadioState() throws IOException {
+ log("testSetRadioState E");
+
+ RilCtrlCmds.CtrlReqRadioState cmdrs = new RilCtrlCmds.CtrlReqRadioState();
+ assertEquals(0, cmdrs.getState());
+
+ cmdrs.setState(RilCmds.RADIOSTATE_SIM_NOT_READY);
+ assertEquals(2, cmdrs.getState());
+
+ Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, cmdrs);
+
+ Msg resp = Msg.recv(mMockRilChannel);
+
+ RilCtrlCmds.CtrlRspRadioState rsp = resp.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
+
+ int state = rsp.getState();
+ log("get response for testSetRadioState: " + state);
+ assertTrue(RilCmds.RADIOSTATE_SIM_NOT_READY == state);
+ }
+}