summaryrefslogtreecommitdiffstats
path: root/telephony
diff options
context:
space:
mode:
Diffstat (limited to 'telephony')
-rw-r--r--telephony/java/android/telephony/CellLocation.java23
-rw-r--r--telephony/java/android/telephony/JapanesePhoneNumberFormatter.java14
-rw-r--r--telephony/java/android/telephony/NeighboringCellInfo.aidl16
-rw-r--r--telephony/java/android/telephony/NeighboringCellInfo.java14
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java105
-rw-r--r--telephony/java/android/telephony/PhoneStateListener.java57
-rw-r--r--telephony/java/android/telephony/ServiceState.java81
-rw-r--r--telephony/java/android/telephony/SignalStrength.aidl22
-rw-r--r--telephony/java/android/telephony/SignalStrength.java311
-rw-r--r--telephony/java/android/telephony/SmsManager.java52
-rw-r--r--telephony/java/android/telephony/SmsMessage.java173
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java142
-rw-r--r--telephony/java/android/telephony/gsm/SmsMessage.java7
-rw-r--r--telephony/java/android/telephony/package.html2
-rw-r--r--telephony/java/com/android/internal/telephony/BaseCommands.java117
-rw-r--r--telephony/java/com/android/internal/telephony/Call.java52
-rw-r--r--telephony/java/com/android/internal/telephony/CallTracker.java28
-rw-r--r--telephony/java/com/android/internal/telephony/CallerInfo.java61
-rw-r--r--telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java134
-rw-r--r--telephony/java/com/android/internal/telephony/CommandsInterface.java199
-rw-r--r--telephony/java/com/android/internal/telephony/Connection.java84
-rw-r--r--telephony/java/com/android/internal/telephony/DataCallState.java (renamed from telephony/java/com/android/internal/telephony/gsm/PDPContextState.java)20
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java94
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionTracker.java34
-rw-r--r--telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java6
-rw-r--r--telephony/java/com/android/internal/telephony/GsmAlphabet.java51
-rw-r--r--telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl4
-rw-r--r--telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl2
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl22
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl3
-rw-r--r--telephony/java/com/android/internal/telephony/IccConstants.java1
-rw-r--r--telephony/java/com/android/internal/telephony/IccRecords.java2
-rw-r--r--telephony/java/com/android/internal/telephony/IccVmFixedException.java2
-rw-r--r--telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java2
-rw-r--r--telephony/java/com/android/internal/telephony/Phone.java345
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java164
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneFactory.java55
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneProxy.java134
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java24
-rw-r--r--telephony/java/com/android/internal/telephony/RIL.java567
-rw-r--r--telephony/java/com/android/internal/telephony/RILConstants.java23
-rw-r--r--telephony/java/com/android/internal/telephony/SMSDispatcher.java217
-rw-r--r--telephony/java/com/android/internal/telephony/ServiceStateTracker.java25
-rw-r--r--telephony/java/com/android/internal/telephony/SmsHeader.java385
-rw-r--r--telephony/java/com/android/internal/telephony/SmsMessageBase.java47
-rw-r--r--telephony/java/com/android/internal/telephony/SmsResponse.java8
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyEventLog.java2
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyIntents.java49
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyProperties.java11
-rw-r--r--telephony/java/com/android/internal/telephony/WapPushOverSms.java47
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CDMAPhone.java570
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CallFailCause.java45
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaCall.java4
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java197
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java48
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java354
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java14
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java200
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java263
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java287
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java818
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/EriInfo.java43
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/EriManager.java436
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/FeatureCode.java6
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java7
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimRecords.java133
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java280
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/SmsMessage.java268
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/package.html2
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java588
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java80
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/UserData.java57
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/package.html2
-rwxr-xr-xtelephony/java/com/android/internal/telephony/gsm/GSMPhone.java49
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmConnection.java28
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java235
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java12
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java233
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java142
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/MccTable.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/PdpConnection.java106
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/PppLink.java219
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/RestrictedState.java12
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SIMRecords.java11
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java133
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsMessage.java117
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java4
-rwxr-xr-xtelephony/java/com/android/internal/telephony/gsm/package.html2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java40
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java12
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java6
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/Input.java4
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/Menu.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java8
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java4
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/StkService.java30
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java26
-rw-r--r--telephony/java/com/android/internal/telephony/test/ModelInterpreter.java70
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedCommands.java193
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java66
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java2
105 files changed, 7569 insertions, 2949 deletions
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index bb5f126..7d600f0 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -62,13 +62,10 @@ public abstract class CellLocation {
* @hide
*/
public static CellLocation newFromBundle(Bundle bundle) {
- // TODO: My need to be use: Settings.Secure.getInt(mContext, Settings.Secure.CURRENT_ACTIVE_PHONE, 0))
- // instead of SystemProperties???
-
- // NOTE here TelephonyManager.getDefault().getPhoneType() cannot be used since at startup
- // ITelephony have not been created
- if (RILConstants.CDMA_PHONE ==
- SystemProperties.getInt(Settings.Secure.CURRENT_ACTIVE_PHONE, RILConstants.GSM_PHONE)) {
+ // TelephonyManager.getDefault().getPhoneType() handles the case when
+ // ITelephony interface is not up yet.
+ int type = TelephonyManager.getDefault().getPhoneType();
+ if (type == RILConstants.CDMA_PHONE) {
return new CdmaCellLocation(bundle);
} else {
return new GsmCellLocation(bundle);
@@ -85,17 +82,13 @@ public abstract class CellLocation {
*
*/
public static CellLocation getEmpty() {
- // TODO: My need to be use: Settings.Secure.getInt(mContext, Settings.Secure.CURRENT_ACTIVE_PHONE, 0))
- // instead of SystemProperties???
-
- // NOTE here TelephonyManager.getDefault().getPhoneType() cannot be used since at startup
- // ITelephony have not been created
- if (RILConstants.CDMA_PHONE ==
- SystemProperties.getInt(Settings.Secure.CURRENT_ACTIVE_PHONE, RILConstants.GSM_PHONE)) {
+ // TelephonyManager.getDefault().getPhoneType() handles the case when
+ // ITelephony interface is not up yet.
+ int type = TelephonyManager.getDefault().getPhoneType();
+ if (type == RILConstants.CDMA_PHONE) {
return new CdmaCellLocation();
} else {
return new GsmCellLocation();
}
}
-
}
diff --git a/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java b/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java
index 8a82966..6390d8e 100644
--- a/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java
+++ b/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java
@@ -21,11 +21,11 @@ import android.text.Editable;
/*
* Japanese Phone number formatting rule is a bit complicated.
* Here are some valid examples:
- *
+ *
* 022-229-1234 0223-23-1234 022-301-9876 015-482-7849 0154-91-3478
* 01547-5-4534 090-1234-1234 080-0123-6789
* 0800-000-9999 0570-000-000 0276-00-0000
- *
+ *
* As you can see, there is no straight-forward rule here.
* In order to handle this, a big array is prepared.
*/
@@ -151,14 +151,14 @@ import android.text.Editable;
-100, -100, -45, -45, -100, -100, -100, -100, -100, -100,
-25, -35, -35, -35, -35, -35, -35, -25, -25, -35,
-35, -35, -35, -35, -35, -35, -35, -35, -35, -45};
-
+
public static void format(Editable text) {
// Here, "root" means the position of "'":
// 0'3, 0'90, and +81'-90
// (dash will be deleted soon, so it is actually +81'90).
int rootIndex = 1;
int length = text.length();
- if (length > 3
+ if (length > 3
&& text.subSequence(0, 3).toString().equals("+81")) {
rootIndex = 3;
} else if (length < 1 || text.charAt(0) != '0') {
@@ -176,10 +176,10 @@ import android.text.Editable;
i++;
}
}
-
+
length = text.length();
int dashposition;
-
+
i = rootIndex;
int base = 0;
while (i < length) {
@@ -208,7 +208,7 @@ import android.text.Editable;
i++;
}
}
-
+
if (length > 3 && rootIndex == 3) {
text.insert(rootIndex, "-");
}
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.aidl b/telephony/java/android/telephony/NeighboringCellInfo.aidl
index a7e709e..c464332 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.aidl
+++ b/telephony/java/android/telephony/NeighboringCellInfo.aidl
@@ -2,16 +2,16 @@
**
** Copyright 2007, The Android Open Source Project
**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
+** 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
+** 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
+** 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.
*/
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
index 326401a..f492abd 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.java
+++ b/telephony/java/android/telephony/NeighboringCellInfo.java
@@ -20,7 +20,7 @@ import android.os.Parcel;
import android.os.Parcelable;
/**
- * Represents the neighboring cell information, including
+ * Represents the neighboring cell information, including
* Received Signal Strength and Cell ID location.
*/
public class NeighboringCellInfo implements Parcelable
@@ -52,7 +52,7 @@ public class NeighboringCellInfo implements Parcelable
mRssi = rssi;
mCid = cid;
}
-
+
/**
* Initialize the object from a parcel.
*/
@@ -60,12 +60,12 @@ public class NeighboringCellInfo implements Parcelable
mRssi = in.readInt();
mCid = in.readInt();
}
-
+
/**
- * @return received signal strength in "asu", ranging from 0 - 31,
+ * @return received signal strength in "asu", ranging from 0 - 31,
* or UNKNOWN_RSSI if unknown
*
- * For GSM, dBm = -113 + 2*asu,
+ * For GSM, dBm = -113 + 2*asu,
* 0 means "-113 dBm or less" and 31 means "-51 dBm or greater"
*/
public int getRssi() {
@@ -95,7 +95,7 @@ public class NeighboringCellInfo implements Parcelable
@Override
public String toString() {
- return "["+ ((mCid == UNKNOWN_CID) ? "/" : Integer.toHexString(mCid))
+ return "["+ ((mCid == UNKNOWN_CID) ? "/" : Integer.toHexString(mCid))
+ " at " + ((mRssi == UNKNOWN_RSSI)? "/" : mRssi) + "]";
}
@@ -105,7 +105,7 @@ public class NeighboringCellInfo implements Parcelable
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mRssi);
- dest.writeInt(mCid);
+ dest.writeInt(mCid);
}
public static final Parcelable.Creator<NeighboringCellInfo> CREATOR
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index d3942fc..dbe8431 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -701,17 +701,6 @@ public class PhoneNumberUtils
}
/**
- * Note: calls extractNetworkPortion(), so do not use for
- * SIM EF[ADN] style records
- *
- * Exceptions thrown if extractNetworkPortion(s).length() == 0
- */
- public static byte[]
- networkPortionToCalledPartyBCD(String s) {
- return numberToCalledPartyBCD(extractNetworkPortion(s));
- }
-
- /**
* Return true iff the network portion of <code>address</code> is,
* as far as we can tell on the device, suitable for use as an SMS
* destination address.
@@ -744,12 +733,25 @@ public class PhoneNumberUtils
}
/**
+ * Note: calls extractNetworkPortion(), so do not use for
+ * SIM EF[ADN] style records
+ *
+ * Returns null if network portion is empty.
+ */
+ public static byte[]
+ networkPortionToCalledPartyBCD(String s) {
+ String networkPortion = extractNetworkPortion(s);
+ return numberToCalledPartyBCDHelper(networkPortion, false);
+ }
+
+ /**
* Same as {@link #networkPortionToCalledPartyBCD}, but includes a
* one-byte length prefix.
*/
public static byte[]
networkPortionToCalledPartyBCDWithLength(String s) {
- return numberToCalledPartyBCDWithLength(extractNetworkPortion(s));
+ String networkPortion = extractNetworkPortion(s);
+ return numberToCalledPartyBCDHelper(networkPortion, true);
}
/**
@@ -761,61 +763,46 @@ public class PhoneNumberUtils
*/
public static byte[]
numberToCalledPartyBCD(String number) {
- // The extra byte required for '+' is taken into consideration while calculating
- // length of ret.
- int size = (hasPlus(number) ? number.length() - 1 : number.length());
- byte[] ret = new byte[(size + 1) / 2 + 1];
-
- return numberToCalledPartyBCDHelper(ret, 0, number);
+ return numberToCalledPartyBCDHelper(number, false);
}
/**
- * Same as {@link #numberToCalledPartyBCD}, but includes a
- * one-byte length prefix.
+ * If includeLength is true, prepend a one-byte length value to
+ * the return array.
*/
private static byte[]
- numberToCalledPartyBCDWithLength(String number) {
- // The extra byte required for '+' is taken into consideration while calculating
- // length of ret.
- int size = (hasPlus(number) ? number.length() - 1 : number.length());
- int length = (size + 1) / 2 + 1;
- byte[] ret = new byte[length + 1];
-
- ret[0] = (byte) (length & 0xff);
- return numberToCalledPartyBCDHelper(ret, 1, number);
- }
-
- private static boolean
- hasPlus(String s) {
- return s.indexOf('+') >= 0;
- }
-
- private static byte[]
- numberToCalledPartyBCDHelper(byte[] ret, int offset, String number) {
- if (hasPlus(number)) {
- number = number.replaceAll("\\+", "");
- ret[offset] = (byte) TOA_International;
- } else {
- ret[offset] = (byte) TOA_Unknown;
+ numberToCalledPartyBCDHelper(String number, boolean includeLength) {
+ int numberLenReal = number.length();
+ int numberLenEffective = numberLenReal;
+ boolean hasPlus = number.indexOf('+') != -1;
+ if (hasPlus) numberLenEffective--;
+
+ if (numberLenEffective == 0) return null;
+
+ int resultLen = (numberLenEffective + 1) / 2; // Encoded numbers require only 4 bits each.
+ int extraBytes = 1; // Prepended TOA byte.
+ if (includeLength) extraBytes++; // Optional prepended length byte.
+ resultLen += extraBytes;
+
+ byte[] result = new byte[resultLen];
+
+ int digitCount = 0;
+ for (int i = 0; i < numberLenReal; i++) {
+ char c = number.charAt(i);
+ if (c == '+') continue;
+ int shift = ((digitCount & 0x01) == 1) ? 4 : 0;
+ result[extraBytes + (digitCount >> 1)] |= (byte)((charToBCD(c) & 0x0F) << shift);
+ digitCount++;
}
- int size = number.length();
- int curChar = 0;
- int countFullBytes = ret.length - offset - 1 - ((size - curChar) & 1);
- for (int i = 1; i < 1 + countFullBytes; i++) {
- ret[offset + i]
- = (byte) ((charToBCD(number.charAt(curChar++)))
- | (charToBCD(number.charAt(curChar++))) << 4);
- }
+ // 1-fill any trailing odd nibble/quartet.
+ if ((digitCount & 0x01) == 1) result[extraBytes + (digitCount >> 1)] |= 0xF0;
- // The left-over octet for odd-length phone numbers should be
- // filled with 0xf.
- if (countFullBytes + offset < ret.length - 1) {
- ret[ret.length - 1]
- = (byte) (charToBCD(number.charAt(curChar))
- | (0xf << 4));
- }
- return ret;
+ int offset = 0;
+ if (includeLength) result[offset++] = (byte)(resultLen - 1);
+ result[offset] = (byte)(hasPlus ? TOA_International : TOA_Unknown);
+
+ return result;
}
/** all of 'a' up to len must match non-US trunk prefix ('0') */
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index df6860b..e113680 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -4,6 +4,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.telephony.CellLocation;
import android.util.Log;
@@ -41,16 +42,22 @@ public class PhoneStateListener {
/**
* Listen for changes to the network signal strength (cellular).
+ * {@more}
+ * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
+ * READ_PHONE_STATE}
* <p>
- * Example: The status bar uses this to control the signal-strength
- * icon.
*
* @see #onSignalStrengthChanged
+ *
+ * TODO: @deprecated to be deprecated by LISTEN_SIGNAL_STRENGTHS, @see #onSignalStrengthsChanged
*/
public static final int LISTEN_SIGNAL_STRENGTH = 0x00000002;
/**
* Listen for changes to the message-waiting indicator.
+ * {@more}
+ * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
+ * READ_PHONE_STATE}
* <p>
* Example: The status bar uses this to determine when to display the
* voicemail icon.
@@ -61,7 +68,9 @@ public class PhoneStateListener {
/**
* Listen for changes to the call-forwarding indicator.
- *
+ * {@more}
+ * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
+ * READ_PHONE_STATE}
* @see #onCallForwardingIndicatorChanged
*/
public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008;
@@ -84,7 +93,9 @@ public class PhoneStateListener {
/**
* Listen for changes to the device call state.
- *
+ * {@more}
+ * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
+ * READ_PHONE_STATE}
* @see #onCallStateChanged
*/
public static final int LISTEN_CALL_STATE = 0x00000020;
@@ -99,7 +110,9 @@ public class PhoneStateListener {
/**
* Listen for changes to the direction of data traffic on the data
* connection (cellular).
- *
+ * {@more}
+ * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
+ * READ_PHONE_STATE}
* Example: The status bar uses this to display the appropriate
* data-traffic icon.
*
@@ -107,6 +120,18 @@ public class PhoneStateListener {
*/
public static final int LISTEN_DATA_ACTIVITY = 0x00000080;
+ /**
+ * Listen for changes to the network signal strengths (cellular).
+ * <p>
+ * Example: The status bar uses this to control the signal-strength
+ * icon.
+ *
+ * @see #onSignalStrengthsChanged
+ *
+ * @hide
+ */
+ public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100;
+
public PhoneStateListener() {
}
@@ -129,6 +154,7 @@ public class PhoneStateListener {
* @see ServiceState#STATE_IN_SERVICE
* @see ServiceState#STATE_OUT_OF_SERVICE
* @see ServiceState#STATE_POWER_OFF
+ * @deprecated, @see #onSignalStrengthsChanged
*/
public void onSignalStrengthChanged(int asu) {
// default implementation empty
@@ -185,12 +211,27 @@ public class PhoneStateListener {
* @see TelephonyManager#DATA_ACTIVITY_IN
* @see TelephonyManager#DATA_ACTIVITY_OUT
* @see TelephonyManager#DATA_ACTIVITY_INOUT
+ * @see TelephonyManager#DATA_ACTIVITY_DORMANT
*/
public void onDataActivity(int direction) {
// default implementation empty
}
/**
+ * Callback invoked when network signal strengths changes.
+ *
+ * @see ServiceState#STATE_EMERGENCY_ONLY
+ * @see ServiceState#STATE_IN_SERVICE
+ * @see ServiceState#STATE_OUT_OF_SERVICE
+ * @see ServiceState#STATE_POWER_OFF
+ *
+ * @hide
+ */
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+ // default implementation empty
+ }
+
+ /**
* The callback methods need to be called on the handler thread where
* this object was created. If the binder did that for us it'd be nice.
*/
@@ -229,6 +270,9 @@ public class PhoneStateListener {
public void onDataActivity(int direction) {
Message.obtain(mHandler, LISTEN_DATA_ACTIVITY, direction, 0, null).sendToTarget();
}
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+ Message.obtain(mHandler, LISTEN_SIGNAL_STRENGTHS, 0, 0, signalStrength).sendToTarget();
+ }
};
Handler mHandler = new Handler() {
@@ -259,6 +303,9 @@ public class PhoneStateListener {
case LISTEN_DATA_ACTIVITY:
PhoneStateListener.this.onDataActivity(msg.arg1);
break;
+ case LISTEN_SIGNAL_STRENGTHS:
+ PhoneStateListener.this.onSignalStrengthsChanged((SignalStrength)msg.obj);
+ break;
}
}
};
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 4de0954..50c4d41 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -99,12 +99,9 @@ public class ServiceState implements Parcelable {
public static final int REGISTRATION_STATE_UNKNOWN = 4;
/** @hide */
public static final int REGISTRATION_STATE_ROAMING = 5;
- /** @hide */
- public static final int REGISTRATION_STATE_ROAMING_AFFILIATE = 6;
private int mState = STATE_OUT_OF_SERVICE;
private boolean mRoaming;
- private int mExtendedCdmaRoaming;
private String mOperatorAlphaLong;
private String mOperatorAlphaShort;
private String mOperatorNumeric;
@@ -115,6 +112,8 @@ public class ServiceState implements Parcelable {
private boolean mCssIndicator;
private int mNetworkId;
private int mSystemId;
+ private int mCdmaRoamingIndicator;
+ private int mCdmaDefaultRoamingIndicator;
/**
* Create a new ServiceState from a intent notifier Bundle
@@ -159,7 +158,8 @@ public class ServiceState implements Parcelable {
mCssIndicator = s.mCssIndicator;
mNetworkId = s.mNetworkId;
mSystemId = s.mSystemId;
- mExtendedCdmaRoaming = s.mExtendedCdmaRoaming;
+ mCdmaRoamingIndicator = s.mCdmaRoamingIndicator;
+ mCdmaDefaultRoamingIndicator = s.mCdmaDefaultRoamingIndicator;
}
/**
@@ -176,7 +176,8 @@ public class ServiceState implements Parcelable {
mCssIndicator = (in.readInt() != 0);
mNetworkId = in.readInt();
mSystemId = in.readInt();
- mExtendedCdmaRoaming = in.readInt();
+ mCdmaRoamingIndicator = in.readInt();
+ mCdmaDefaultRoamingIndicator = in.readInt();
}
public void writeToParcel(Parcel out, int flags) {
@@ -190,7 +191,8 @@ public class ServiceState implements Parcelable {
out.writeInt(mCssIndicator ? 1 : 0);
out.writeInt(mNetworkId);
out.writeInt(mSystemId);
- out.writeInt(mExtendedCdmaRoaming);
+ out.writeInt(mCdmaRoamingIndicator);
+ out.writeInt(mCdmaDefaultRoamingIndicator);
}
public int describeContents() {
@@ -231,15 +233,25 @@ public class ServiceState implements Parcelable {
return mRoaming;
}
- /** @hide */
- public int getExtendedCdmaRoaming(){
- return this.mExtendedCdmaRoaming;
+ /**
+ * @hide
+ */
+ public int getCdmaRoamingIndicator(){
+ return this.mCdmaRoamingIndicator;
+ }
+
+ /**
+ * @hide
+ */
+ public int getCdmaDefaultRoamingIndicator(){
+ return this.mCdmaDefaultRoamingIndicator;
}
/**
* Get current registered operator name in long alphanumeric format
*
* In GSM/UMTS, long format can be upto 16 characters long
+ * In CDMA, returns the ERI text, if set, otherwise the ONS
*
* @return long name of operator, null if unregistered or unknown
*/
@@ -289,7 +301,8 @@ public class ServiceState implements Parcelable {
+ ((null == mOperatorAlphaLong) ? 0 : mOperatorAlphaLong.hashCode())
+ ((null == mOperatorAlphaShort) ? 0 : mOperatorAlphaShort.hashCode())
+ ((null == mOperatorNumeric) ? 0 : mOperatorNumeric.hashCode())
- + (mExtendedCdmaRoaming));
+ + mCdmaRoamingIndicator
+ + mCdmaDefaultRoamingIndicator);
}
@Override
@@ -316,7 +329,9 @@ public class ServiceState implements Parcelable {
&& equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
&& equalsHandlesNulls(mNetworkId, s.mNetworkId)
&& equalsHandlesNulls(mSystemId, s.mSystemId)
- && equalsHandlesNulls(mExtendedCdmaRoaming, s.mExtendedCdmaRoaming));
+ && equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator)
+ && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
+ s.mCdmaDefaultRoamingIndicator));
}
@Override
@@ -363,9 +378,10 @@ public class ServiceState implements Parcelable {
+ " " + (mIsManualNetworkSelection ? "(manual)" : "")
+ " " + radioTechnology
+ " " + (mCssIndicator ? "CSS supported" : "CSS not supported")
- + "NetworkId: " + mNetworkId
- + "SystemId: " + mSystemId
- + "ExtendedCdmaRoaming: " + mExtendedCdmaRoaming);
+ + " " + mNetworkId
+ + " " + mSystemId
+ + "RoamInd: " + mCdmaRoamingIndicator
+ + "DefRoamInd: " + mCdmaDefaultRoamingIndicator);
}
public void setStateOutOfService() {
@@ -379,7 +395,8 @@ public class ServiceState implements Parcelable {
mCssIndicator = false;
mNetworkId = -1;
mSystemId = -1;
- mExtendedCdmaRoaming = -1;
+ mCdmaRoamingIndicator = -1;
+ mCdmaDefaultRoamingIndicator = -1;
}
public void setStateOff() {
@@ -393,7 +410,8 @@ public class ServiceState implements Parcelable {
mCssIndicator = false;
mNetworkId = -1;
mSystemId = -1;
- mExtendedCdmaRoaming = -1;
+ mCdmaRoamingIndicator = -1;
+ mCdmaDefaultRoamingIndicator = -1;
}
public void setState(int state) {
@@ -404,9 +422,18 @@ public class ServiceState implements Parcelable {
mRoaming = roaming;
}
- /** @hide */
- public void setExtendedCdmaRoaming (int roaming) {
- this.mExtendedCdmaRoaming = roaming;
+ /**
+ * @hide
+ */
+ public void setCdmaRoamingIndicator(int roaming) {
+ this.mCdmaRoamingIndicator = roaming;
+ }
+
+ /**
+ * @hide
+ */
+ public void setCdmaDefaultRoamingIndicator (int roaming) {
+ this.mCdmaDefaultRoamingIndicator = roaming;
}
public void setOperatorName(String longName, String shortName, String numeric) {
@@ -415,6 +442,16 @@ public class ServiceState implements Parcelable {
mOperatorNumeric = numeric;
}
+ /**
+ * In CDMA mOperatorAlphaLong can be set from the ERI
+ * text, this is done from the CDMAPhone and not from the CdmaServiceStateTracker
+ *
+ * @hide
+ */
+ public void setCdmaEriText(String longName) {
+ mOperatorAlphaLong = longName;
+ }
+
public void setIsManualSelection(boolean isManual) {
mIsManualNetworkSelection = isManual;
}
@@ -447,7 +484,8 @@ public class ServiceState implements Parcelable {
mCssIndicator = m.getBoolean("cssIndicator");
mNetworkId = m.getInt("networkId");
mSystemId = m.getInt("systemId");
- mExtendedCdmaRoaming = m.getInt("extendedCdmaRoaming");
+ mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator");
+ mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator");
}
/**
@@ -467,7 +505,8 @@ public class ServiceState implements Parcelable {
m.putBoolean("cssIndicator", mCssIndicator);
m.putInt("networkId", mNetworkId);
m.putInt("systemId", mSystemId);
- m.putInt("extendedCdmaRoaming", mExtendedCdmaRoaming);
+ m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator);
+ m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
}
//***** CDMA
diff --git a/telephony/java/android/telephony/SignalStrength.aidl b/telephony/java/android/telephony/SignalStrength.aidl
new file mode 100644
index 0000000..c25411e
--- /dev/null
+++ b/telephony/java/android/telephony/SignalStrength.aidl
@@ -0,0 +1,22 @@
+/* //device/java/android/android/content/Intent.aidl
+**
+** Copyright (C) 2009 Qualcomm Innovation Center, Inc. All Rights Reserved.
+** 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.
+*/
+
+package android.telephony;
+
+parcelable SignalStrength;
+
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
new file mode 100644
index 0000000..8ed0065
--- /dev/null
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2009 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * 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.
+ */
+
+package android.telephony;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * Contains phone signal strength related information.
+ *
+ * @hide
+ */
+public class SignalStrength implements Parcelable {
+
+ static final String LOG_TAG = "PHONE";
+
+ private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
+ private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
+ private int mCdmaDbm; // This value is the RSSI value
+ private int mCdmaEcio; // This value is the Ec/Io
+ private int mEvdoDbm; // This value is the EVDO RSSI value
+ private int mEvdoEcio; // This value is the EVDO Ec/Io
+ private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio
+
+ private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
+
+ /**
+ * Create a new SignalStrength from a intent notifier Bundle
+ *
+ * This method is used by PhoneStateIntentReceiver and maybe by
+ * external applications.
+ *
+ * @param m Bundle from intent notifier
+ * @return newly created SignalStrength
+ *
+ */
+ public static SignalStrength newFromBundle(Bundle m) {
+ SignalStrength ret;
+ ret = new SignalStrength();
+ ret.setFromNotifierBundle(m);
+ return ret;
+ }
+
+ /**
+ * Empty constructor
+ *
+ */
+ public SignalStrength() {
+ mGsmSignalStrength = 99;
+ mGsmBitErrorRate = -1;
+ mCdmaDbm = -1;
+ mCdmaEcio = -1;
+ mEvdoDbm = -1;
+ mEvdoEcio = -1;
+ mEvdoSnr = -1;
+ isGsm = true;
+ }
+
+ /**
+ * Constructor
+ *
+ */
+ public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
+ int cdmaDbm, int cdmaEcio,
+ int evdoDbm, int evdoEcio, int evdoSnr, boolean gsm) {
+ mGsmSignalStrength = gsmSignalStrength;
+ mGsmBitErrorRate = gsmBitErrorRate;
+ mCdmaDbm = cdmaDbm;
+ mCdmaEcio = cdmaEcio;
+ mEvdoDbm = evdoDbm;
+ mEvdoEcio = evdoEcio;
+ mEvdoSnr = evdoSnr;
+ isGsm = gsm;
+ }
+
+ /**
+ * Copy constructors
+ *
+ * @param s Source SignalStrength
+ */
+ public SignalStrength(SignalStrength s) {
+ copyFrom(s);
+ }
+
+ /**
+ * @hide
+ */
+ protected void copyFrom(SignalStrength s) {
+ mGsmSignalStrength = s.mGsmSignalStrength;
+ mGsmBitErrorRate = s.mGsmBitErrorRate;
+ mCdmaDbm = s.mCdmaDbm;
+ mCdmaEcio = s.mCdmaEcio;
+ mEvdoDbm = s.mEvdoDbm;
+ mEvdoEcio = s.mEvdoEcio;
+ mEvdoSnr = s.mEvdoSnr;
+ isGsm = s.isGsm;
+ }
+
+ /**
+ * Construct a SignalStrength object from the given parcel.
+ */
+ public SignalStrength(Parcel in) {
+ mGsmSignalStrength = in.readInt();
+ mGsmBitErrorRate = in.readInt();
+ mCdmaDbm = in.readInt();
+ mCdmaEcio = in.readInt();
+ mEvdoDbm = in.readInt();
+ mEvdoEcio = in.readInt();
+ mEvdoSnr = in.readInt();
+ isGsm = (in.readInt() != 0);
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mGsmSignalStrength);
+ out.writeInt(mGsmBitErrorRate);
+ out.writeInt(mCdmaDbm);
+ out.writeInt(mCdmaEcio);
+ out.writeInt(mEvdoDbm);
+ out.writeInt(mEvdoEcio);
+ out.writeInt(mEvdoSnr);
+ out.writeInt(isGsm ? 1 : 0);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Parcelable.Creator<SignalStrength> CREATOR = new Parcelable.Creator() {
+ public SignalStrength createFromParcel(Parcel in) {
+ return new SignalStrength(in);
+ }
+
+ public SignalStrength[] newArray(int size) {
+ return new SignalStrength[size];
+ }
+ };
+
+ /**
+ * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS 27.007 8.5
+ */
+ public int getGsmSignalStrength() {
+ return this.mGsmSignalStrength;
+ }
+
+ /**
+ * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5
+ */
+ public int getGsmBitErrorRate() {
+ return this.mGsmBitErrorRate;
+ }
+
+ /**
+ * Get the CDMA RSSI value in dBm
+ */
+ public int getCdmaDbm() {
+ return this.mCdmaDbm;
+ }
+
+ /**
+ * Get the CDMA Ec/Io value in dB*10
+ */
+ public int getCdmaEcio() {
+ return this.mCdmaEcio;
+ }
+
+ /**
+ * Get the EVDO RSSI value in dBm
+ */
+ public int getEvdoDbm() {
+ return this.mEvdoDbm;
+ }
+
+ /**
+ * Get the EVDO Ec/Io value in dB*10
+ */
+ public int getEvdoEcio() {
+ return this.mEvdoEcio;
+ }
+
+ /**
+ * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
+ */
+ public int getEvdoSnr() {
+ return this.mEvdoSnr;
+ }
+
+ /**
+ * @hide
+ */
+ public boolean isGsm() {
+ return this.isGsm;
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public int hashCode() {
+ return ((mGsmSignalStrength * 0x1234)
+ + mGsmBitErrorRate
+ + mCdmaDbm + mCdmaEcio
+ + mEvdoDbm + mEvdoEcio + mEvdoSnr
+ + (isGsm ? 1 : 0));
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public boolean equals (Object o) {
+ SignalStrength s;
+
+ try {
+ s = (SignalStrength) o;
+ } catch (ClassCastException ex) {
+ return false;
+ }
+
+ if (o == null) {
+ return false;
+ }
+
+ return (mGsmSignalStrength == s.mGsmSignalStrength
+ && mGsmBitErrorRate == s.mGsmBitErrorRate
+ && mCdmaDbm == s.mCdmaDbm
+ && mCdmaEcio == s.mCdmaEcio
+ && mEvdoDbm == s.mEvdoDbm
+ && mEvdoEcio == s.mEvdoEcio
+ && mEvdoSnr == s.mEvdoSnr
+ && isGsm == s.isGsm);
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public String toString() {
+ return ("SignalStrength:"
+ + " " + mGsmSignalStrength
+ + " " + mGsmBitErrorRate
+ + " " + mCdmaDbm
+ + " " + mCdmaEcio
+ + " " + mEvdoDbm
+ + " " + mEvdoEcio
+ + " " + mEvdoSnr
+ + " " + (isGsm ? "gsm" : "cdma"));
+ }
+
+ /**
+ * Test whether two objects hold the same data values or both are null
+ *
+ * @param a first obj
+ * @param b second obj
+ * @return true if two objects equal or both are null
+ * @hide
+ */
+ private static boolean equalsHandlesNulls (Object a, Object b) {
+ return (a == null) ? (b == null) : a.equals (b);
+ }
+
+ /**
+ * Set SignalStrength based on intent notifier map
+ *
+ * @param m intent notifier map
+ * @hide
+ */
+ private void setFromNotifierBundle(Bundle m) {
+ mGsmSignalStrength = m.getInt("GsmSignalStrength");
+ mGsmBitErrorRate = m.getInt("GsmBitErrorRate");
+ mCdmaDbm = m.getInt("CdmaDbm");
+ mCdmaEcio = m.getInt("CdmaEcio");
+ mEvdoDbm = m.getInt("EvdoDbm");
+ mEvdoEcio = m.getInt("EvdoEcio");
+ mEvdoSnr = m.getInt("EvdoSnr");
+ isGsm = m.getBoolean("isGsm");
+ }
+
+ /**
+ * Set intent notifier Bundle based on SignalStrength
+ *
+ * @param m intent notifier Bundle
+ * @hide
+ */
+ public void fillInNotifierBundle(Bundle m) {
+ m.putInt("GsmSignalStrength", mGsmSignalStrength);
+ m.putInt("GsmBitErrorRate", mGsmBitErrorRate);
+ m.putInt("CdmaDbm", mCdmaDbm);
+ m.putInt("CdmaEcio", mCdmaEcio);
+ m.putInt("EvdoDbm", mEvdoDbm);
+ m.putInt("EvdoEcio", mEvdoEcio);
+ m.putInt("EvdoSnr", mEvdoSnr);
+ m.putBoolean("isGsm", Boolean.valueOf(isGsm));
+ }
+}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 9395d66..890f930 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -22,7 +22,6 @@ import android.os.ServiceManager;
import android.text.TextUtils;
import com.android.internal.telephony.EncodeException;
-import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.ISms;
import com.android.internal.telephony.IccConstants;
import com.android.internal.telephony.SmsRawData;
@@ -31,14 +30,12 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-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_UNKNOWN;
-import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
-import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
-import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS;
-import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER;
+/*
+ * 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
+ * interfering with the API...
+ */
/**
* Manages SMS operations such as sending data, text, and pdu SMS messages.
@@ -88,7 +85,7 @@ public final class SmsManager {
}
/**
- * Divide a text message into several messages, none bigger than
+ * Divide a message text into several fragments, none bigger than
* the maximum SMS message size.
*
* @param text the original message. Must not be null.
@@ -96,40 +93,7 @@ public final class SmsManager {
* comprise the original message
*/
public ArrayList<String> divideMessage(String text) {
- int size = text.length();
- int[] params = SmsMessage.calculateLength(text, false);
- /* SmsMessage.calculateLength returns an int[4] with:
- * int[0] being the number of SMS's required,
- * int[1] the number of code units used,
- * int[2] is the number of code units remaining until the next message.
- * int[3] is the encoding type that should be used for the message.
- */
- int messageCount = params[0];
- int encodingType = params[3];
- ArrayList<String> result = new ArrayList<String>(messageCount);
-
- int start = 0;
- int limit;
-
- if (messageCount > 1) {
- limit = (encodingType == ENCODING_7BIT)?
- MAX_USER_DATA_SEPTETS_WITH_HEADER: MAX_USER_DATA_BYTES_WITH_HEADER;
- } else {
- limit = (encodingType == ENCODING_7BIT)?
- MAX_USER_DATA_SEPTETS: MAX_USER_DATA_BYTES;
- }
-
- try {
- while (start < size) {
- int end = GsmAlphabet.findLimitIndex(text, start, limit, encodingType);
- result.add(text.substring(start, end));
- start = end;
- }
- }
- catch (EncodeException e) {
- // ignore it.
- }
- return result;
+ return SmsMessage.fragmentText(text);
}
/**
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index 3b7f4b5..775b034 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -17,11 +17,17 @@
package android.telephony;
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;
+import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
+
+import java.lang.Math;
+import java.util.ArrayList;
import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
@@ -43,19 +49,41 @@ public class SmsMessage {
UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
}
- /** Unknown encoding scheme (see TS 23.038) */
+ /**
+ * TODO(cleanup): given that we now have more than one possible
+ * 7bit encoding, this result starts to look rather vague and
+ * maybe confusing... If this is just an indication of code unit
+ * size, maybe that is no problem. Otherwise, should we try to
+ * create an aggregate collection of GSM and CDMA encodings? CDMA
+ * contains a superset of the encodings we use (it does not
+ * support 8-bit GSM, but we also do not use that encoding
+ * currently)... We could get rid of these and directly reference
+ * the CDMA encoding definitions...
+ */
+
+ /** User data text encoding code unit size */
public static final int ENCODING_UNKNOWN = 0;
- /** 7-bit encoding scheme (see TS 23.038) */
public static final int ENCODING_7BIT = 1;
- /** 8-bit encoding scheme (see TS 23.038) */
public static final int ENCODING_8BIT = 2;
- /** 16-bit encoding scheme (see TS 23.038) */
public static final int ENCODING_16BIT = 3;
/** The maximum number of payload bytes per message */
public static final int MAX_USER_DATA_BYTES = 140;
/**
+ * TODO(cleanup): It would be more flexible and less fragile to
+ * rewrite this (meaning get rid of the following constant) such
+ * that an actual UDH is taken into consideration (meaning its
+ * length is measured), allowing for messages that actually
+ * contain other UDH fields... Hence it is actually a shame to
+ * extend the API with this constant. If necessary, maybe define
+ * the size of such a header and let the math for calculating
+ * max_octets/septets be done elsewhere. And, while I am griping,
+ * if we use the word septet, we should use the word octet in
+ * corresponding places, not byte...
+ */
+
+ /**
* The maximum number of payload bytes per message if a user data header
* is present. This assumes the header only contains the
* CONCATENATED_8_BIT_REFERENCE element.
@@ -221,54 +249,95 @@ public class SmsMessage {
}
}
+ /*
+ * TODO(cleanup): It would make some sense if the result of
+ * preprocessing a message to determine the proper encoding (ie
+ * the resulting datastructure from calculateLength) could be
+ * passed as an argument to the actual final encoding function.
+ * This would better ensure that the logic behind size calculation
+ * actually matched the encoding.
+ */
+
/**
* Calculates the number of SMS's required to encode the message body and
- * the number of characters remaining until the next message, given the
- * current encoding.
+ * the number of characters remaining until the next message.
*
- * @param messageBody the message to encode
- * @param use7bitOnly if true, characters that are not part of the GSM
- * alphabet are counted as a single space char. If false, a
- * messageBody containing non-GSM alphabet characters is calculated
- * for 16-bit encoding.
- * @return an int[4] with int[0] being the number of SMS's required, int[1]
- * the number of code units used, and int[2] is the number of code
- * units remaining until the next message. int[3] is the encoding
- * type that should be used for the message.
- */
- public static int[] calculateLength(CharSequence messageBody, boolean use7bitOnly) {
+ * @param msgBody the message to encode
+ * @param use7bitOnly if true, characters that are not part of the
+ * radio-specific 7-bit encoding are counted as single
+ * space chars. If false, and if the messageBody contains
+ * non-7-bit encodable characters, length is calculated
+ * using a 16-bit encoding.
+ * @return an int[4] with int[0] being the number of SMS's
+ * required, int[1] the number of code units used, and
+ * int[2] is the number of code units remaining until the
+ * next message. int[3] is an indicator of the encoding
+ * code unit size (see the ENCODING_* definitions in this
+ * class).
+ */
+ public static int[] calculateLength(CharSequence msgBody, boolean use7bitOnly) {
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+ TextEncodingDetails ted = (PHONE_TYPE_CDMA == activePhone) ?
+ com.android.internal.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly) :
+ com.android.internal.telephony.cdma.SmsMessage.calculateLength(msgBody, use7bitOnly);
int ret[] = new int[4];
+ ret[0] = ted.msgCount;
+ ret[1] = ted.codeUnitCount;
+ ret[2] = ted.codeUnitsRemaining;
+ ret[3] = ted.codeUnitSize;
+ return ret;
+ }
+
+ /**
+ * Divide a message text into several fragments, none bigger than
+ * the maximum SMS message text size.
+ *
+ * @param text text, must not be null.
+ * @return an <code>ArrayList</code> of strings that, in order,
+ * comprise the original msg text
+ */
+ public static ArrayList<String> fragmentText(String text) {
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+ TextEncodingDetails ted = (PHONE_TYPE_CDMA == activePhone) ?
+ com.android.internal.telephony.gsm.SmsMessage.calculateLength(text, false) :
+ com.android.internal.telephony.cdma.SmsMessage.calculateLength(text, false);
+
+ // TODO(cleanup): The code here could be rolled into the logic
+ // below cleanly if these MAX_* constants were defined more
+ // flexibly...
+
+ int limit;
+ if (ted.msgCount > 1) {
+ limit = (ted.codeUnitSize == ENCODING_7BIT) ?
+ MAX_USER_DATA_SEPTETS_WITH_HEADER : MAX_USER_DATA_BYTES_WITH_HEADER;
+ } else {
+ limit = (ted.codeUnitSize == ENCODING_7BIT) ?
+ MAX_USER_DATA_SEPTETS : MAX_USER_DATA_BYTES;
+ }
- try {
- // Try GSM alphabet
- int septets = GsmAlphabet.countGsmSeptets(messageBody, !use7bitOnly);
- ret[1] = septets;
- if (septets > MAX_USER_DATA_SEPTETS) {
- ret[0] = (septets / MAX_USER_DATA_SEPTETS_WITH_HEADER) + 1;
- ret[2] = MAX_USER_DATA_SEPTETS_WITH_HEADER
- - (septets % MAX_USER_DATA_SEPTETS_WITH_HEADER);
- } else {
- ret[0] = 1;
- ret[2] = MAX_USER_DATA_SEPTETS - septets;
+ int pos = 0; // Index in code units.
+ int textLen = text.length();
+ ArrayList<String> result = new ArrayList<String>(ted.msgCount);
+ while (pos < textLen) {
+ int nextPos = 0; // Counts code units.
+ if (ted.codeUnitSize == ENCODING_7BIT) {
+ if (PHONE_TYPE_CDMA == activePhone) {
+ nextPos = pos + Math.min(limit, textLen - pos);
+ } else {
+ nextPos = GsmAlphabet.findGsmSeptetLimitIndex(text, pos, limit);
+ }
+ } else { // Assume unicode.
+ nextPos = pos + Math.min(limit / 2, textLen - pos);
}
- ret[3] = ENCODING_7BIT;
- } catch (EncodeException ex) {
- // fall back to UCS-2
- int octets = messageBody.length() * 2;
- ret[1] = messageBody.length();
- if (octets > MAX_USER_DATA_BYTES) {
- // 6 is the size of the user data header
- ret[0] = (octets / MAX_USER_DATA_BYTES_WITH_HEADER) + 1;
- ret[2] = (MAX_USER_DATA_BYTES_WITH_HEADER
- - (octets % MAX_USER_DATA_BYTES_WITH_HEADER))/2;
- } else {
- ret[0] = 1;
- ret[2] = (MAX_USER_DATA_BYTES - octets)/2;
+ if ((nextPos <= pos) || (nextPos > textLen)) {
+ Log.e(LOG_TAG, "fragmentText failed (" + pos + " >= " + nextPos + " or " +
+ nextPos + " >= " + textLen + ")");
+ break;
}
- ret[3] = ENCODING_16BIT;
+ result.add(text.substring(pos, nextPos));
+ pos = nextPos;
}
-
- return ret;
+ return result;
}
/**
@@ -307,7 +376,8 @@ public class SmsMessage {
if (PHONE_TYPE_CDMA == activePhone) {
spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
- destinationAddress, message, statusReportRequested, header);
+ destinationAddress, message, statusReportRequested,
+ SmsHeader.fromByteArray(header));
} else {
spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, message, statusReportRequested, header);
@@ -331,7 +401,7 @@ public class SmsMessage {
if (PHONE_TYPE_CDMA == activePhone) {
spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
- destinationAddress, message, statusReportRequested);
+ destinationAddress, message, statusReportRequested, null);
} else {
spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, message, statusReportRequested);
@@ -515,9 +585,14 @@ public class SmsMessage {
return mWrappedSmsMessage.getUserData();
}
- /* Not part of the SDK interface and only needed by specific classes:
- protected SmsHeader getUserDataHeader()
- */
+ /**
+ * Return the user data header (UDH).
+ *
+ * @hide
+ */
+ public SmsHeader getUserDataHeader() {
+ return mWrappedSmsMessage.getUserDataHeader();
+ }
/**
* Returns the raw PDU for the message.
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 559542a..c9dcd8b 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -16,26 +16,24 @@
package android.telephony;
-import com.android.internal.telephony.*;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
-import android.telephony.CellLocation;
import com.android.internal.telephony.IPhoneSubInfo;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.ITelephonyRegistry;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.TelephonyProperties;
+import java.util.List;
+
/**
* Provides access to information about the telephony services on
* the device. Applications can use the methods in this class to
@@ -192,8 +190,9 @@ public class TelephonyManager {
/**
* Returns the current location of the device.
*
- * <p>Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
- * ACCESS_COARSE_LOCATION}.
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION}.
*/
public CellLocation getCellLocation() {
try {
@@ -238,10 +237,10 @@ public class TelephonyManager {
/**
* Returns the neighboring cell information of the device.
- *
+ *
* @return List of NeighboringCellInfo or null if info unavailable.
- *
- * <p>Requires Permission:
+ *
+ * <p>Requires Permission:
* (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
*/
public List<NeighboringCellInfo> getNeighboringCellInfo() {
@@ -250,24 +249,25 @@ public class TelephonyManager {
} catch (RemoteException ex) {
}
return null;
-
+
}
-
+
/**
* No phone module
+ *
*/
public static final int PHONE_TYPE_NONE = 0;
/**
* GSM phone
*/
- public static final int PHONE_TYPE_GSM = 1;
+ public static final int PHONE_TYPE_GSM = RILConstants.GSM_PHONE;
/**
* CDMA phone
* @hide
*/
- public static final int PHONE_TYPE_CDMA = 2;
+ public static final int PHONE_TYPE_CDMA = RILConstants.CDMA_PHONE;
/**
* Returns a constant indicating the device phone type.
@@ -278,16 +278,41 @@ public class TelephonyManager {
*/
public int getPhoneType() {
try{
- if(getITelephony().getActivePhoneType() == RILConstants.CDMA_PHONE) {
- return PHONE_TYPE_CDMA;
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ if(telephony.getActivePhoneType() == RILConstants.CDMA_PHONE) {
+ return PHONE_TYPE_CDMA;
+ } else {
+ return PHONE_TYPE_GSM;
+ }
} else {
- return PHONE_TYPE_GSM;
+ // This can happen when the ITelephony interface is not up yet.
+ return getPhoneTypeFromProperty();
}
- }catch(RemoteException ex){
- return PHONE_TYPE_NONE;
+ } catch(RemoteException ex){
+ // This shouldn't happen in the normal case, as a backup we
+ // read from the system property.
+ return getPhoneTypeFromProperty();
}
}
+
+ private int getPhoneTypeFromProperty() {
+ int type =
+ SystemProperties.getInt(TelephonyProperties.CURRENT_ACTIVE_PHONE,
+ getPhoneTypeFromNetworkType());
+ return type;
+ }
+
+ private int getPhoneTypeFromNetworkType() {
+ // When the system property CURRENT_ACTIVE_PHONE, has not been set,
+ // use the system property for default network type.
+ // This is a fail safe, and can only happen at first boot.
+ int mode = SystemProperties.getInt("ro.telephony.default_network", -1);
+ if (mode == -1)
+ return PHONE_TYPE_NONE;
+ return PhoneFactory.getPhoneType(mode);
+ }
//
//
// Current Network
@@ -587,6 +612,21 @@ public class TelephonyManager {
}
/**
+ * Returns the voice mail count.
+ * <p>
+ * Requires Permission:
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * @hide
+ */
+ public int getVoiceMessageCount() {
+ try {
+ return getITelephony().getVoiceMessageCount();
+ } catch (RemoteException ex) {
+ }
+ return 0;
+ }
+
+ /**
* Retrieves the alphabetic identifier associated with the voice
* mail number.
* <p>
@@ -627,7 +667,10 @@ public class TelephonyManager {
} catch (RemoteException ex) {
// the phone process is restarting.
return CALL_STATE_IDLE;
- }
+ } catch (NullPointerException ex) {
+ // the phone process is restarting.
+ return CALL_STATE_IDLE;
+ }
}
/** Data connection activity: No traffic. */
@@ -639,6 +682,11 @@ public class TelephonyManager {
/** Data connection activity: Currently both sending and receiving
* IP PPP traffic. */
public static final int DATA_ACTIVITY_INOUT = DATA_ACTIVITY_IN | DATA_ACTIVITY_OUT;
+ /**
+ * Data connection is active, but physical link is down
+ * @hide
+ */
+ public static final int DATA_ACTIVITY_DORMANT = 0x00000004;
/**
* Returns a constant indicating the type of activity on a data connection
@@ -648,6 +696,7 @@ public class TelephonyManager {
* @see #DATA_ACTIVITY_IN
* @see #DATA_ACTIVITY_OUT
* @see #DATA_ACTIVITY_INOUT
+ * @see #DATA_ACTIVITY_DORMANT
*/
public int getDataActivity() {
try {
@@ -655,7 +704,10 @@ public class TelephonyManager {
} catch (RemoteException ex) {
// the phone process is restarting.
return DATA_ACTIVITY_NONE;
- }
+ } catch (NullPointerException ex) {
+ // the phone process is restarting.
+ return DATA_ACTIVITY_NONE;
+ }
}
/** Data connection state: Disconnected. IP traffic not available. */
@@ -729,4 +781,48 @@ public class TelephonyManager {
// system process dead
}
}
+
+ /**
+ * Returns the CDMA ERI icon index to display
+ *
+ * @hide
+ */
+ public int getCdmaEriIconIndex() {
+ try {
+ return getITelephony().getCdmaEriIconIndex();
+ } catch (RemoteException ex) {
+ // the phone process is restarting.
+ return -1;
+ }
+ }
+
+ /**
+ * Returns the CDMA ERI icon mode,
+ * 0 - ON
+ * 1 - FLASHING
+ *
+ * @hide
+ */
+ public int getCdmaEriIconMode() {
+ try {
+ return getITelephony().getCdmaEriIconMode();
+ } catch (RemoteException ex) {
+ // the phone process is restarting.
+ return -1;
+ }
+ }
+
+ /**
+ * Returns the CDMA ERI text,
+ *
+ * @hide
+ */
+ public String getCdmaEriText() {
+ try {
+ return getITelephony().getCdmaEriText();
+ } catch (RemoteException ex) {
+ // the phone process is restarting.
+ return null;
+ }
+ }
}
diff --git a/telephony/java/android/telephony/gsm/SmsMessage.java b/telephony/java/android/telephony/gsm/SmsMessage.java
index 0928ddf..84dfca0 100644
--- a/telephony/java/android/telephony/gsm/SmsMessage.java
+++ b/telephony/java/android/telephony/gsm/SmsMessage.java
@@ -21,6 +21,7 @@ import android.telephony.TelephonyManager;
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;
@@ -369,7 +370,8 @@ public class SmsMessage {
if (PHONE_TYPE_CDMA == activePhone) {
spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
- destinationAddress, message, statusReportRequested, header);
+ destinationAddress, message, statusReportRequested,
+ SmsHeader.fromByteArray(header));
} else {
spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, message, statusReportRequested, header);
@@ -395,7 +397,7 @@ public class SmsMessage {
if (PHONE_TYPE_CDMA == activePhone) {
spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
- destinationAddress, message, statusReportRequested);
+ destinationAddress, message, statusReportRequested, null);
} else {
spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, message, statusReportRequested);
@@ -744,4 +746,3 @@ public class SmsMessage {
}
}
}
-
diff --git a/telephony/java/android/telephony/package.html b/telephony/java/android/telephony/package.html
index aee4a6f..cb2fb49 100644
--- a/telephony/java/android/telephony/package.html
+++ b/telephony/java/android/telephony/package.html
@@ -1,6 +1,6 @@
<HTML>
<BODY>
-Provides APIs for monitoring the basic phone information, such as
+Provides APIs for monitoring the basic phone information, such as
the network type and connection state, plus utilities
for manipulating phone number strings.
</BODY>
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index fbc596c..3edca66 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -55,33 +55,39 @@ public abstract class BaseCommands implements CommandsInterface {
protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
protected Registrant mUnsolOemHookRawRegistrant;
+ protected RegistrantList mOtaProvisionRegistrants = new RegistrantList();
+ protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList();
+ protected RegistrantList mDisplayInfoRegistrants = new RegistrantList();
+ protected RegistrantList mSignalInfoRegistrants = new RegistrantList();
+ protected RegistrantList mNumberInfoRegistrants = new RegistrantList();
+ protected RegistrantList mRedirNumInfoRegistrants = new RegistrantList();
+ protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
+ protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
+ protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
+
protected Registrant mSMSRegistrant;
protected Registrant mNITZTimeRegistrant;
protected Registrant mSignalStrengthRegistrant;
protected Registrant mUSSDRegistrant;
protected Registrant mSmsOnSimRegistrant;
- /** Registrant for handling SMS Status Reports */
protected Registrant mSmsStatusRegistrant;
- /** Registrant for handling Supplementary Service Notifications */
protected Registrant mSsnRegistrant;
protected Registrant mStkSessionEndRegistrant;
protected Registrant mStkProCmdRegistrant;
protected Registrant mStkEventRegistrant;
protected Registrant mStkCallSetUpRegistrant;
- /** Registrant for handling SIM/RUIM SMS storage full messages */
protected Registrant mIccSmsFullRegistrant;
- /** Registrant for handling Icc Refresh notifications */
+ protected Registrant mEmergencyCallbackModeRegistrant;
protected Registrant mIccRefreshRegistrant;
- /** Registrant for handling RING notifications */
protected Registrant mRingRegistrant;
- /** Registrant for handling RESTRICTED STATE changed notification */
protected Registrant mRestrictedStateRegistrant;
+ protected Registrant mGsmBroadcastSmsRegistrant;
- //Network Mode received from PhoneFactory
+ // Network Mode received from PhoneFactory
protected int mNetworkMode;
- //CDMA subscription received from PhoneFactory
+ // CDMA subscription received from PhoneFactory
protected int mCdmaSubscription;
- //Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
+ // Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
protected int mPhoneType;
@@ -332,6 +338,14 @@ public abstract class BaseCommands implements CommandsInterface {
mSMSRegistrant.clear();
}
+ public void setOnNewGsmBroadcastSms(Handler h, int what, Object obj) {
+ mGsmBroadcastSmsRegistrant = new Registrant (h, what, obj);
+ }
+
+ public void unSetOnNewGsmBroadcastSms(Handler h) {
+ mGsmBroadcastSmsRegistrant.clear();
+ }
+
public void setOnSmsOnSim(Handler h, int what, Object obj) {
mSmsOnSimRegistrant = new Registrant (h, what, obj);
}
@@ -424,6 +438,10 @@ public abstract class BaseCommands implements CommandsInterface {
mIccRefreshRegistrant = new Registrant (h, what, obj);
}
+ public void setEmergencyCallbackMode(Handler h, int what, Object obj) {
+ mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj);
+ }
+
public void unSetOnIccRefresh(Handler h) {
mIccRefreshRegistrant.clear();
}
@@ -462,6 +480,29 @@ public abstract class BaseCommands implements CommandsInterface {
mRestrictedStateRegistrant.clear();
}
+ public void registerForDisplayInfo(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mDisplayInfoRegistrants.add(r);
+ }
+
+ public void unregisterForDisplayInfo(Handler h) {
+ mDisplayInfoRegistrants.remove(h);
+ }
+
+ public void registerForCallWaitingInfo(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mCallWaitingInfoRegistrants.add(r);
+ }
+
+ public void unregisterForCallWaitingInfo(Handler h) {
+ mCallWaitingInfoRegistrants.remove(h);
+ }
+
+ public void registerForSignalInfo(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mSignalInfoRegistrants.add(r);
+ }
+
public void setOnUnsolOemHookRaw(Handler h, int what, Object obj) {
mUnsolOemHookRawRegistrant = new Registrant (h, what, obj);
}
@@ -470,6 +511,64 @@ public abstract class BaseCommands implements CommandsInterface {
mUnsolOemHookRawRegistrant.clear();
}
+ public void unregisterForSignalInfo(Handler h) {
+ mSignalInfoRegistrants.remove(h);
+ }
+
+ public void registerForCdmaOtaProvision(Handler h,int what, Object obj){
+ Registrant r = new Registrant (h, what, obj);
+ mOtaProvisionRegistrants.add(r);
+ }
+
+ public void unregisterForCdmaOtaProvision(Handler h){
+ mOtaProvisionRegistrants.remove(h);
+ }
+
+ public void registerForNumberInfo(Handler h,int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mNumberInfoRegistrants.add(r);
+ }
+
+ public void unregisterForNumberInfo(Handler h){
+ mNumberInfoRegistrants.remove(h);
+ }
+
+ public void registerForRedirectedNumberInfo(Handler h,int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mRedirNumInfoRegistrants.add(r);
+ }
+
+ public void unregisterForRedirectedNumberInfo(Handler h) {
+ mRedirNumInfoRegistrants.remove(h);
+ }
+
+ public void registerForLineControlInfo(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mLineControlInfoRegistrants.add(r);
+ }
+
+ public void unregisterForLineControlInfo(Handler h) {
+ mLineControlInfoRegistrants.remove(h);
+ }
+
+ public void registerFoT53ClirlInfo(Handler h,int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mT53ClirInfoRegistrants.add(r);
+ }
+
+ public void unregisterForT53ClirInfo(Handler h) {
+ mT53ClirInfoRegistrants.remove(h);
+ }
+
+ public void registerForT53AudioControlInfo(Handler h,int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mT53AudCntrlInfoRegistrants.add(r);
+ }
+
+ public void unregisterForT53AudioControlInfo(Handler h) {
+ mT53AudCntrlInfoRegistrants.remove(h);
+ }
+
//***** Protected Methods
/**
* Store new RadioState and send notification based on the changes
diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java
index 70471b6..7eb9d85 100644
--- a/telephony/java/com/android/internal/telephony/Call.java
+++ b/telephony/java/com/android/internal/telephony/Call.java
@@ -46,6 +46,13 @@ public abstract class Call {
public State state = State.IDLE;
+ // Flag to indicate if the current calling/caller information
+ // is accurate. If false the information is known to be accurate.
+ //
+ // For CDMA, during call waiting/3 way, there is no network response
+ // if call waiting is answered, network timed out, dropped, 3 way
+ // merged, etc.
+ protected boolean isGeneric = false;
/* Instance Methods */
@@ -126,6 +133,7 @@ public abstract class Call {
if (t < time) {
earliest = c;
+ time = t;
}
}
@@ -157,10 +165,8 @@ public abstract class Call {
public long
getEarliestConnectTime() {
- List l;
long time = Long.MAX_VALUE;
-
- l = getConnections();
+ List l = getConnections();
if (l.size() == 0) {
return 0;
@@ -189,4 +195,44 @@ public abstract class Call {
return getState().isRinging();
}
+ /**
+ * Returns the Connection associated with this Call that was created
+ * last, or null if there are no Connections in this Call
+ */
+ public Connection
+ getLatestConnection() {
+ List l = getConnections();
+ if (l.size() == 0) {
+ return null;
+ }
+
+ long time = 0;
+ Connection latest = null;
+ for (int i = 0, s = l.size() ; i < s ; i++) {
+ Connection c = (Connection) l.get(i);
+ long t = c.getCreateTime();
+
+ if (t > time) {
+ latest = c;
+ time = t;
+ }
+ }
+
+ return latest;
+ }
+
+ /**
+ * To indicate if the connection information is accurate
+ * or not. false means accurate. Only used for CDMA.
+ */
+ public boolean isGeneric() {
+ return isGeneric;
+ }
+
+ /**
+ * Set the generic instance variable
+ */
+ public void setGeneric(boolean generic) {
+ isGeneric = generic;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java
index eb339f8..9619a66 100644
--- a/telephony/java/com/android/internal/telephony/CallTracker.java
+++ b/telephony/java/com/android/internal/telephony/CallTracker.java
@@ -44,19 +44,21 @@ public abstract class CallTracker extends Handler {
//***** Events
- protected static final int EVENT_POLL_CALLS_RESULT = 1;
- protected static final int EVENT_CALL_STATE_CHANGE = 2;
- protected static final int EVENT_REPOLL_AFTER_DELAY = 3;
- protected static final int EVENT_OPERATION_COMPLETE = 4;
- protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5;
-
- protected static final int EVENT_SWITCH_RESULT = 8;
- protected static final int EVENT_RADIO_AVAILABLE = 9;
- protected static final int EVENT_RADIO_NOT_AVAILABLE = 10;
- protected static final int EVENT_CONFERENCE_RESULT = 11;
- protected static final int EVENT_SEPARATE_RESULT = 12;
- protected static final int EVENT_ECT_RESULT = 13;
-
+ protected static final int EVENT_POLL_CALLS_RESULT = 1;
+ protected static final int EVENT_CALL_STATE_CHANGE = 2;
+ protected static final int EVENT_REPOLL_AFTER_DELAY = 3;
+ protected static final int EVENT_OPERATION_COMPLETE = 4;
+ protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5;
+
+ protected static final int EVENT_SWITCH_RESULT = 8;
+ protected static final int EVENT_RADIO_AVAILABLE = 9;
+ protected static final int EVENT_RADIO_NOT_AVAILABLE = 10;
+ protected static final int EVENT_CONFERENCE_RESULT = 11;
+ protected static final int EVENT_SEPARATE_RESULT = 12;
+ protected static final int EVENT_ECT_RESULT = 13;
+ protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA = 14;
+ protected static final int EVENT_CALL_WAITING_INFO_CDMA = 15;
+ protected static final int EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA = 16;
protected void pollCallsWhenSafe() {
needsPoll = true;
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index da53e15..afc8b62 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -70,17 +70,23 @@ public class CallerInfo {
*/
public String name;
public String phoneNumber;
+
+ public String cnapName;
+ public int numberPresentation;
+ public int namePresentation;
+ public boolean contactExists;
+
public String phoneLabel;
/* Split up the phoneLabel into number type and label name */
public int numberType;
public String numberLabel;
-
+
public int photoResource;
public long person_id;
public boolean needUpdate;
public Uri contactRefUri;
-
- // fields to hold individual contact preference data,
+
+ // fields to hold individual contact preference data,
// including the send to voicemail flag and the ringtone
// uri reference.
public Uri contactRingtoneUri;
@@ -110,7 +116,7 @@ public class CallerInfo {
* number. The returned CallerInfo is null if no number is supplied.
*/
public static CallerInfo getCallerInfo(Context context, Uri contactRef, Cursor cursor) {
-
+
CallerInfo info = new CallerInfo();
info.photoResource = 0;
info.phoneLabel = null;
@@ -118,9 +124,10 @@ public class CallerInfo {
info.numberLabel = null;
info.cachedPhoto = null;
info.isCachedPhotoCurrent = false;
-
+ info.contactExists = false;
+
if (Config.LOGV) Log.v(TAG, "construct callerInfo from cursor");
-
+
if (cursor != null) {
if (cursor.moveToFirst()) {
@@ -137,7 +144,7 @@ public class CallerInfo {
if (columnIndex != -1) {
info.phoneNumber = cursor.getString(columnIndex);
}
-
+
// Look for the label/type combo
columnIndex = cursor.getColumnIndex(Phones.LABEL);
if (columnIndex != -1) {
@@ -161,7 +168,7 @@ public class CallerInfo {
info.person_id = cursor.getLong(columnIndex);
}
}
-
+
// look for the custom ringtone, create from the string stored
// in the database.
columnIndex = cursor.getColumnIndex(People.CUSTOM_RINGTONE);
@@ -174,8 +181,9 @@ public class CallerInfo {
// look for the send to voicemail flag, set it to true only
// under certain circumstances.
columnIndex = cursor.getColumnIndex(People.SEND_TO_VOICEMAIL);
- info.shouldSendToVoicemail = (columnIndex != -1) &&
+ info.shouldSendToVoicemail = (columnIndex != -1) &&
((cursor.getInt(columnIndex)) == 1);
+ info.contactExists = true;
}
cursor.close();
}
@@ -186,7 +194,7 @@ public class CallerInfo {
return info;
}
-
+
/**
* getCallerInfo given a URI, look up in the call-log database
* for the uri unique key.
@@ -196,11 +204,11 @@ public class CallerInfo {
* number. The returned CallerInfo is null if no number is supplied.
*/
public static CallerInfo getCallerInfo(Context context, Uri contactRef) {
-
- return getCallerInfo(context, contactRef,
+
+ return getCallerInfo(context, contactRef,
context.getContentResolver().query(contactRef, null, null, null, null));
}
-
+
/**
* getCallerInfo given a phone number, look up in the call-log database
* for the matching caller id info.
@@ -216,13 +224,13 @@ public class CallerInfo {
return null;
} else {
// Change the callerInfo number ONLY if it is an emergency number
- // or if it is the voicemail number. If it is either, take a
+ // or if it is the voicemail number. If it is either, take a
// shortcut and skip the query.
if (PhoneNumberUtils.isEmergencyNumber(number)) {
CallerInfo ci = new CallerInfo();
// Note we're setting the phone number here (refer to javadoc
- // comments at the top of CallerInfo class).
+ // comments at the top of CallerInfo class).
ci.phoneNumber = context.getString(
com.android.internal.R.string.emergency_call_dialog_number_for_display);
return ci;
@@ -233,14 +241,14 @@ public class CallerInfo {
CallerInfo ci = new CallerInfo();
// Note we're setting the phone number here (refer to javadoc
- // comments at the top of CallerInfo class).
+ // comments at the top of CallerInfo class).
ci.phoneNumber = TelephonyManager.getDefault().getVoiceMailAlphaTag();
// TODO: FIND ANOTHER ICON
//info.photoResource = android.R.drawable.badge_voicemail;
return ci;
}
} catch (SecurityException ex) {
- // Don't crash if this process doesn't have permission to
+ // Don't crash if this process doesn't have permission to
// retrieve VM number. It's still allowed to look up caller info.
// But don't try it again.
sSkipVmCheck = true;
@@ -249,16 +257,16 @@ public class CallerInfo {
}
Uri contactUri = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL,
- Uri.encode(number));
-
+ Uri.encode(number));
+
CallerInfo info = getCallerInfo(context, contactUri);
- // if no query results were returned with a viable number,
- // fill in the original number value we used to query with.
+ // if no query results were returned with a viable number,
+ // fill in the original number value we used to query with.
if (TextUtils.isEmpty(info.phoneNumber)) {
info.phoneNumber = number;
}
-
+
return info;
}
@@ -270,9 +278,9 @@ public class CallerInfo {
* @param number a phone number.
* @return if the number belongs to a contact, the contact's name is
* returned; otherwise, the number itself is returned.
- *
- * TODO NOTE: This MAY need to refer to the Asynchronous Query API
- * [startQuery()], instead of getCallerInfo, but since it looks like
+ *
+ * TODO NOTE: This MAY need to refer to the Asynchronous Query API
+ * [startQuery()], instead of getCallerInfo, but since it looks like
* it is only being used by the provider calls in the messaging app:
* 1. android.provider.Telephony.Mms.getDisplayAddress()
* 2. android.provider.Telephony.Sms.getDisplayAddress()
@@ -302,5 +310,4 @@ public class CallerInfo {
return null;
}
}
-}
-
+}
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index 04da9f7..f81f42a 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -35,10 +35,10 @@ import android.util.Log;
*/
public class CallerInfoAsyncQuery {
-
+
private static final boolean DBG = false;
private static final String LOG_TAG = "PHONE";
-
+
private static final int EVENT_NEW_QUERY = 1;
private static final int EVENT_ADD_LISTENER = 2;
private static final int EVENT_END_OF_QUEUE = 3;
@@ -55,24 +55,24 @@ public class CallerInfoAsyncQuery {
*/
public interface OnQueryCompleteListener {
/**
- * Called when the query is complete.
- */
+ * Called when the query is complete.
+ */
public void onQueryComplete(int token, Object cookie, CallerInfo ci);
}
-
-
+
+
/**
* Wrap the cookie from the WorkerArgs with additional information needed by our
- * classes.
+ * classes.
*/
private static final class CookieWrapper {
public OnQueryCompleteListener listener;
public Object cookie;
public int event;
public String number;
- }
-
-
+ }
+
+
/**
* Simple exception used to communicate problems with the query pool.
*/
@@ -81,12 +81,12 @@ public class CallerInfoAsyncQuery {
super(error);
}
}
-
+
/**
* Our own implementation of the AsyncQueryHandler.
*/
private class CallerInfoAsyncQueryHandler extends AsyncQueryHandler {
-
+
/**
* The information relevant to each CallerInfo query. Each query may have multiple
* listeners, so each AsyncCursorInfo is associated with 2 or more CookieWrapper
@@ -96,20 +96,20 @@ public class CallerInfoAsyncQuery {
private Context mQueryContext;
private Uri mQueryUri;
private CallerInfo mCallerInfo;
-
+
/**
* Our own query worker thread.
- *
+ *
* This thread handles the messages enqueued in the looper. The normal sequence
* of events is that a new query shows up in the looper queue, followed by 0 or
* more add listener requests, and then an end request. Of course, these requests
* can be interlaced with requests from other tokens, but is irrelevant to this
* handler since the handler has no state.
- *
+ *
* Note that we depend on the queue to keep things in order; in other words, the
- * looper queue must be FIFO with respect to input from the synchronous startQuery
+ * looper queue must be FIFO with respect to input from the synchronous startQuery
* calls and output to this handleMessage call.
- *
+ *
* This use of the queue is required because CallerInfo objects may be accessed
* multiple times before the query is complete. All accesses (listeners) must be
* queued up and informed in order when the query is complete.
@@ -123,22 +123,22 @@ public class CallerInfoAsyncQuery {
public void handleMessage(Message msg) {
WorkerArgs args = (WorkerArgs) msg.obj;
CookieWrapper cw = (CookieWrapper) args.cookie;
-
+
if (cw == null) {
// Normally, this should never be the case for calls originating
// from within this code.
- // However, if there is any code that this Handler calls (such as in
+ // However, if there is any code that this Handler calls (such as in
// super.handleMessage) that DOES place unexpected messages on the
// queue, then we need pass these messages on.
- if (DBG) log("Unexpected command (CookieWrapper is null): " + msg.what +
+ if (DBG) log("Unexpected command (CookieWrapper is null): " + msg.what +
" ignored by CallerInfoWorkerHandler, passing onto parent.");
-
+
super.handleMessage(msg);
} else {
-
- if (DBG) log("Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
+
+ if (DBG) log("Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
" command: " + msg.what + " query URI: " + args.uri);
-
+
switch (cw.event) {
case EVENT_NEW_QUERY:
//start the sql command.
@@ -148,7 +148,7 @@ public class CallerInfoAsyncQuery {
// shortcuts to avoid query for recognized numbers.
case EVENT_EMERGENCY_NUMBER:
case EVENT_VOICEMAIL_NUMBER:
-
+
case EVENT_ADD_LISTENER:
case EVENT_END_OF_QUEUE:
// query was already completed, so just send the reply.
@@ -157,17 +157,17 @@ public class CallerInfoAsyncQuery {
Message reply = args.handler.obtainMessage(msg.what);
reply.obj = args;
reply.arg1 = msg.arg1;
-
+
reply.sendToTarget();
-
+
break;
default:
}
}
}
}
-
-
+
+
/**
* Asynchronous query handler class for the contact / callerinfo object.
*/
@@ -182,29 +182,29 @@ public class CallerInfoAsyncQuery {
/**
* Overrides onQueryComplete from AsyncQueryHandler.
- *
+ *
* This method takes into account the state of this class; we construct the CallerInfo
* object only once for each set of listeners. When the query thread has done its work
- * and calls this method, we inform the remaining listeners in the queue, until we're
- * out of listeners. Once we get the message indicating that we should expect no new
- * listeners for this CallerInfo object, we release the AsyncCursorInfo back into the
+ * and calls this method, we inform the remaining listeners in the queue, until we're
+ * out of listeners. Once we get the message indicating that we should expect no new
+ * listeners for this CallerInfo object, we release the AsyncCursorInfo back into the
* pool.
*/
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
if (DBG) log("query complete for token: " + token);
-
+
//get the cookie and notify the listener.
CookieWrapper cw = (CookieWrapper) cookie;
if (cw == null) {
// Normally, this should never be the case for calls originating
// from within this code.
- // However, if there is any code that calls this method, we should
+ // However, if there is any code that calls this method, we should
// check the parameters to make sure they're viable.
if (DBG) log("Cookie is null, ignoring onQueryComplete() request.");
return;
}
-
+
if (cw.event == EVENT_END_OF_QUEUE) {
release();
return;
@@ -216,16 +216,16 @@ public class CallerInfoAsyncQuery {
throw new QueryPoolException
("Bad context or query uri, or CallerInfoAsyncQuery already released.");
}
-
+
// adjust the callerInfo data as needed, and only if it was set from the
// initial query request.
// Change the callerInfo number ONLY if it is an emergency number or the
- // voicemail number, and adjust other data (including photoResource)
+ // voicemail number, and adjust other data (including photoResource)
// accordingly.
if (cw.event == EVENT_EMERGENCY_NUMBER) {
mCallerInfo = new CallerInfo();
// Note we're setting the phone number here (refer to javadoc
- // comments at the top of CallerInfo class).
+ // comments at the top of CallerInfo class).
mCallerInfo.phoneNumber = mQueryContext.getString(com.android.internal
.R.string.emergency_call_dialog_number_for_display);
mCallerInfo.photoResource = com.android.internal.R.drawable.picture_emergency;
@@ -234,8 +234,8 @@ public class CallerInfoAsyncQuery {
mCallerInfo = new CallerInfo();
try {
// Note we're setting the phone number here (refer to javadoc
- // comments at the top of CallerInfo class).
- mCallerInfo.phoneNumber =
+ // comments at the top of CallerInfo class).
+ mCallerInfo.phoneNumber =
TelephonyManager.getDefault().getVoiceMailAlphaTag();
} catch (SecurityException ex) {
// Should never happen: if this process does not have
@@ -243,80 +243,80 @@ public class CallerInfoAsyncQuery {
// permission to retrieve VM number and would not generate
// an EVENT_VOICEMAIL_NUMBER. But if it happens, don't crash.
}
- } else {
+ } else {
mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor);
// Use the number entered by the user for display.
if (!TextUtils.isEmpty(cw.number)) {
mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number);
}
}
-
+
if (DBG) log("constructing CallerInfo object for token: " + token);
-
+
//notify that we can clean up the queue after this.
CookieWrapper endMarker = new CookieWrapper();
endMarker.event = EVENT_END_OF_QUEUE;
startQuery (token, endMarker, null, null, null, null, null);
}
-
+
//notify the listener that the query is complete.
if (cw.listener != null) {
- if (DBG) log("notifying listener: " + cw.listener.getClass().toString() +
+ if (DBG) log("notifying listener: " + cw.listener.getClass().toString() +
" for token: " + token);
cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo);
}
}
}
-
+
/**
* Private constructor for factory methods.
*/
private CallerInfoAsyncQuery() {
}
-
+
/**
* Factory method to start query with a Uri query spec
*/
- public static CallerInfoAsyncQuery startQuery(int token, Context context, Uri contactRef,
+ public static CallerInfoAsyncQuery startQuery(int token, Context context, Uri contactRef,
OnQueryCompleteListener listener, Object cookie) {
-
+
CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
c.allocate(context, contactRef);
if (DBG) log("starting query for URI: " + contactRef + " handler: " + c.toString());
-
+
//create cookieWrapper, start query
CookieWrapper cw = new CookieWrapper();
cw.listener = listener;
cw.cookie = cookie;
cw.event = EVENT_NEW_QUERY;
-
+
c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
-
+
return c;
}
-
+
/**
* Factory method to start query with a number
*/
- public static CallerInfoAsyncQuery startQuery(int token, Context context, String number,
+ public static CallerInfoAsyncQuery startQuery(int token, Context context, String number,
OnQueryCompleteListener listener, Object cookie) {
//contruct the URI object and start Query.
Uri contactRef = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, number);
-
+
CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
c.allocate(context, contactRef);
if (DBG) log("starting query for number: " + number + " handler: " + c.toString());
-
+
//create cookieWrapper, start query
CookieWrapper cw = new CookieWrapper();
cw.listener = listener;
cw.cookie = cookie;
cw.number = number;
- // check to see if these are recognized numbers, and use shortcuts if we can.
+ // check to see if these are recognized numbers, and use shortcuts if we can.
if (PhoneNumberUtils.isEmergencyNumber(number)) {
cw.event = EVENT_EMERGENCY_NUMBER;
} else {
@@ -325,13 +325,13 @@ public class CallerInfoAsyncQuery {
try {
vmNumber = TelephonyManager.getDefault().getVoiceMailNumber();
} catch (SecurityException ex) {
- // Don't crash if this process doesn't have permission to
+ // Don't crash if this process doesn't have permission to
// retrieve VM number. It's still allowed to look up caller info.
// But don't try it again.
sSkipVmCheck = true;
}
}
- if (PhoneNumberUtils.compare(number, vmNumber)) {
+ if (PhoneNumberUtils.compare(number, vmNumber)) {
cw.event = EVENT_VOICEMAIL_NUMBER;
} else {
cw.event = EVENT_NEW_QUERY;
@@ -339,24 +339,24 @@ public class CallerInfoAsyncQuery {
}
c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
-
+
return c;
}
-
+
/**
* Method to add listeners to a currently running query
*/
public void addQueryListener(int token, OnQueryCompleteListener listener, Object cookie) {
- if (DBG) log("adding listener to query: " + mHandler.mQueryUri + " handler: " +
+ if (DBG) log("adding listener to query: " + mHandler.mQueryUri + " handler: " +
mHandler.toString());
-
+
//create cookieWrapper, add query request to end of queue.
CookieWrapper cw = new CookieWrapper();
cw.listener = listener;
cw.cookie = cookie;
cw.event = EVENT_ADD_LISTENER;
-
+
mHandler.startQuery (token, cw, null, null, null, null, null);
}
@@ -382,12 +382,12 @@ public class CallerInfoAsyncQuery {
mHandler.mCallerInfo = null;
mHandler = null;
}
-
+
/**
* static logging method
*/
private static void log(String msg) {
Log.d(LOG_TAG, msg);
- }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 5a1bb7e..25c512e 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
+
import android.os.Message;
import android.os.Handler;
@@ -147,6 +149,14 @@ public interface CommandsInterface {
static final int SIM_REFRESH_INIT = 1; // SIM initialized; reload all
static final int SIM_REFRESH_RESET = 2; // SIM reset; may be locked
+ // GSM SMS fail cause for acknowledgeLastIncomingSMS. From TS 23.040, 9.2.3.22.
+ static final int GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED = 0xD3;
+ static final int GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR = 0xFF;
+
+ // CDMA SMS fail cause for acknowledgeLastIncomingCdmaSms. From TS N.S00005, 6.5.2.125.
+ static final int CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE = 35;
+ static final int CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM = 39;
+
//***** Methods
RadioState getRadioState();
@@ -348,12 +358,12 @@ public interface CommandsInterface {
void unSetOnCallRing(Handler h);
/**
- * Sets the handler for RESTRICTED_STATE changed notification,
+ * Sets the handler for RESTRICTED_STATE changed notification,
* eg, for Domain Specific Access Control
* unlike the register* methods, there's only one signal strength handler
- *
- * AsyncResult.result is an int[1]
- * response.obj.result[0] is a bitmask of RIL_RESTRICTED_STATE_* values
+ *
+ * AsyncResult.result is an int[1]
+ * response.obj.result[0] is a bitmask of RIL_RESTRICTED_STATE_* values
*/
void setOnRestrictedStateChanged(Handler h, int what, Object obj);
@@ -424,6 +434,104 @@ public interface CommandsInterface {
void setSuppServiceNotifications(boolean enable, Message result);
//void unSetSuppServiceNotifications(Handler h);
+ /**
+ * Sets the handler for Event Notifications for CDMA Display Info.
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForDisplayInfo(Handler h, int what, Object obj);
+ void unregisterForDisplayInfo(Handler h);
+
+ /**
+ * Sets the handler for Event Notifications for CallWaiting Info.
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForCallWaitingInfo(Handler h, int what, Object obj);
+ void unregisterForCallWaitingInfo(Handler h);
+
+ /**
+ * Sets the handler for Event Notifications for Signal Info.
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForSignalInfo(Handler h, int what, Object obj);
+ void unregisterForSignalInfo(Handler h);
+
+ /**
+ * Registers the handler for CDMA number information record
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForNumberInfo(Handler h, int what, Object obj);
+ void unregisterForNumberInfo(Handler h);
+
+ /**
+ * Registers the handler for CDMA redirected number Information record
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForRedirectedNumberInfo(Handler h, int what, Object obj);
+ void unregisterForRedirectedNumberInfo(Handler h);
+
+ /**
+ * Registers the handler for CDMA line control information record
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForLineControlInfo(Handler h, int what, Object obj);
+ void unregisterForLineControlInfo(Handler h);
+
+ /**
+ * Registers the handler for CDMA T53 CLIR information record
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerFoT53ClirlInfo(Handler h, int what, Object obj);
+ void unregisterForT53ClirInfo(Handler h);
+
+ /**
+ * Registers the handler for CDMA T53 audio control information record
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForT53AudioControlInfo(Handler h, int what, Object obj);
+ void unregisterForT53AudioControlInfo(Handler h);
+
+ /**
+ * Fires on if Modem enters Emergency Callback mode
+ */
+ void setEmergencyCallbackMode(Handler h, int what, Object obj);
+
+ /**
+ * Fires on any CDMA OTA provision status change
+ */
+ void registerForCdmaOtaProvision(Handler h,int what, Object obj);
+ void unregisterForCdmaOtaProvision(Handler h);
/**
* Returns current ICC status.
@@ -516,7 +624,7 @@ public interface CommandsInterface {
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
- * ar.result contains a List of PDPContextState
+ * ar.result contains a List of DataCallState
* @deprecated
*/
void getPDPContextList(Message result);
@@ -526,7 +634,7 @@ public interface CommandsInterface {
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
- * ar.result contains a List of PDPContextState
+ * ar.result contains a List of DataCallState
*/
void getDataCallList(Message result);
@@ -767,6 +875,12 @@ public interface CommandsInterface {
*/
void stopDtmf(Message result);
+ /**
+ * ar.exception carries exception on failure
+ * ar.userObject contains the orignal value of result.obj
+ * ar.result is null on success and failure
+ */
+ void sendBurstDtmf(String dtmfString, Message result);
/**
* smscPDU is smsc address in PDU form GSM BCD format prefixed
@@ -833,9 +947,9 @@ public interface CommandsInterface {
void setRadioPower(boolean on, Message response);
- void acknowledgeLastIncomingSMS(boolean success, Message response);
+ void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message response);
- void acknowledgeLastIncomingCdmaSms(boolean success, Message response);
+ void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response);
/**
* parameters equivilient to 27.007 AT+CRSM command
@@ -1038,6 +1152,20 @@ public interface CommandsInterface {
*/
void setSmscAddress(String address, Message result);
+ /**
+ * Indicates whether there is storage available for new SMS messages.
+ * @param available true if storage is available
+ * @param result callback message
+ */
+ void reportSmsMemoryStatus(boolean available, Message result);
+
+ /**
+ * Indicates to the vendor ril that StkService is running
+ * rand is eady to receive RIL_UNSOL_STK_XXXX commands.
+ *
+ * @param result callback message
+ */
+ void reportStkServiceIsRunning(Message result);
void invokeOemRilRequestRaw(byte[] data, Message response);
@@ -1074,6 +1202,31 @@ public interface CommandsInterface {
*/
public void handleCallSetupRequestFromSim(boolean accept, Message response);
+ /**
+ * Activate or deactivate cell broadcast SMS for GSM.
+ *
+ * @param activate
+ * true = activate, false = deactivate
+ * @param result Callback message is empty on completion
+ */
+ public void setGsmBroadcastActivation(boolean activate, Message result);
+
+ /**
+ * Configure cell broadcast SMS for GSM.
+ *
+ * @param response Callback message is empty on completion
+ */
+ public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response);
+
+ /**
+ * Query the current configuration of cell broadcast SMS of GSM.
+ *
+ * @param response
+ * Callback message contains the configuration from the modem
+ * on completion
+ */
+ public void getGsmBroadcastConfig(Message response);
+
//***** new Methods for CDMA support
/**
@@ -1087,13 +1240,12 @@ public interface CommandsInterface {
public void getDeviceIdentity(Message response);
/**
- * Request the device IMSI_M / MDN / AH_SID / H_SID / H_NID.
+ * Request the device MDN / H_SID / H_NID / MIN.
* "response" is const char **
- * [0] is IMSI_M if CDMA subscription is available
- * [1] is MDN if CDMA subscription is available
- * [2] is AH_SID (Analog Home SID) if CDMA subscription
- * [3] is H_SID (Home SID) if CDMA subscription is available
- * [4] is H_NID (Home SID) if CDMA subscription is available
+ * [0] is MDN if CDMA subscription is available
+ * [1] is H_SID (Home SID) if CDMA subscription is available
+ * [2] is H_NID (Home NID) if CDMA subscription is available
+ * [3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available
*/
public void getCDMASubscription(Message response);
@@ -1133,7 +1285,7 @@ public interface CommandsInterface {
* @param enable is true to enable, false to disable
* @param response is callback message
*/
- void setTTYModeEnabled(boolean enable, Message response);
+ void setTTYMode(int ttyMode, Message response);
/**
* Query the TTY mode for the CDMA phone
@@ -1142,7 +1294,7 @@ public interface CommandsInterface {
*
* @param response is callback message
*/
- void queryTTYModeEnabled(Message response);
+ void queryTTYMode(Message response);
/**
* Setup a packet data connection On successful completion, the result
@@ -1181,14 +1333,14 @@ public interface CommandsInterface {
public void deactivateDataCall(int cid, Message result);
/**
- * Activate or deactivate cell broadcast SMS.
+ * Activate or deactivate cell broadcast SMS for CDMA.
*
* @param activate
- * 0 = activate, 1 = deactivate
+ * true = activate, false = deactivate
* @param result
* Callback message is empty on completion
*/
- public void activateCdmaBroadcastSms(int activate, Message result);
+ public void setCdmaBroadcastActivation(boolean activate, Message result);
/**
* Configure cdma cell broadcast SMS.
@@ -1196,6 +1348,7 @@ public interface CommandsInterface {
* @param result
* Callback message is empty on completion
*/
+ // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
public void setCdmaBroadcastConfig(int[] configValuesArray, Message result);
/**
@@ -1205,4 +1358,12 @@ public interface CommandsInterface {
* Callback message contains the configuration from the modem on completion
*/
public void getCdmaBroadcastConfig(Message result);
+
+ /**
+ * Requests the radio's system selection module to exit emergency callback mode.
+ * This function should only be called from CDMAPHone.java.
+ *
+ * @param response callback message
+ */
+ public void exitEmergencyCallbackMode(Message response);
}
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
index 86ceb89..92f6cb8 100644
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ b/telephony/java/com/android/internal/telephony/Connection.java
@@ -27,27 +27,36 @@ public abstract class Connection {
public static int PRESENTATION_UNKNOWN = 3; // no specified or unknown by network
public static int PRESENTATION_PAYPHONE = 4; // show pay phone info
-
+
public enum DisconnectCause {
- NOT_DISCONNECTED, /* has not yet disconnected */
- INCOMING_MISSED, /* an incoming call that was missed and never answered */
- NORMAL, /* normal; remote */
- LOCAL, /* normal; local hangup */
- BUSY, /* outgoing call to busy line */
- CONGESTION, /* outgoing call to congested network */
- MMI, /* not presently used; dial() returns null */
- INVALID_NUMBER, /* invalid dial string */
+ NOT_DISCONNECTED, /* has not yet disconnected */
+ INCOMING_MISSED, /* an incoming call that was missed and never answered */
+ NORMAL, /* normal; remote */
+ LOCAL, /* normal; local hangup */
+ BUSY, /* outgoing call to busy line */
+ CONGESTION, /* outgoing call to congested network */
+ MMI, /* not presently used; dial() returns null */
+ INVALID_NUMBER, /* invalid dial string */
LOST_SIGNAL,
- LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */
- INCOMING_REJECTED, /* an incoming call that was rejected */
- POWER_OFF, /* radio is turned off explicitly */
- OUT_OF_SERVICE, /* out of service */
- ICC_ERROR, /* No ICC, ICC locked, or other ICC error */
- CALL_BARRED, /* call was blocked by call barrring */
- FDN_BLOCKED, /* call was blocked by fixed dial number */
- CS_RESTRICTED, /* call was blocked by restricted all voice access */
- CS_RESTRICTED_NORMAL,/* call was blocked by restricted normal voice access */
- CS_RESTRICTED_EMERGENCY/* call was blocked by restricted emergency voice access */
+ LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */
+ INCOMING_REJECTED, /* an incoming call that was rejected */
+ POWER_OFF, /* radio is turned off explicitly */
+ OUT_OF_SERVICE, /* out of service */
+ ICC_ERROR, /* No ICC, ICC locked, or other ICC error */
+ CALL_BARRED, /* call was blocked by call barrring */
+ FDN_BLOCKED, /* call was blocked by fixed dial number */
+ CS_RESTRICTED, /* call was blocked by restricted all voice access */
+ CS_RESTRICTED_NORMAL, /* call was blocked by restricted normal voice access */
+ CS_RESTRICTED_EMERGENCY, /* call was blocked by restricted emergency voice access */
+ CDMA_LOCKED_UNTIL_POWER_CYCLE, /* MS is locked until next power cycle */
+ CDMA_DROP,
+ CDMA_INTERCEPT, /* INTERCEPT order received, MS state idle entered */
+ CDMA_REORDER, /* MS has been redirected, call is cancelled */
+ CDMA_SO_REJECT, /* service option rejection */
+ CDMA_RETRY_ORDER, /* requeseted service is rejected, retry delay is set */
+ CDMA_ACCESS_FAILURE,
+ CDMA_PREEMPTED,
+ CDMA_NOT_EMERGENCY /* not an emergency call */
}
Object userData;
@@ -64,6 +73,31 @@ public abstract class Connection {
public abstract String getAddress();
/**
+ * Gets cdma CNAP name associated with connection
+ * @return cnap name or null if unavailable
+ */
+ public String getCnapName() {
+ return null;
+ }
+
+ /**
+ * Get orignal dial string
+ * @return orignal dial string or null if unavailable
+ */
+ public String getOrigDialString(){
+ return null;
+ }
+
+ /**
+ * Gets cdma CNAP presentation associated with connection
+ * @return cnap name or null if unavailable
+ */
+
+ public int getCnapNamePresentation() {
+ return 0;
+ };
+
+ /**
* @return Call that owns this Connection, or null if none
*/
public abstract Call getCall();
@@ -195,8 +229,14 @@ public abstract class Connection {
WILD, /* The post dial string playback is waiting for a
call to proceedAfterWildChar() */
COMPLETE, /* The post dial string playback is complete */
- CANCELLED /* The post dial string playback was cancelled
+ CANCELLED, /* The post dial string playback was cancelled
with cancelPostDial() */
+ PAUSE /* The post dial string playback is pausing for a
+ call to processNextPostDialChar*/
+ }
+
+ public void clearUserData(){
+ userData = null;
}
public abstract PostDialState getPostDialState();
@@ -220,8 +260,8 @@ public abstract class Connection {
/**
* Cancel any post
*/
- public abstract void cancelPostDial();
-
+ public abstract void cancelPostDial();
+
/**
* Returns the caller id presentation type for incoming and waiting calls
* @return one of PRESENTATION_*
diff --git a/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java b/telephony/java/com/android/internal/telephony/DataCallState.java
index 31cdacf..d0f3d24 100644
--- a/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java
+++ b/telephony/java/com/android/internal/telephony/DataCallState.java
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2009 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * 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.
@@ -14,25 +15,18 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
-/**
- * {@hide}
- */
-public class PDPContextState {
+public class DataCallState {
public int cid;
public int active;
public String type;
public String apn;
public String address;
+ @Override
public String toString() {
- return "com.android.internal.telephony.gsm.PDPContextState: {" +
- " cid: " + cid +
- ", active: " + active +
- ", type: " + type +
- ", apn: " + apn +
- ", address: " + address +
- " }";
+ return "DataCallState: {" + " cid: " + cid + ", active: " + active + ", type: " + type
+ + ", apn: " + apn + ", address: " + address + " }";
}
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 6e9d1ab..7809fed 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -55,57 +55,83 @@ public abstract class DataConnection extends Handler {
public enum FailCause {
NONE,
- BAD_APN,
- BAD_PAP_SECRET,
- BARRED,
+ OPERATOR_BARRED,
+ INSUFFICIENT_RESOURCES,
+ MISSING_UKNOWN_APN,
+ UNKNOWN_PDP_ADDRESS,
USER_AUTHENTICATION,
+ ACTIVATION_REJECT_GGSN,
+ ACTIVATION_REJECT_UNSPECIFIED,
SERVICE_OPTION_NOT_SUPPORTED,
SERVICE_OPTION_NOT_SUBSCRIBED,
- SIM_LOCKED,
- RADIO_OFF,
- NO_SIGNAL,
- NO_DATA_PLAN,
+ SERVICE_OPTION_OUT_OF_ORDER,
+ NSAPI_IN_USE,
+ PROTOCOL_ERRORS,
+ REGISTRATION_FAIL,
+ GPRS_REGISTRATION_FAIL,
+ UNKNOWN,
+
RADIO_NOT_AVAILABLE,
- SUSPENED_TEMPORARY,
- RADIO_ERROR_RETRY,
- UNKNOWN;
+ RADIO_ERROR_RETRY;
public boolean isPermanentFail() {
- return (this == RADIO_OFF);
+ return (this == OPERATOR_BARRED) || (this == MISSING_UKNOWN_APN) ||
+ (this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) ||
+ (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
+ (this == SERVICE_OPTION_NOT_SUPPORTED) ||
+ (this == SERVICE_OPTION_NOT_SUBSCRIBED) || (this == NSAPI_IN_USE) ||
+ (this == PROTOCOL_ERRORS);
+ }
+
+ public boolean isEventLoggable() {
+ return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) ||
+ (this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) ||
+ (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
+ (this == SERVICE_OPTION_NOT_SUBSCRIBED) ||
+ (this == SERVICE_OPTION_NOT_SUPPORTED) ||
+ (this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) ||
+ (this == PROTOCOL_ERRORS);
}
+ @Override
public String toString() {
switch (this) {
case NONE:
- return "no error";
- case BAD_APN:
- return "bad apn";
- case BAD_PAP_SECRET:
- return "bad pap secret";
- case BARRED:
- return "barred";
+ return "No Error";
+ case OPERATOR_BARRED:
+ return "Operator Barred";
+ case INSUFFICIENT_RESOURCES:
+ return "Insufficient Resources";
+ case MISSING_UKNOWN_APN:
+ return "Missing / Unknown APN";
+ case UNKNOWN_PDP_ADDRESS:
+ return "Unknown PDP Address";
case USER_AUTHENTICATION:
- return "error user autentication";
+ return "Error User Autentication";
+ case ACTIVATION_REJECT_GGSN:
+ return "Activation Reject GGSN";
+ case ACTIVATION_REJECT_UNSPECIFIED:
+ return "Activation Reject unspecified";
case SERVICE_OPTION_NOT_SUPPORTED:
- return "data not supported";
+ return "Data Not Supported";
case SERVICE_OPTION_NOT_SUBSCRIBED:
- return "datt not subcribed";
- case SIM_LOCKED:
- return "sim locked";
- case RADIO_OFF:
- return "radio is off";
- case NO_SIGNAL:
- return "no signal";
- case NO_DATA_PLAN:
- return "no data plan";
+ return "Data Not subscribed";
+ case SERVICE_OPTION_OUT_OF_ORDER:
+ return "Data Services Out of Order";
+ case NSAPI_IN_USE:
+ return "NSAPI in use";
+ case PROTOCOL_ERRORS:
+ return "Protocol Errors";
+ case REGISTRATION_FAIL:
+ return "Network Registration Failure";
+ case GPRS_REGISTRATION_FAIL:
+ return "Data Network Registration Failure";
case RADIO_NOT_AVAILABLE:
- return "radio not available";
- case SUSPENED_TEMPORARY:
- return "suspend temporary";
+ return "Radio Not Available";
case RADIO_ERROR_RETRY:
- return "transient radio error";
+ return "Transient Radio Rrror";
default:
- return "unknown data error";
+ return "Unknown Data Error";
}
}
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 5b826b2..c074cb8 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -63,7 +63,8 @@ public abstract class DataConnectionTracker extends Handler {
NONE,
DATAIN,
DATAOUT,
- DATAINANDOUT
+ DATAINANDOUT,
+ DORMANT
}
//***** Event Codes
@@ -92,19 +93,20 @@ public abstract class DataConnectionTracker extends Handler {
protected static final int EVENT_NV_READY = 31;
protected static final int EVENT_PS_RESTRICT_ENABLED = 32;
protected static final int EVENT_PS_RESTRICT_DISABLED = 33;
+ public static final int EVENT_CLEAN_UP_CONNECTION = 34;
//***** Constants
protected static final int RECONNECT_DELAY_INITIAL_MILLIS = 5 * 1000;
- /** Cap out with 1 hour retry interval. */
- protected static final int RECONNECT_DELAY_MAX_MILLIS = 60 * 60 * 1000;
+ /** Cap out with 30 min retry interval. */
+ protected static final int RECONNECT_DELAY_MAX_MILLIS = 30 * 60 * 1000;
/** Slow poll when attempting connection recovery. */
protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000;
/** Default ping deadline, in seconds. */
- protected final int DEFAULT_PING_DEADLINE = 5;
+ protected static final int DEFAULT_PING_DEADLINE = 5;
/** Default max failure count before attempting to network re-registration. */
- protected final int DEFAULT_MAX_PDP_RESET_FAIL = 3;
+ protected static final int DEFAULT_MAX_PDP_RESET_FAIL = 3;
/**
* After detecting a potential connection problem, this is the max number
@@ -148,7 +150,7 @@ public abstract class DataConnectionTracker extends Handler {
/** Intent sent when the reconnect alarm fires. */
protected PendingIntent mReconnectIntent = null;
-
+
/** CID of active data connection */
protected int cidActive;
@@ -216,7 +218,7 @@ public abstract class DataConnectionTracker extends Handler {
}
// abstract handler methods
- protected abstract void onTrySetupData();
+ protected abstract void onTrySetupData(String reason);
protected abstract void onRoamingOff();
protected abstract void onRoamingOn();
protected abstract void onRadioAvailable();
@@ -225,13 +227,18 @@ public abstract class DataConnectionTracker extends Handler {
protected abstract void onDisconnectDone(AsyncResult ar);
protected abstract void onVoiceCallStarted();
protected abstract void onVoiceCallEnded();
+ protected abstract void onCleanUpConnection(boolean tearDown, String reason);
//***** Overridden from Handler
public void handleMessage (Message msg) {
switch (msg.what) {
case EVENT_TRY_SETUP_DATA:
- onTrySetupData();
+ String reason = null;
+ if (msg.obj instanceof String) {
+ reason = (String)msg.obj;
+ }
+ onTrySetupData(reason);
break;
case EVENT_ROAMING_OFF:
@@ -267,6 +274,11 @@ public abstract class DataConnectionTracker extends Handler {
onVoiceCallEnded();
break;
+ case EVENT_CLEAN_UP_CONNECTION:
+ boolean tearDown = (msg.arg1 == 0) ? false : true;
+ onCleanUpConnection(tearDown, (String)msg.obj);
+ break;
+
default:
Log.e("DATA", "Unidentified event = " + msg.what);
break;
@@ -274,12 +286,6 @@ public abstract class DataConnectionTracker extends Handler {
}
/**
- * Simply tear down data connections due to radio off
- * and don't setup again.
- */
- public abstract void cleanConnectionBeforeRadioOff();
-
- /**
* Report the current state of data connectivity (enabled or disabled)
* @return {@code false} if data connectivity has been explicitly disabled,
* {@code true} otherwise.
diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index 79b4afe..d6151c6 100644
--- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -62,7 +62,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
public void notifySignalStrength(Phone sender) {
try {
- mRegistry.notifySignalStrength(sender.getSignalStrengthASU());
+ mRegistry.notifySignalStrength(sender.getSignalStrength());
} catch (RemoteException ex) {
// system process is dead
}
@@ -200,6 +200,8 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
return TelephonyManager.DATA_ACTIVITY_OUT;
case DATAINANDOUT:
return TelephonyManager.DATA_ACTIVITY_INOUT;
+ case DORMANT:
+ return TelephonyManager.DATA_ACTIVITY_DORMANT;
default:
return TelephonyManager.DATA_ACTIVITY_NONE;
}
@@ -217,6 +219,8 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
return Phone.DataActivityState.DATAOUT;
case TelephonyManager.DATA_ACTIVITY_INOUT:
return Phone.DataActivityState.DATAINANDOUT;
+ case TelephonyManager.DATA_ACTIVITY_DORMANT:
+ return Phone.DataActivityState.DORMANT;
default:
return Phone.DataActivityState.NONE;
}
diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
index 8f4c69c..e8095e1 100644
--- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
@@ -182,7 +182,7 @@ public class GsmAlphabet {
return stringToGsm7BitPacked(data);
}
- int headerBits = header.length * 8;
+ int headerBits = (header.length + 1) * 8;
int headerSeptets = headerBits / 7;
headerSeptets += (headerBits % 7) > 0 ? 1 : 0;
@@ -194,7 +194,8 @@ public class GsmAlphabet {
(headerSeptets*7), true);
// Paste in the header
- System.arraycopy(header, 0, ret, 1, header.length);
+ ret[1] = (byte)header.length;
+ System.arraycopy(header, 0, ret, 2, header.length);
return ret;
}
@@ -575,52 +576,6 @@ public class GsmAlphabet {
return size;
}
- /**
- * Returns the index into <code>s</code> of the first character
- * after <code>limit</code> octets have been reached, starting at
- * index <code>start</code>. This is used when dividing messages
- * in UCS2 encoding into units within the SMS message size limit.
- *
- * @param s source string
- * @param start index of where to start counting septets
- * @param limit maximum septets to include,
- * e.g. <code>MAX_USER_DATA_BYTES</code>
- * @return index of first character that won't fit, or the length
- * of the entire string if everything fits
- */
- public static int
- findUCS2LimitIndex(String s, int start, int limit) {
- int numCharToBeEncoded = s.length() - start;
- return ((numCharToBeEncoded*2 > limit)? limit/2: numCharToBeEncoded) + start;
- }
-
- /**
- * Returns the index into <code>s</code> of the first character
- * after <code>limit</code> septets/octets have been reached
- * according to the <code>encodingType</code>, starting at
- * index <code>start</code>. This is used when dividing messages
- * units within the SMS message size limit.
- *
- * @param s source string
- * @param start index of where to start counting septets
- * @param limit maximum septets to include,
- * e.g. <code>MAX_USER_DATA_BYTES</code>
- * @return index of first character that won't fit, or the length
- * of the entire string if everything fits
- */
- public static int
- findLimitIndex(String s, int start, int limit, int encodingType) throws EncodeException {
- if (encodingType == SmsMessage.ENCODING_7BIT) {
- return findGsmSeptetLimitIndex(s, start, limit);
- }
- else if (encodingType == SmsMessage.ENCODING_16BIT) {
- return findUCS2LimitIndex(s, start, limit);
- }
- else {
- throw new EncodeException("Unsupported encoding type: " + encodingType);
- }
- }
-
// Set in the static initializer
private static int sGsmSpaceChar;
diff --git a/telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl b/telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl
index 6c1f4bb..facdc49 100644
--- a/telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl
+++ b/telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl
@@ -1,11 +1,11 @@
package com.android.internal.telephony;
/**
- * Interface used to interact with extended MMI/USSD network service.
+ * Interface used to interact with extended MMI/USSD network service.
*/
interface IExtendedNetworkService {
/**
- * Set a MMI/USSD command to ExtendedNetworkService for further process.
+ * Set a MMI/USSD command to ExtendedNetworkService for further process.
* This should be called when a MMI command is placed from panel.
* @param number the dialed MMI/USSD number.
*/
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index e0884b3..0202ec8 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -18,6 +18,7 @@ package com.android.internal.telephony;
import android.os.Bundle;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
oneway interface IPhoneStateListener {
void onServiceStateChanged(in ServiceState serviceState);
@@ -30,5 +31,6 @@ oneway interface IPhoneStateListener {
void onCallStateChanged(int state, String incomingNumber);
void onDataConnectionStateChanged(int state);
void onDataActivity(int direction);
+ void onSignalStrengthsChanged(in SignalStrength signalStrength);
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index bab0603..d83b135 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -221,5 +221,27 @@ interface ITelephony {
*/
int getActivePhoneType();
+ /**
+ * Returns the CDMA ERI icon index to display
+ */
+ int getCdmaEriIconIndex();
+
+ /**
+ * Returns the CDMA ERI icon mode,
+ * 0 - ON
+ * 1 - FLASHING
+ */
+ int getCdmaEriIconMode();
+
+ /**
+ * Returns the CDMA ERI text,
+ */
+ String getCdmaEriText();
+
+ /**
+ * Returns the unread count of voicemails
+ */
+ int getVoiceMessageCount();
+
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 1b011fe..865c6ca 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -19,6 +19,7 @@ package com.android.internal.telephony;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import com.android.internal.telephony.IPhoneStateListener;
interface ITelephonyRegistry {
@@ -26,7 +27,7 @@ interface ITelephonyRegistry {
void notifyCallState(int state, String incomingNumber);
void notifyServiceState(in ServiceState state);
- void notifySignalStrength(int signalStrengthASU);
+ void notifySignalStrength(in SignalStrength signalStrength);
void notifyMessageWaitingChanged(boolean mwi);
void notifyCallForwardingChanged(boolean cfi);
void notifyDataActivity(int state);
diff --git a/telephony/java/com/android/internal/telephony/IccConstants.java b/telephony/java/com/android/internal/telephony/IccConstants.java
index 014fbb6..7eafafd 100644
--- a/telephony/java/com/android/internal/telephony/IccConstants.java
+++ b/telephony/java/com/android/internal/telephony/IccConstants.java
@@ -61,4 +61,5 @@ public interface IccConstants {
static final String DF_TELECOM = "7F10";
static final String DF_GRAPHICS = "5F50";
static final String DF_GSM = "7F20";
+ static final String DF_CDMA = "7F25";
}
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
index 114094b..ea24c25 100644
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ b/telephony/java/com/android/internal/telephony/IccRecords.java
@@ -196,7 +196,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
* If not available (eg, on an older CPHS SIM) -1 is returned if
* getVoiceMessageWaiting() is true
*/
- public int getCountVoiceMessages() {
+ public int getVoiceMessageCount() {
return countVoiceMessages;
}
diff --git a/telephony/java/com/android/internal/telephony/IccVmFixedException.java b/telephony/java/com/android/internal/telephony/IccVmFixedException.java
index 45679c1..a75496f 100644
--- a/telephony/java/com/android/internal/telephony/IccVmFixedException.java
+++ b/telephony/java/com/android/internal/telephony/IccVmFixedException.java
@@ -28,5 +28,5 @@ public final class IccVmFixedException extends IccException {
public IccVmFixedException(String s)
{
super(s);
- }
+ }
} \ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java b/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java
index 7e90d24..3c9d126 100644
--- a/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java
+++ b/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java
@@ -28,5 +28,5 @@ public final class IccVmNotSupportedException extends IccException {
public IccVmNotSupportedException(String s)
{
super(s);
- }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 03c1c56..c8d384d 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -23,6 +23,7 @@ import android.os.Message;
import android.preference.PreferenceManager;
import android.telephony.CellLocation;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.gsm.NetworkInfo;
@@ -82,9 +83,11 @@ public interface Phone {
* <li>DATAIN = Receiving IP ppp traffic</li>
* <li>DATAOUT = Sending IP ppp traffic</li>
* <li>DATAINANDOUT = Both receiving and sending IP ppp traffic</li>
+ * <li>DORMANT = The data connection is still active,
+ but physical link is down</li>
* </ul>
*/
- NONE, DATAIN, DATAOUT, DATAINANDOUT;
+ NONE, DATAIN, DATAOUT, DATAINANDOUT, DORMANT;
};
enum SuppService {
@@ -99,6 +102,7 @@ public interface Phone {
static final String DATA_APN_KEY = "apn";
static final String DATA_IFACE_NAME_KEY = "iface";
static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
+ static final String PHONE_IN_ECM_STATE = "phoneinECMState";
/**
* APN types for data connections. These are usage categories for an APN
@@ -150,7 +154,7 @@ public interface Phone {
static final String REASON_PS_RESTRICT_ENABLED = "psRestrictEnabled";
static final String REASON_PS_RESTRICT_DISABLED = "psRestrictDisabled";
static final String REASON_SIM_LOADED = "simLoaded";
-
+
// Used for band mode selection methods
static final int BM_UNSPECIFIED = 0; // selected by baseband automatically
static final int BM_EURO_BAND = 1; // GSM-900 / DCS-1800 / WCDMA-IMT-2000
@@ -162,28 +166,53 @@ public interface Phone {
// Used for preferred network type
// Note NT_* substitute RILConstants.NETWORK_MODE_* above the Phone
- int NT_MODE_WCDMA_PREF = 0; /* GSM/WCDMA (WCDMA preferred) */
- int NT_MODE_GSM_ONLY = 1; /* GSM only */
- int NT_MODE_WCDMA_ONLY = 2; /* WCDMA only */
- int NT_MODE_GSM_UMTS = 3; /* GSM/WCDMA (auto mode, according to PRL)
- AVAILABLE Application Settings menu*/
- int NT_MODE_CDMA = 4; /* CDMA and EvDo (auto mode, according to PRL)
- AVAILABLE Application Settings menu*/
- int NT_MODE_CDMA_NO_EVDO = 5; /* CDMA only */
- int NT_MODE_EVDO_NO_CDMA = 6; /* EvDo only */
- int NT_MODE_GLOBAL = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)
- AVAILABLE Application Settings menu*/
- int PREFERRED_NT_MODE = NT_MODE_GSM_ONLY;
+ int NT_MODE_WCDMA_PREF = RILConstants.NETWORK_MODE_WCDMA_PREF;
+ int NT_MODE_GSM_ONLY = RILConstants.NETWORK_MODE_GSM_ONLY;
+ int NT_MODE_WCDMA_ONLY = RILConstants.NETWORK_MODE_WCDMA_ONLY;
+ int NT_MODE_GSM_UMTS = RILConstants.NETWORK_MODE_GSM_UMTS;
+
+ int NT_MODE_CDMA = RILConstants.NETWORK_MODE_CDMA;
+
+ int NT_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO;
+ int NT_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
+ int NT_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL;
+
+ int PREFERRED_NT_MODE = RILConstants.PREFERRED_NETWORK_MODE;
// Used for CDMA roaming mode
- static final int CDMA_RM_HOME = 0; //Home Networks only, as defined in PRL
- static final int CDMA_RM_AFFILIATED = 1; //Roaming an Affiliated networks, as defined in PRL
- static final int CDMA_RM_ANY = 2; //Roaming on Any Network, as defined in PRL
+ static final int CDMA_RM_HOME = 0; // Home Networks only, as defined in PRL
+ static final int CDMA_RM_AFFILIATED = 1; // Roaming an Affiliated networks, as defined in PRL
+ static final int CDMA_RM_ANY = 2; // Roaming on Any Network, as defined in PRL
// Used for CDMA subscription mode
- static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; //RUIM/SIM (default)
- static final int CDMA_SUBSCRIPTION_NV = 1; //NV -> non-volatile memory
+ static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // RUIM/SIM (default)
+ static final int CDMA_SUBSCRIPTION_NV = 1; // NV -> non-volatile memory
+
+ static final int PREFERRED_CDMA_SUBSCRIPTION = CDMA_SUBSCRIPTION_NV;
+
+ static final int TTY_MODE_OFF = 0;
+ static final int TTY_MODE_FULL = 1;
+ static final int TTY_MODE_HCO = 2;
+ static final int TTY_MODE_VCO = 3;
+
+ /**
+ * CDMA OTA PROVISION STATUS, the same as RIL_CDMA_OTA_Status in ril.h
+ */
+
+ public static final int CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED = 0;
+ public static final int CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED = 1;
+ public static final int CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED = 2;
+ public static final int CDMA_OTA_PROVISION_STATUS_SSD_UPDATED = 3;
+ public static final int CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED = 4;
+ public static final int CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED = 5;
+ public static final int CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED = 6;
+ public static final int CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED = 7;
+ public static final int CDMA_OTA_PROVISION_STATUS_COMMITTED = 8;
+ public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED = 9;
+ public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED = 10;
+ public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED = 11;
+
/**
* Get the current ServiceState. Use
@@ -200,7 +229,7 @@ public interface Phone {
/**
* Get the current DataState. No change notification exists at this
* interface -- use
- * {@link com.android.internal.telephony.PhoneStateIntentReceiver PhoneStateIntentReceiver}
+ * {@link com.android.telephony.PhoneStateListener PhoneStateListener}
* instead.
*/
DataState getDataConnectionState();
@@ -270,9 +299,9 @@ public interface Phone {
* <ul><li>0 means "-113 dBm or less".</li>
* <li>31 means "-51 dBm or greater".</li></ul>
*
- * @return Current signal strength in ASU's.
+ * @return Current signal strength as SignalStrength
*/
- int getSignalStrengthASU();
+ SignalStrength getSignalStrength();
/**
* Notifies when a previously untracked non-ringing/waiting connection has appeared.
@@ -494,6 +523,21 @@ public interface Phone {
void unregisterForInCallVoicePrivacyOff(Handler h);
/**
+ * Register for notifications when CDMA OTA Provision status change
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForCdmaOtaStatusChange(Handler h, int what, Object obj);
+
+ /**
+ * Unegister for notifications when CDMA OTA Provision status change
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForCdmaOtaStatusChange(Handler h);
+
+ /**
* Returns SIM record load state. Use
* <code>getSimCard().registerForReady()</code> for change notification.
*
@@ -707,6 +751,19 @@ public interface Phone {
*/
void stopDtmf();
+ /**
+ * send burst DTMF tone, it can send the string as single character or multiple character
+ * ignore if there is no active call or not valid digits string.
+ * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
+ * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
+ * this api can send single character and multiple character, also, this api has response
+ * back to caller.
+ *
+ * @param dtmfString is string representing the dialing digit(s) in the active call
+ * @param onCompelte is the callback message when the action is processed by BP
+ *
+ */
+ void sendBurstDtmf(String dtmfString, Message onComplete);
/**
* Sets the radio power on/off state (off is sometimes
@@ -771,6 +828,12 @@ public interface Phone {
String getVoiceMailNumber();
/**
+ * Returns unread voicemail count. This count is shown when the voicemail
+ * notification is expanded.<p>
+ */
+ int getVoiceMessageCount();
+
+ /**
* Returns the alpha tag associated with the voice mail number.
* If there is no alpha tag associated or the record is not yet available,
* returns a default localized string. <p>
@@ -803,7 +866,7 @@ public interface Phone {
*
* @param commandInterfaceCFReason is one of the valid call forwarding
* CF_REASONS, as defined in
- * <code>com.android.internal.telephony.CommandsInterface./code>
+ * <code>com.android.internal.telephony.CommandsInterface.</code>
* @param onComplete a callback message when the action is completed.
* @see com.android.internal.telephony.CallForwardInfo for details.
*/
@@ -816,10 +879,10 @@ public interface Phone {
*
* @param commandInterfaceCFReason is one of the valid call forwarding
* CF_REASONS, as defined in
- * <code>com.android.internal.telephony.CommandsInterface./code>
+ * <code>com.android.internal.telephony.CommandsInterface.</code>
* @param commandInterfaceCFAction is one of the valid call forwarding
* CF_ACTIONS, as defined in
- * <code>com.android.internal.telephony.CommandsInterface./code>
+ * <code>com.android.internal.telephony.CommandsInterface.</code>
* @param dialingNumber is the target phone number to forward calls to
* @param timerSeconds is used by CFNRy to indicate the timeout before
* forwarding is attempted.
@@ -1279,6 +1342,20 @@ public interface Phone {
//***** CDMA support methods
+ /*
+ * TODO(Moto) TODO(Teleca): can getCdmaMin, getEsn, getMeid use more generic calls
+ * already defined getXxxx above?
+ */
+
+ /**
+ * Retrieves the MIN for CDMA phones.
+ */
+ String getCdmaMin();
+
+ /**
+ * Retrieves PRL Version for CDMA phones
+ */
+ String getCdmaPrlVersion();
/**
* Retrieves the ESN for CDMA phones.
@@ -1306,22 +1383,22 @@ public interface Phone {
public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager();
/**
- * setTTYModeEnabled
+ * setTTYMode
* sets a TTY mode option.
*
* @param enable is a boolean representing the state that you are
* requesting, true for enabled, false for disabled.
* @param onComplete a callback message when the action is completed
*/
- void setTTYModeEnabled(boolean enable, Message onComplete);
+ void setTTYMode(int ttyMode, Message onComplete);
/**
- * queryTTYModeEnabled
+ * queryTTYMode
* query the status of the TTY mode
*
* @param onComplete a callback message when the action is completed.
*/
- void queryTTYModeEnabled(Message onComplete);
+ void queryTTYMode(Message onComplete);
/**
* Activate or deactivate cell broadcast SMS.
@@ -1344,10 +1421,220 @@ public interface Phone {
/**
* Configure cell broadcast SMS.
*
+ * TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
+ *
* @param response
* Callback message is empty on completion
*/
public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response);
public void notifyDataActivity();
+
+ /**
+ * Returns the CDMA ERI icon index to display
+ */
+ public int getCdmaEriIconIndex();
+
+ /**
+ * Returns the CDMA ERI icon mode,
+ * 0 - ON
+ * 1 - FLASHING
+ */
+ public int getCdmaEriIconMode();
+
+ /**
+ * Returns the CDMA ERI text,
+ */
+ public String getCdmaEriText();
+
+ /**
+ * request to exit emergency call back mode
+ * the caller should use setOnECMModeExitResponse
+ * to receive the emergency callback mode exit response
+ */
+ void exitEmergencyCallbackMode();
+
+ /**
+ * this decides if the dial number is OTA(Over the air provision) number or not
+ * @param dialStr is string representing the dialing digit(s)
+ * @return true means the dialStr is OTA number, and false means the dialStr is not OTA number
+ */
+ boolean isOtaSpNumber(String dialStr);
+
+ /**
+ * Register for notifications when CDMA call waiting comes
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForCallWaiting(Handler h, int what, Object obj);
+
+ /**
+ * Unegister for notifications when CDMA Call waiting comes
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForCallWaiting(Handler h);
+
+
+ /**
+ * Register for signal information notifications from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a SuppServiceNotification instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+
+ void registerForSignalInfo(Handler h, int what, Object obj) ;
+ /**
+ * Unregisters for signal information notifications.
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForSignalInfo(Handler h);
+
+ /**
+ * Register for display information notifications from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a SuppServiceNotification instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForDisplayInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for display information notifications.
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForDisplayInfo(Handler h) ;
+
+ /**
+ * Register for CDMA number information record notification from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec
+ * instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForNumberInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for number information record notifications.
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForNumberInfo(Handler h);
+
+ /**
+ * Register for CDMA redirected number information record notification
+ * from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec
+ * instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForRedirectedNumberInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for redirected number information record notification.
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForRedirectedNumberInfo(Handler h);
+
+ /**
+ * Register for CDMA line control information record notification
+ * from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec
+ * instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForLineControlInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for line control information notifications.
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForLineControlInfo(Handler h);
+
+ /**
+ * Register for CDMA T53 CLIR information record notifications
+ * from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec
+ * instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerFoT53ClirlInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for T53 CLIR information record notification
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForT53ClirInfo(Handler h);
+
+ /**
+ * Register for CDMA T53 audio control information record notifications
+ * from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec
+ * instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForT53AudioControlInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for T53 audio control information record notifications.
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForT53AudioControlInfo(Handler h);
+
+ /**
+ * registers for exit emergency call back mode request response
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+
+ void setOnEcbModeExitResponse(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for exit emergency call back mode request response
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unsetOnEcbModeExitResponse(Handler h);
+
+
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 0314034..a26e729 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -29,6 +29,7 @@ import android.os.RegistrantList;
import android.os.SystemProperties;
import android.preference.PreferenceManager;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.text.TextUtils;
import android.util.Log;
@@ -90,6 +91,8 @@ public abstract class PhoneBase implements Phone {
protected static final int EVENT_RUIM_RECORDS_LOADED = 21;
protected static final int EVENT_NV_READY = 22;
protected static final int EVENT_SET_ENHANCED_VP = 23;
+ protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 24;
+ protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 25;
// Key used to read/write current CLIR setting
public static final String CLIR_KEY = "clir_key";
@@ -187,7 +190,7 @@ public abstract class PhoneBase implements Phone {
setUnitTestMode(unitTestMode);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
+ mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
}
// Inherited documentation suffices.
@@ -204,7 +207,7 @@ public abstract class PhoneBase implements Phone {
mDnsCheckDisabled = b;
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor editor = sp.edit();
- editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
+ editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
editor.commit();
}
@@ -282,7 +285,6 @@ public abstract class PhoneBase implements Phone {
mCM.unregisterForInCallVoicePrivacyOff(h);
}
-
/**
* Notifiy registrants of a new ringing Connection.
* Subclasses of Phone probably want to replace this with a
@@ -567,9 +569,6 @@ public abstract class PhoneBase implements Phone {
mCM.setPreferredNetworkType(networkType, response);
}
- /**
- * Set the status of the preferred Network Type: Global, CDMA only or GSM/UMTS only
- */
public void getPreferredNetworkType(Message response) {
mCM.getPreferredNetworkType(response);
}
@@ -582,12 +581,12 @@ public abstract class PhoneBase implements Phone {
mCM.setSmscAddress(address, result);
}
- public void setTTYModeEnabled(boolean enable, Message onComplete) {
+ public void setTTYMode(int ttyMode, Message onComplete) {
// This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
}
- public void queryTTYModeEnabled(Message onComplete) {
+ public void queryTTYMode(Message onComplete) {
// This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
}
@@ -632,10 +631,159 @@ public abstract class PhoneBase implements Phone {
mNotifier.notifyDataActivity(this);
}
+ public void notifyMessageWaitingIndicator() {
+ // This function is added to send the notification to DefaultPhoneNotifier.
+ mNotifier.notifyMessageWaitingChanged(this);
+ }
+
public void notifyDataConnection(String reason) {
mNotifier.notifyDataConnection(this, reason);
}
public abstract String getPhoneName();
+ /** @hide */
+ public int getVoiceMessageCount(){
+ return 0;
+ }
+
+ /**
+ * Returns the CDMA ERI icon index to display
+ */
+ public int getCdmaEriIconIndex() {
+ Log.e(LOG_TAG, "Error! getCdmaEriIconIndex should never be executed in GSM mode");
+ return -1;
+ }
+
+ /**
+ * Returns the CDMA ERI icon mode,
+ * 0 - ON
+ * 1 - FLASHING
+ */
+ public int getCdmaEriIconMode() {
+ Log.e(LOG_TAG, "Error! getCdmaEriIconMode should never be executed in GSM mode");
+ return -1;
+ }
+
+ /**
+ * Returns the CDMA ERI text,
+ */
+ public String getCdmaEriText() {
+ Log.e(LOG_TAG, "Error! getCdmaEriText should never be executed in GSM mode");
+ return "GSM nw, no ERI";
+ }
+
+ public String getCdmaMin() {
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ return null;
+ }
+
+ public String getCdmaPrlVersion(){
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ return null;
+ }
+
+ public void sendBurstDtmf(String dtmfString, Message onComplete) {
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
+
+ public void exitEmergencyCallbackMode() {
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
+
+ public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
+
+ public void unregisterForCdmaOtaStatusChange(Handler h) {
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
+
+ public boolean isOtaSpNumber(String dialStr) {
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ return false;
+ }
+
+ public void registerForCallWaiting(Handler h, int what, Object obj){
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
+
+ public void unregisterForCallWaiting(Handler h){
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
+
+ public void registerForSignalInfo(Handler h, int what, Object obj) {
+ mCM.registerForSignalInfo(h, what, obj);
+ }
+
+ public void unregisterForSignalInfo(Handler h) {
+ mCM.unregisterForSignalInfo(h);
+ }
+
+ public void registerForDisplayInfo(Handler h, int what, Object obj) {
+ mCM.registerForDisplayInfo(h, what, obj);
+ }
+
+ public void unregisterForDisplayInfo(Handler h) {
+ mCM.unregisterForDisplayInfo(h);
+ }
+
+ public void registerForNumberInfo(Handler h, int what, Object obj) {
+ mCM.registerForNumberInfo(h, what, obj);
+ }
+
+ public void unregisterForNumberInfo(Handler h) {
+ mCM.unregisterForNumberInfo(h);
+ }
+
+ public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
+ mCM.registerForRedirectedNumberInfo(h, what, obj);
+ }
+
+ public void unregisterForRedirectedNumberInfo(Handler h) {
+ mCM.unregisterForRedirectedNumberInfo(h);
+ }
+
+ public void registerForLineControlInfo(Handler h, int what, Object obj) {
+ mCM.registerForLineControlInfo( h, what, obj);
+ }
+
+ public void unregisterForLineControlInfo(Handler h) {
+ mCM.unregisterForLineControlInfo(h);
+ }
+
+ public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
+ mCM.registerFoT53ClirlInfo(h, what, obj);
+ }
+
+ public void unregisterForT53ClirInfo(Handler h) {
+ mCM.unregisterForT53ClirInfo(h);
+ }
+
+ public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
+ mCM.registerForT53AudioControlInfo( h, what, obj);
+ }
+
+ public void unregisterForT53AudioControlInfo(Handler h) {
+ mCM.unregisterForT53AudioControlInfo(h);
+ }
+
+ public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
+
+ public void unsetOnEcbModeExitResponse(Handler h){
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java
index 86e2f04..a84f74e 100644
--- a/telephony/java/com/android/internal/telephony/PhoneFactory.java
+++ b/telephony/java/com/android/internal/telephony/PhoneFactory.java
@@ -107,30 +107,49 @@ public class PhoneFactory {
//reads the system properties and makes commandsinterface
sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
- switch(networkMode) {
- case RILConstants.NETWORK_MODE_CDMA:
- case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
- case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
- case RILConstants.NETWORK_MODE_GLOBAL:
- sProxyPhone = new PhoneProxy(new CDMAPhone(context,
- sCommandsInterface, sPhoneNotifier));
- Log.i(LOG_TAG, "Creating CDMAPhone");
- break;
- case RILConstants.NETWORK_MODE_WCDMA_PREF:
- case RILConstants.NETWORK_MODE_GSM_ONLY:
- case RILConstants.NETWORK_MODE_WCDMA_ONLY:
- case RILConstants.NETWORK_MODE_GSM_UMTS:
- default:
- sProxyPhone = new PhoneProxy(new GSMPhone(context,
- sCommandsInterface, sPhoneNotifier));
- Log.i(LOG_TAG, "Creating GSMPhone");
- break;
+ int phoneType = getPhoneType(networkMode);
+ if (phoneType == RILConstants.GSM_PHONE) {
+ sProxyPhone = new PhoneProxy(new GSMPhone(context,
+ sCommandsInterface, sPhoneNotifier));
+ Log.i(LOG_TAG, "Creating GSMPhone");
+ } else if (phoneType == RILConstants.CDMA_PHONE) {
+ sProxyPhone = new PhoneProxy(new CDMAPhone(context,
+ sCommandsInterface, sPhoneNotifier));
+ Log.i(LOG_TAG, "Creating CDMAPhone");
}
+
sMadeDefaults = true;
}
}
}
+ /*
+ * This function returns the type of the phone, depending
+ * on the network mode.
+ *
+ * @param network mode
+ * @return Phone Type
+ */
+ public static int getPhoneType(int networkMode) {
+ switch(networkMode) {
+ case RILConstants.NETWORK_MODE_CDMA:
+ case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
+ case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
+ return RILConstants.CDMA_PHONE;
+
+ case RILConstants.NETWORK_MODE_WCDMA_PREF:
+ case RILConstants.NETWORK_MODE_GSM_ONLY:
+ case RILConstants.NETWORK_MODE_WCDMA_ONLY:
+ case RILConstants.NETWORK_MODE_GSM_UMTS:
+ return RILConstants.GSM_PHONE;
+
+ case RILConstants.NETWORK_MODE_GLOBAL:
+ return RILConstants.CDMA_PHONE;
+ default:
+ return RILConstants.GSM_PHONE;
+ }
+ }
+
public static Phone getDefaultPhone() {
if (sLooper != Looper.myLooper()) {
throw new RuntimeException(
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index b76d801..5b3c8dd 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -26,6 +26,7 @@ import android.os.Message;
import android.preference.PreferenceManager;
import android.telephony.CellLocation;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.util.Log;
import com.android.internal.telephony.cdma.CDMAPhone;
@@ -127,10 +128,9 @@ public class PhoneProxy extends Handler implements Phone {
Intent intent = new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
intent.putExtra(Phone.PHONE_NAME_KEY, mActivePhone.getPhoneName());
ActivityManagerNative.broadcastStickyIntent(intent, null);
-
break;
default:
- Log.e(LOG_TAG, "Error! This handler was not registered for this message type. Message: "
+ Log.e(LOG_TAG,"Error! This handler was not registered for this message type. Message: "
+ msg.what);
break;
}
@@ -198,8 +198,8 @@ public class PhoneProxy extends Handler implements Phone {
return mActivePhone.getActiveApn();
}
- public int getSignalStrengthASU() {
- return mActivePhone.getSignalStrengthASU();
+ public SignalStrength getSignalStrength() {
+ return mActivePhone.getSignalStrength();
}
public void registerForUnknownConnection(Handler h, int what, Object obj) {
@@ -306,6 +306,14 @@ public class PhoneProxy extends Handler implements Phone {
mActivePhone.unregisterForInCallVoicePrivacyOff(h);
}
+ public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
+ mActivePhone.registerForCdmaOtaStatusChange(h,what,obj);
+ }
+
+ public void unregisterForCdmaOtaStatusChange(Handler h) {
+ mActivePhone.unregisterForCdmaOtaStatusChange(h);
+ }
+
public boolean getIccRecordsLoaded() {
return mActivePhone.getIccRecordsLoaded();
}
@@ -406,6 +414,14 @@ public class PhoneProxy extends Handler implements Phone {
return mActivePhone.getLine1Number();
}
+ public String getCdmaMin() {
+ return mActivePhone.getCdmaMin();
+ }
+
+ public String getCdmaPrlVersion() {
+ return mActivePhone.getCdmaPrlVersion();
+ }
+
public String getLine1AlphaTag() {
return mActivePhone.getLine1AlphaTag();
}
@@ -418,6 +434,11 @@ public class PhoneProxy extends Handler implements Phone {
return mActivePhone.getVoiceMailNumber();
}
+ /** @hide */
+ public int getVoiceMessageCount(){
+ return mActivePhone.getVoiceMessageCount();
+ }
+
public String getVoiceMailAlphaTag() {
return mActivePhone.getVoiceMailAlphaTag();
}
@@ -648,12 +669,12 @@ public class PhoneProxy extends Handler implements Phone {
return mActivePhone.getIccPhoneBookInterfaceManager();
}
- public void setTTYModeEnabled(boolean enable, Message onComplete) {
- mActivePhone.setTTYModeEnabled(enable, onComplete);
+ public void setTTYMode(int ttyMode, Message onComplete) {
+ mActivePhone.setTTYMode(ttyMode, onComplete);
}
- public void queryTTYModeEnabled(Message onComplete) {
- mActivePhone.queryTTYModeEnabled(onComplete);
+ public void queryTTYMode(Message onComplete) {
+ mActivePhone.queryTTYMode(onComplete);
}
public void activateCellBroadcastSms(int activate, Message response) {
@@ -679,5 +700,100 @@ public class PhoneProxy extends Handler implements Phone {
public void setSmscAddress(String address, Message result) {
mActivePhone.setSmscAddress(address, result);
}
-}
+ public int getCdmaEriIconIndex() {
+ return mActivePhone.getCdmaEriIconIndex();
+ }
+
+ public String getCdmaEriText() {
+ return mActivePhone.getCdmaEriText();
+ }
+
+ public int getCdmaEriIconMode() {
+ return mActivePhone.getCdmaEriIconMode();
+ }
+
+ public void sendBurstDtmf(String dtmfString, Message onComplete){
+ mActivePhone.sendBurstDtmf(dtmfString,onComplete);
+ }
+
+ public void exitEmergencyCallbackMode(){
+ mActivePhone.exitEmergencyCallbackMode();
+ }
+
+ public boolean isOtaSpNumber(String dialStr){
+ return mActivePhone.isOtaSpNumber(dialStr);
+ }
+
+ public void registerForCallWaiting(Handler h, int what, Object obj){
+ mActivePhone.registerForCallWaiting(h,what,obj);
+ }
+
+ public void unregisterForCallWaiting(Handler h){
+ mActivePhone.unregisterForCallWaiting(h);
+ }
+
+ public void registerForSignalInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerForSignalInfo(h,what,obj);
+ }
+
+ public void unregisterForSignalInfo(Handler h) {
+ mActivePhone.unregisterForSignalInfo(h);
+ }
+
+ public void registerForDisplayInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerForDisplayInfo(h,what,obj);
+ }
+
+ public void unregisterForDisplayInfo(Handler h) {
+ mActivePhone.unregisterForDisplayInfo(h);
+ }
+
+ public void registerForNumberInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerForNumberInfo(h, what, obj);
+ }
+
+ public void unregisterForNumberInfo(Handler h) {
+ mActivePhone.unregisterForNumberInfo(h);
+ }
+
+ public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerForRedirectedNumberInfo(h, what, obj);
+ }
+
+ public void unregisterForRedirectedNumberInfo(Handler h) {
+ mActivePhone.unregisterForRedirectedNumberInfo(h);
+ }
+
+ public void registerForLineControlInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerForLineControlInfo( h, what, obj);
+ }
+
+ public void unregisterForLineControlInfo(Handler h) {
+ mActivePhone.unregisterForLineControlInfo(h);
+ }
+
+ public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerFoT53ClirlInfo(h, what, obj);
+ }
+
+ public void unregisterForT53ClirInfo(Handler h) {
+ mActivePhone.unregisterForT53ClirInfo(h);
+ }
+
+ public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerForT53AudioControlInfo( h, what, obj);
+ }
+
+ public void unregisterForT53AudioControlInfo(Handler h) {
+ mActivePhone.unregisterForT53AudioControlInfo(h);
+ }
+
+ public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
+ mActivePhone.setOnEcbModeExitResponse(h,what,obj);
+ }
+
+ public void unsetOnEcbModeExitResponse(Handler h){
+ mActivePhone.unsetOnEcbModeExitResponse(h);
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
index fd822cd..b31161c 100644
--- a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
+++ b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
@@ -23,6 +23,7 @@ import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -39,8 +40,6 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver {
private static final String LOG_TAG = "PHONE";
private static final boolean DBG = false;
- public static final String INTENT_KEY_ASU = "asu";
-
private static final int NOTIF_PHONE = 1 << 0;
private static final int NOTIF_SERVICE = 1 << 1;
private static final int NOTIF_SIGNAL = 1 << 2;
@@ -49,7 +48,8 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver {
Phone.State mPhoneState = Phone.State.IDLE;
ServiceState mServiceState = new ServiceState();
- int mAsu = -1;
+ SignalStrength mSignalStrength = new SignalStrength();
+
private Context mContext;
private Handler mTarget;
private IntentFilter mFilter;
@@ -106,12 +106,14 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver {
* Throws RuntimeException if client has not called notifySignalStrength()
*/
public int getSignalStrength() {
+ // TODO: use new SignalStrength instead of asu
if ((mWants & NOTIF_SIGNAL) == 0) {
throw new RuntimeException
("client must call notifySignalStrength(int)");
}
+ int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
- return mAsu;
+ return (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
}
/**
@@ -129,10 +131,15 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver {
int dBm = -1;
- if (mAsu != -1) {
- dBm = -113 + 2*mAsu;
+ if(!mSignalStrength.isGsm()) {
+ dBm = mSignalStrength.getCdmaDbm();
+ } else {
+ int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
+ int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
+ if (asu != -1) {
+ dBm = -113 + 2*asu;
+ }
}
-
return dBm;
}
@@ -180,8 +187,7 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver {
try {
if (TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED.equals(action)) {
- mAsu = intent.getIntExtra(INTENT_KEY_ASU, mAsu);
- if (DBG) Log.d(LOG_TAG, "onReceiveIntent: set asu=" + mAsu);
+ mSignalStrength = SignalStrength.newFromBundle(intent.getExtras());
if (mTarget != null && getNotifySignalStrength()) {
Message message = Message.obtain(mTarget, mAsuEventWhat);
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index be18a39..4db3e5b 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -38,9 +38,19 @@ import android.telephony.SmsMessage;
import android.util.Config;
import android.util.Log;
+import com.android.internal.telephony.CallForwardInfo;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.gsm.NetworkInfo;
-import com.android.internal.telephony.gsm.PDPContextState;
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.gsm.SuppServiceNotification;
+import com.android.internal.telephony.IccCardApplication;
+import com.android.internal.telephony.IccCardStatus;
+import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.SmsResponse;
+import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
+import com.android.internal.telephony.cdma.CdmaInformationRecords;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
@@ -156,7 +166,7 @@ class RILRequest {
}
void
- onError(int error) {
+ onError(int error, Object ret) {
CommandException ex;
ex = CommandException.fromRilErrno(error);
@@ -166,7 +176,7 @@ class RILRequest {
+ " error: " + ex);
if (mResult != null) {
- AsyncResult.forMessage(mResult, null, ex);
+ AsyncResult.forMessage(mResult, ret, ex);
mResult.sendToTarget();
}
@@ -233,6 +243,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
private static final int CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES = 31;
BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
sendScreenState(true);
@@ -280,7 +291,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
s = mSocket;
if (s == null) {
- rr.onError(RADIO_NOT_AVAILABLE);
+ rr.onError(RADIO_NOT_AVAILABLE, null);
rr.release();
mRequestMessagesPending--;
alreadySubtracted = true;
@@ -321,7 +332,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
// make sure this request has not already been handled,
// eg, if RILReceiver cleared the list.
if (req != null || !alreadySubtracted) {
- rr.onError(RADIO_NOT_AVAILABLE);
+ rr.onError(RADIO_NOT_AVAILABLE, null);
rr.release();
}
} catch (RuntimeException exc) {
@@ -330,7 +341,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
// make sure this request has not already been handled,
// eg, if RILReceiver cleared the list.
if (req != null || !alreadySubtracted) {
- rr.onError(GENERIC_FAILURE);
+ rr.onError(GENERIC_FAILURE, null);
rr.release();
}
}
@@ -535,7 +546,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
synchronized (mRequestsList) {
for (int i = 0, sz = mRequestsList.size() ; i < sz ; i++) {
RILRequest rr = mRequestsList.get(i);
- rr.onError(RADIO_NOT_AVAILABLE);
+ rr.onError(RADIO_NOT_AVAILABLE, null);
rr.release();
}
@@ -562,18 +573,22 @@ public final class RIL extends BaseCommands implements CommandsInterface {
mNetworkMode = networkMode;
//At startup mPhoneType is first set from networkMode
switch(networkMode) {
+ case RILConstants.NETWORK_MODE_WCDMA_PREF:
+ case RILConstants.NETWORK_MODE_GSM_ONLY:
+ case RILConstants.NETWORK_MODE_WCDMA_ONLY:
+ case RILConstants.NETWORK_MODE_GSM_UMTS:
+ mPhoneType = RILConstants.GSM_PHONE;
+ break;
case RILConstants.NETWORK_MODE_CDMA:
case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
+ mPhoneType = RILConstants.CDMA_PHONE;
+ break;
case RILConstants.NETWORK_MODE_GLOBAL:
mPhoneType = RILConstants.CDMA_PHONE;
break;
- case RILConstants.NETWORK_MODE_WCDMA_PREF:
- case RILConstants.NETWORK_MODE_GSM_ONLY:
- case RILConstants.NETWORK_MODE_WCDMA_ONLY:
- case RILConstants.NETWORK_MODE_GSM_UMTS:
default:
- mPhoneType = RILConstants.GSM_PHONE;
+ mPhoneType = RILConstants.CDMA_PHONE;
}
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
@@ -1052,6 +1067,17 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
+ public void
+ sendBurstDtmf(String dtmfString, Message result) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BURST_DTMF, result);
+
+ rr.mp.writeString(dtmfString);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " : " + dtmfString);
+
+ send(rr);
+ }
public void
sendSMS (String smscPDU, String pdu, Message result) {
@@ -1234,13 +1260,19 @@ public final class RIL extends BaseCommands implements CommandsInterface {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
- rr.mp.writeInt(5);
+ rr.mp.writeInt(6);
rr.mp.writeString(radioTechnology);
rr.mp.writeString(profile);
rr.mp.writeString(apn);
rr.mp.writeString(user);
rr.mp.writeString(password);
+ //TODO(): Add to the APN database, AuthType is set to CHAP/PAP
+ // 0 => Neither PAP nor CHAP will be performed, 3 => PAP / CHAP will be performed.
+ if (user != null)
+ rr.mp.writeString("3");
+ else
+ rr.mp.writeString("0");
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " "
+ apn);
@@ -1314,28 +1346,31 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
public void
- acknowledgeLastIncomingSMS(boolean success, Message result) {
+ acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SMS_ACKNOWLEDGE, result);
- rr.mp.writeInt(1);
+ rr.mp.writeInt(2);
rr.mp.writeInt(success ? 1 : 0);
+ rr.mp.writeInt(cause);
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " " + success + " " + cause);
send(rr);
}
public void
- acknowledgeLastIncomingCdmaSms(boolean success, Message result) {
+ acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result);
rr.mp.writeInt(success ? 0 : 1); //RIL_CDMA_SMS_ErrorClass
// cause code according to X.S004-550E
- rr.mp.writeInt(39); //39 means other terminal problem; is not interpreted for success.
+ rr.mp.writeInt(cause);
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " " + success + " " + cause);
send(rr);
}
@@ -1361,6 +1396,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
if (RILJ_LOGD) riljLog(rr.serialString() + "> iccIO: " + requestToString(rr.mRequest)
+ " 0x" + Integer.toHexString(command)
+ " 0x" + Integer.toHexString(fileid) + " "
+ + " path: " + path + ","
+ p1 + "," + p2 + "," + p3);
send(rr);
@@ -1777,7 +1813,6 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void setSmscAddress(String address, Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_SMSC_ADDRESS, result);
- rr.mp.writeInt(1);
rr.mp.writeString(address);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
@@ -1786,6 +1821,84 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
+ /**
+ * {@inheritDoc}
+ */
+ public void reportSmsMemoryStatus(boolean available, Message result) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result);
+ rr.mp.writeInt(1);
+ rr.mp.writeInt(available ? 1 : 0);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> "
+ + requestToString(rr.mRequest) + ": " + available);
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void reportStkServiceIsRunning(Message result) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void getGsmBroadcastConfig(Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, response);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, response);
+
+ int numOfConfig = config.length;
+ rr.mp.writeInt(numOfConfig);
+
+ for(int i = 0; i < numOfConfig; i++) {
+ rr.mp.writeInt(config[i].getFromServiceId());
+ rr.mp.writeInt(config[i].getToServiceId());
+ rr.mp.writeInt(config[i].getFromCodeScheme());
+ rr.mp.writeInt(config[i].getToCodeScheme());
+ rr.mp.writeInt(config[i].isSelected() ? 1 : 0);
+ }
+
+ if (RILJ_LOGD) {
+ riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " with " + numOfConfig + "configs : ");
+ for (int i = 0; i < numOfConfig; i++) {
+ riljLog(config[i].toString());
+ }
+ }
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setGsmBroadcastActivation(boolean activate, Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, response);
+
+ rr.mp.writeInt(1);
+ rr.mp.writeInt(activate ? 0 : 1);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
//***** Private Methods
private void sendScreenState(boolean on) {
@@ -1793,7 +1906,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr.mp.writeInt(1);
rr.mp.writeInt(on ? 1 : 0);
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + ": " + on);
+ if (RILJ_LOGD) riljLog(rr.serialString()
+ + "> " + requestToString(rr.mRequest) + ": " + on);
send(rr);
}
@@ -1838,7 +1952,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
* and/or radio knowing.
*/
if (RILJ_LOGD) Log.d(LOG_TAG, "Radio ON @ init; reset to OFF");
- setRadioPower(false, null);
+ setRadioPower(false, null);
} else {
if (DBG) Log.d(LOG_TAG, "Radio OFF @ init");
setRadioState(newState);
@@ -1941,28 +2055,24 @@ public final class RIL extends BaseCommands implements CommandsInterface {
return;
}
- if (error != 0) {
- rr.onError(error);
- rr.release();
- return;
- }
+ Object ret = null;
- Object ret;
-
- try {switch (rr.mRequest) {
-/*
+ if (error == 0 || p.dataAvail() > 0) {
+ // either command succeeds or command fails but with data payload
+ try {switch (rr.mRequest) {
+ /*
cat libs/telephony/ril_commands.h \
| egrep "^ *{RIL_" \
| sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/'
-*/
+ */
case RIL_REQUEST_GET_SIM_STATUS: ret = responseIccCardStatus(p); break;
- case RIL_REQUEST_ENTER_SIM_PIN: ret = responseVoid(p); break;
- case RIL_REQUEST_ENTER_SIM_PUK: ret = responseVoid(p); break;
- case RIL_REQUEST_ENTER_SIM_PIN2: ret = responseVoid(p); break;
- case RIL_REQUEST_ENTER_SIM_PUK2: ret = responseVoid(p); break;
- case RIL_REQUEST_CHANGE_SIM_PIN: ret = responseVoid(p); break;
- case RIL_REQUEST_CHANGE_SIM_PIN2: ret = responseVoid(p); break;
- case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret = responseVoid(p); break;
+ case RIL_REQUEST_ENTER_SIM_PIN: ret = responseInts(p); break;
+ case RIL_REQUEST_ENTER_SIM_PUK: ret = responseInts(p); break;
+ case RIL_REQUEST_ENTER_SIM_PIN2: ret = responseInts(p); break;
+ case RIL_REQUEST_ENTER_SIM_PUK2: ret = responseInts(p); break;
+ case RIL_REQUEST_CHANGE_SIM_PIN: ret = responseInts(p); break;
+ case RIL_REQUEST_CHANGE_SIM_PIN2: ret = responseInts(p); break;
+ case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret = responseInts(p); break;
case RIL_REQUEST_GET_CURRENT_CALLS: ret = responseCallList(p); break;
case RIL_REQUEST_DIAL: ret = responseVoid(p); break;
case RIL_REQUEST_GET_IMSI: ret = responseString(p); break;
@@ -1973,7 +2083,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break;
case RIL_REQUEST_UDUB: ret = responseVoid(p); break;
case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break;
- case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseInts(p); break;
+ case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
case RIL_REQUEST_REGISTRATION_STATE: ret = responseStrings(p); break;
case RIL_REQUEST_GPRS_REGISTRATION_STATE: ret = responseStrings(p); break;
case RIL_REQUEST_OPERATOR: ret = responseStrings(p); break;
@@ -1997,7 +2107,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_ANSWER: ret = responseVoid(p); break;
case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret = responseVoid(p); break;
case RIL_REQUEST_QUERY_FACILITY_LOCK: ret = responseInts(p); break;
- case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseVoid(p); break;
+ case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseInts(p); break;
case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break;
case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret = responseInts(p); break;
case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret = responseVoid(p); break;
@@ -2042,33 +2152,42 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_CDMA_BURST_DTMF: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SEND_SMS: ret = responseSMS(p); break;
case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
- case RIL_REQUEST_GET_BROADCAST_CONFIG: ret = responseBR_SMS_CNF(p); break;
- case RIL_REQUEST_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCDMA_BR_CNF(p); break;
+ case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret = responseGmsBroadcastConfig(p); break;
+ case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
+ case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCdmaBroadcastConfig(p); break;
case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
- case RIL_REQUEST_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_VALIDATE_AKEY: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_VALIDATE_AKEY: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SUBSCRIPTION: ret = responseStrings(p); break;
case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret = responseInts(p); break;
case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret = responseVoid(p); break;
case RIL_REQUEST_DEVICE_IDENTITY: ret = responseStrings(p); break;
case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
+ case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
+ case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
default:
throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
- }} catch (Throwable tr) {
- // Exceptions here usually mean invalid RIL responses
+ }} catch (Throwable tr) {
+ // Exceptions here usually mean invalid RIL responses
- Log.w(LOG_TAG, rr.serialString() + "< "
- + requestToString(rr.mRequest)
- + " exception, possible invalid RIL response", tr);
+ Log.w(LOG_TAG, rr.serialString() + "< "
+ + requestToString(rr.mRequest)
+ + " exception, possible invalid RIL response", tr);
- if (rr.mResult != null) {
- AsyncResult.forMessage(rr.mResult, null, tr);
- rr.mResult.sendToTarget();
+ if (rr.mResult != null) {
+ AsyncResult.forMessage(rr.mResult, null, tr);
+ rr.mResult.sendToTarget();
+ }
+ rr.release();
+ return;
}
+ }
+
+ if (error != 0) {
+ rr.onError(error, ret);
rr.release();
return;
}
@@ -2167,7 +2286,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break;
case RIL_UNSOL_ON_USSD: ret = responseStrings(p); break;
case RIL_UNSOL_NITZ_TIME_RECEIVED: ret = responseString(p); break;
- case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseInts(p); break;
+ case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;
case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break;
case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break;
@@ -2176,13 +2295,18 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
case RIL_UNSOL_SIM_REFRESH: ret = responseInts(p); break;
- case RIL_UNSOL_CALL_RING: ret = responseVoid(p); break;
+ case RIL_UNSOL_CALL_RING: ret = responseCallRing(p); break;
case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break;
case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseString(p); break;
case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
+ case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
+ case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
+ case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
+ case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
+
default:
throw new RuntimeException("Unrecognized unsol response: " + response);
//break; (implied)
@@ -2366,10 +2490,11 @@ public final class RIL extends BaseCommands implements CommandsInterface {
break;
case RIL_UNSOL_CALL_RING:
- if (RILJ_LOGD) unsljLog(response);
+ if (RILJ_LOGD) unsljLogRet(response, ret);
if (mRingRegistrant != null) {
- mRingRegistrant.notifyRegistrant();
+ mRingRegistrant.notifyRegistrant(
+ new AsyncResult (null, ret, null));
}
break;
@@ -2381,12 +2506,16 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
+ if (RILJ_LOGD) unsljLog(response);
+
if (mIccStatusChangedRegistrants != null) {
mIccStatusChangedRegistrants.notifyRegistrants();
}
break;
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
+ if (RILJ_LOGD) unsljLog(response);
+
SmsMessage sms = (SmsMessage) ret;
if (mSMSRegistrant != null) {
@@ -2396,19 +2525,64 @@ public final class RIL extends BaseCommands implements CommandsInterface {
break;
case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
- // TODO T: waiting for SMS BC feature
+ if (RILJ_LOGD) unsljLog(response);
+
+ if (mGsmBroadcastSmsRegistrant != null) {
+ mGsmBroadcastSmsRegistrant
+ .notifyRegistrant(new AsyncResult(null, ret, null));
+ }
break;
case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
- if (Config.LOGD) {
- if (RILJ_LOGD) riljLog("[UNSL]< RUIM_SMS_STORAGE_FULL");
- }
+ if (RILJ_LOGD) unsljLog(response);
if (mIccSmsFullRegistrant != null) {
mIccSmsFullRegistrant.notifyRegistrant();
}
break;
+ case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
+ if (RILJ_LOGD) unsljLog(response);
+
+ if (mEmergencyCallbackModeRegistrant != null) {
+ mEmergencyCallbackModeRegistrant.notifyRegistrant();
+ }
+ break;
+
+ case RIL_UNSOL_CDMA_CALL_WAITING:
+ if (RILJ_LOGD) unsljLog(response);
+
+ if (mCallWaitingInfoRegistrants != null) {
+ mCallWaitingInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mOtaProvisionRegistrants != null) {
+ mOtaProvisionRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_CDMA_INFO_REC:
+ ArrayList<CdmaInformationRecords> listInfoRecs;
+
+ try {
+ listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
+ } catch (ClassCastException e) {
+ Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
+ break;
+ }
+
+ for (CdmaInformationRecords rec : listInfoRecs) {
+ if (RILJ_LOGD) unsljLogRet(response, rec);
+ notifyRegistrantsCdmaInfoRec(rec);
+ }
+ break;
+
case RIL_UNSOL_OEM_HOOK_RAW:
if (RILJ_LOGD) unsljLogvRet(response, IccUtils.bytesToHexString((byte[])ret));
if (mUnsolOemHookRawRegistrant != null) {
@@ -2524,13 +2698,14 @@ public final class RIL extends BaseCommands implements CommandsInterface {
private Object
responseSMS(Parcel p) {
- int messageRef;
+ int messageRef, errorCode;
String ackPDU;
messageRef = p.readInt();
ackPDU = p.readString();
+ errorCode = p.readInt();
- SmsResponse response = new SmsResponse(messageRef, ackPDU);
+ SmsResponse response = new SmsResponse(messageRef, ackPDU, errorCode);
return response;
}
@@ -2547,6 +2722,11 @@ public final class RIL extends BaseCommands implements CommandsInterface {
String s = p.readString();
+ if (RILJ_LOGD) riljLog("< iccIO: "
+ + " 0x" + Integer.toHexString(sw1)
+ + " 0x" + Integer.toHexString(sw2) + " "
+ + s);
+
return new IccIoResult(sw1, sw2, s);
}
@@ -2658,33 +2838,24 @@ public final class RIL extends BaseCommands implements CommandsInterface {
dc.als = p.readInt();
voiceSettings = p.readInt();
dc.isVoice = (0 == voiceSettings) ? false : true;
-
- //dc.isVoicePrivacy = (0 != p.readInt());
- int voicePrivacy = p.readInt();
- dc.isVoicePrivacy = (0 != voicePrivacy);
-
+ dc.isVoicePrivacy = (0 != p.readInt());
dc.number = p.readString();
int np = p.readInt();
dc.numberPresentation = DriverCall.presentationFromCLIP(np);
dc.name = p.readString();
dc.namePresentation = p.readInt();
- // Make sure there's a leading + on addresses with a TOA
- // of 145
-
- dc.number = PhoneNumberUtils.stringFromStringAndTOA(
- dc.number, dc.TOA);
+ // Make sure there's a leading + on addresses with a TOA of 145
+ dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
response.add(dc);
- if ( RILConstants.CDMA_VOICE_PRIVACY == voiceSettings ) {
+ if (dc.isVoicePrivacy) {
mVoicePrivacyOnRegistrants.notifyRegistrants();
- Log.d(LOG_TAG, "InCall VoicePrivacy is enabled: " +
- Integer.toString(voiceSettings));
+ Log.d(LOG_TAG, "InCall VoicePrivacy is enabled");
} else {
mVoicePrivacyOffRegistrants.notifyRegistrants();
- Log.d(LOG_TAG, "InCall VoicePrivacy is disabled: " +
- Integer.toString(voiceSettings));
+ Log.d(LOG_TAG, "InCall VoicePrivacy is disabled");
}
}
@@ -2696,21 +2867,21 @@ public final class RIL extends BaseCommands implements CommandsInterface {
private Object
responseDataCallList(Parcel p) {
int num;
- ArrayList<PDPContextState> response;
+ ArrayList<DataCallState> response;
num = p.readInt();
- response = new ArrayList<PDPContextState>(num);
+ response = new ArrayList<DataCallState>(num);
for (int i = 0; i < num; i++) {
- PDPContextState pdp = new PDPContextState();
+ DataCallState dataCall = new DataCallState();
- pdp.cid = p.readInt();
- pdp.active = p.readInt();
- pdp.type = p.readString();
- pdp.apn = p.readString();
- pdp.address = p.readString();
+ dataCall.cid = p.readInt();
+ dataCall.active = p.readInt();
+ dataCall.type = p.readString();
+ dataCall.apn = p.readString();
+ dataCall.address = p.readString();
- response.add(pdp);
+ response.add(dataCall);
}
return response;
@@ -2751,51 +2922,66 @@ public final class RIL extends BaseCommands implements CommandsInterface {
response = new ArrayList<NeighboringCellInfo>(num);
for (int i = 0 ; i < num ; i++) {
- try {
- int rssi = p.readInt();
- int cid = Integer.valueOf(p.readString(), 16);
- cell = new NeighboringCellInfo(rssi, cid);
- response.add(cell);
- } catch ( Exception e) {
- }
+ int rssi = p.readInt();
+ int cid = Integer.valueOf(p.readString(), 16);
+ cell = new NeighboringCellInfo(rssi, cid);
+ response.add(cell);
}
return response;
}
- private Object
- responseBR_SMS_CNF(Parcel p) {
- // TODO
- return null;
+ private Object responseGmsBroadcastConfig(Parcel p) {
+ int num;
+ ArrayList<SmsBroadcastConfigInfo> response;
+ SmsBroadcastConfigInfo info;
+
+ num = p.readInt();
+ response = new ArrayList<SmsBroadcastConfigInfo>(num);
+
+ for (int i = 0; i < num; i++) {
+ int fromId = p.readInt();
+ int toId = p.readInt();
+ int fromScheme = p.readInt();
+ int toScheme = p.readInt();
+ boolean selected = (p.readInt() == 1);
+
+ info = new SmsBroadcastConfigInfo(fromId, toId, fromScheme,
+ toScheme, selected);
+ response.add(info);
+ }
+ return response;
}
private Object
- responseCDMA_BR_CNF(Parcel p) {
+ responseCdmaBroadcastConfig(Parcel p) {
int numServiceCategories;
int response[];
numServiceCategories = p.readInt();
if (numServiceCategories == 0) {
+ // TODO(Teleca) TODO(Moto): The logic of providing default
+ // values should not be done by this transport layer. And
+ // needs to be done by the vendor ril or application logic.
+ // TODO(Google): Remove ASAP
int numInts;
numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1;
response = new int[numInts];
- // indicate that a zero length table was received
- response[0] = 0;
- //for all supported service categories set 'english' as default language
- //and selection status to false
- for (int i = 1, j = 1
- ; i <= (CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES
- * CDMA_BSI_NO_OF_INTS_STRUCT)
- ; i += CDMA_BSI_NO_OF_INTS_STRUCT, j++ ) {
- response[i] = j;
- response[i+1] = 1;
- response[i+2] = 0;
+ // Faking a default record for all possible records.
+ response[0] = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES;
+
+ // Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as
+ // default language and selection status to false for all.
+ for (int i = 1; i < numInts; i += CDMA_BSI_NO_OF_INTS_STRUCT ) {
+ response[i + 0] = i / CDMA_BSI_NO_OF_INTS_STRUCT;
+ response[i + 1] = 1;
+ response[i + 2] = 0;
}
} else {
int numInts;
- numInts = numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT + 1;
+ numInts = (numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT) + 1;
response = new int[numInts];
response[0] = numServiceCategories;
@@ -2807,6 +2993,116 @@ public final class RIL extends BaseCommands implements CommandsInterface {
return response;
}
+ private Object
+ responseSignalStrength(Parcel p) {
+ int numInts = 7;
+ int response[];
+
+ /* TODO: Add SignalStrength class to match RIL_SignalStrength */
+ response = new int[numInts];
+ for (int i = 0 ; i < numInts ; i++) {
+ response[i] = p.readInt();
+ }
+
+ return response;
+ }
+
+ private ArrayList<CdmaInformationRecords>
+ responseCdmaInformationRecord(Parcel p) {
+ int numberOfInfoRecs;
+ ArrayList<CdmaInformationRecords> response;
+
+ /**
+ * Loop through all of the information records unmarshalling them
+ * and converting them to Java Objects.
+ */
+ numberOfInfoRecs = p.readInt();
+ response = new ArrayList<CdmaInformationRecords>(numberOfInfoRecs);
+
+ for (int i = 0; i < numberOfInfoRecs; i++) {
+ CdmaInformationRecords InfoRec = new CdmaInformationRecords(p);
+ response.add(InfoRec);
+ }
+
+ return response;
+ }
+
+ private Object
+ responseCdmaCallWaiting(Parcel p) {
+ CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification();
+
+ notification.number = p.readString();
+ notification.numberPresentation = p.readInt();
+ notification.name = p.readString();
+ notification.namePresentation = notification.numberPresentation;
+ notification.isPresent = p.readInt();
+ notification.signalType = p.readInt();
+ notification.alertPitch = p.readInt();
+ notification.signal = p.readInt();
+
+ return notification;
+ }
+
+ private Object
+ responseCallRing(Parcel p){
+ char response[] = new char[4];
+
+ response[0] = (char) p.readInt(); // isPresent
+ response[1] = (char) p.readInt(); // signalType
+ response[2] = (char) p.readInt(); // alertPitch
+ response[3] = (char) p.readInt(); // signal
+
+ return response;
+ }
+
+ private void
+ notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
+ int response = RIL_UNSOL_CDMA_INFO_REC;
+ if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
+ if (mDisplayInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mDisplayInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) {
+ if (mSignalInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mSignalInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) {
+ if (mNumberInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mNumberInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) {
+ if (mRedirNumInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mRedirNumInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
+ if (mLineControlInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mLineControlInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
+ if (mT53ClirInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mT53ClirInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) {
+ if (mT53AudCntrlInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mT53AudCntrlInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ }
+ }
+
static String
requestToString(int request) {
/*
@@ -2902,11 +3198,11 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_CDMA_BURST_DTMF: return "RIL_REQUEST_CDMA_BURST_DTMF";
case RIL_REQUEST_CDMA_SEND_SMS: return "RIL_REQUEST_CDMA_SEND_SMS";
case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
- case RIL_REQUEST_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GET_BROADCAST_CONFIG";
- case RIL_REQUEST_SET_BROADCAST_CONFIG: return "RIL_REQUEST_SET_BROADCAST_CONFIG";
+ case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG";
+ case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG";
case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
- case RIL_REQUEST_BROADCAST_ACTIVATION: return "RIL_REQUEST_BROADCAST_ACTIVATION";
+ case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
case RIL_REQUEST_CDMA_VALIDATE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AKEY";
case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
case RIL_REQUEST_CDMA_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SUBSCRIPTION";
@@ -2915,6 +3211,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_DEVICE_IDENTITY: return "RIL_REQUEST_DEVICE_IDENTITY";
case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS";
case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS";
+ case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
+ case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
+ case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
default: return "<unknown request>";
}
}
@@ -2947,8 +3246,16 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL";
case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
- case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "RIL_UNSOL_RESTRICTED_STATE_CHANGED";
- case RIL_UNSOL_OEM_HOOK_RAW: return "RIL_UNSOL_OEM_HOOK_RAW";
+ case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
+ case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS";
+ case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
+ case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
+ case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
+ case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
+ case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
+ case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
+ case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
+ case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
default: return "<unknown reponse>";
}
}
@@ -3048,7 +3355,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
/**
* {@inheritDoc}
*/
- public void queryTTYModeEnabled(Message response) {
+ public void queryTTYMode(Message response) {
RILRequest rr = RILRequest.obtain(
RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
@@ -3058,12 +3365,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
/**
* {@inheritDoc}
*/
- public void setTTYModeEnabled(boolean enable, Message response) {
+ public void setTTYMode(int ttyMode, Message response) {
RILRequest rr = RILRequest.obtain(
RILConstants.RIL_REQUEST_SET_TTY_MODE, response);
rr.mp.writeInt(1);
- rr.mp.writeInt(enable ? 1 : 0);
+ rr.mp.writeInt(ttyMode);
send(rr);
}
@@ -3075,7 +3382,6 @@ public final class RIL extends BaseCommands implements CommandsInterface {
sendCDMAFeatureCode(String FeatureCode, Message response) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_FLASH, response);
- rr.mp.writeInt(1);
rr.mp.writeString(FeatureCode);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
@@ -3090,11 +3396,11 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
+ // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, response);
- rr.mp.writeInt(configValuesArray[0]);
- for(int i = 1; i <= (configValuesArray[0] * 3); i++) {
+ for(int i = 0; i < configValuesArray.length; i++) {
rr.mp.writeInt(configValuesArray[i]);
}
@@ -3103,11 +3409,22 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void activateCdmaBroadcastSms(int activate, Message response) {
+ public void setCdmaBroadcastActivation(boolean activate, Message response) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, response);
rr.mp.writeInt(1);
- rr.mp.writeInt(activate);
+ rr.mp.writeInt(activate ? 0 :1);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void exitEmergencyCallbackMode(Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, response);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index bcf5141..b2e16c7 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -16,6 +16,13 @@
package com.android.internal.telephony;
+/**
+ * TODO: This should probably not be an interface see
+ * http://www.javaworld.com/javaworld/javaqa/2001-06/01-qa-0608-constants.html and google with
+ * http://www.google.com/search?q=interface+constants&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a
+ *
+ * Also they should all probably be static final.
+ */
/**
* {@hide}
@@ -51,7 +58,7 @@ public interface RILConstants {
int NETWORK_MODE_EVDO_NO_CDMA = 6; /* EvDo only */
int NETWORK_MODE_GLOBAL = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)
AVAILABLE Application Settings menu*/
- int PREFERRED_NETWORK_MODE = NETWORK_MODE_GSM_ONLY;
+ int PREFERRED_NETWORK_MODE = NETWORK_MODE_WCDMA_PREF;
/* CDMA subscription source. See ril.h RIL_REQUEST_CDMA_SET_SUBSCRIPTION */
int SUBSCRIPTION_FROM_RUIM = 0; /* CDMA subscription from RUIM when available */
@@ -67,8 +74,9 @@ public interface RILConstants {
int CDM_TTY_MODE_DISABLED = 0;
int CDM_TTY_MODE_ENABLED = 1;
- byte CDMA_VOICE_PRIVACY = 0x70; /* "p" value used in Ril_Call.isVoice if Privacy
- is active */
+ int CDM_TTY_FULL_MODE = 1;
+ int CDM_TTY_HCO_MODE = 2;
+ int CDM_TTY_VCO_MODE = 3;
/*
cat include/telephony/ril.h | \
@@ -198,9 +206,9 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_CDMA_VALIDATE_AKEY = 86;
int RIL_REQUEST_CDMA_SEND_SMS = 87;
int RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE = 88;
- int RIL_REQUEST_GET_BROADCAST_CONFIG = 89;
- int RIL_REQUEST_SET_BROADCAST_CONFIG = 90;
- int RIL_REQUEST_BROADCAST_ACTIVATION = 91;
+ int RIL_REQUEST_GSM_GET_BROADCAST_CONFIG = 89;
+ int RIL_REQUEST_GSM_SET_BROADCAST_CONFIG = 90;
+ int RIL_REQUEST_GSM_BROADCAST_ACTIVATION = 91;
int RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG = 92;
int RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG = 93;
int RIL_REQUEST_CDMA_BROADCAST_ACTIVATION = 94;
@@ -208,8 +216,11 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM = 96;
int RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM = 97;
int RIL_REQUEST_DEVICE_IDENTITY = 98;
+ int RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE = 99;
int RIL_REQUEST_GET_SMSC_ADDRESS = 100;
int RIL_REQUEST_SET_SMSC_ADDRESS = 101;
+ int RIL_REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
+ int RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index f2bd361..890ea63 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -20,11 +20,13 @@ import android.app.Activity;
import android.app.PendingIntent;
import android.app.AlertDialog;
import android.app.PendingIntent.CanceledException;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.DialogInterface;
+import android.content.IntentFilter;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
@@ -32,6 +34,7 @@ import android.net.Uri;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
+import android.os.PowerManager;
import android.provider.Telephony;
import android.provider.Telephony.Sms.Intents;
import android.provider.Settings;
@@ -75,6 +78,7 @@ public abstract class SMSDispatcher extends Handler {
protected static final String[] RAW_PROJECTION = new String[] {
"pdu",
"sequence",
+ "destination_port",
};
static final int MAIL_SEND_SMS = 1;
@@ -113,7 +117,7 @@ public abstract class SMSDispatcher extends Handler {
/** Maximum number of times to retry sending a failed SMS. */
private static final int MAX_SEND_RETRIES = 3;
/** Delay before next send attempt on a failed SMS, in milliseconds. */
- private static final int SEND_RETRY_DELAY = 2000;
+ private static final int SEND_RETRY_DELAY = 2000;
/** single part SMS */
private static final int SINGLE_PART_SMS = 1;
@@ -122,15 +126,30 @@ public abstract class SMSDispatcher extends Handler {
* CONCATENATED_16_BIT_REFERENCE message set. Should be
* incremented for each set of concatenated messages.
*/
- protected static int sConcatenatedRef;
+ private static int sConcatenatedRef;
private SmsCounter mCounter;
private SmsTracker mSTracker;
+ /** Wake lock to ensure device stays awake while dispatching the SMS intent. */
+ private PowerManager.WakeLock mWakeLock;
+
+ /**
+ * Hold the wake lock for 5 seconds, which should be enough time for
+ * any receiver(s) to grab its own wake lock.
+ */
+ private final int WAKE_LOCK_TIMEOUT = 5000;
+
private static SmsMessage mSmsMessage;
private static SmsMessageBase mSmsMessageBase;
private SmsMessageBase.SubmitPduBase mSubmitPduBase;
+ private boolean mStorageAvailable = true;
+
+ protected static int getNextConcatenatedRef() {
+ sConcatenatedRef += 1;
+ return sConcatenatedRef;
+ }
/**
* Implement the per-application based SMS control, which only allows
@@ -155,11 +174,11 @@ public abstract class SMSDispatcher extends Handler {
/**
* Check to see if an application allow to send new SMS messages
- *
+ *
* @param appName is the application sending sms
* @param smsWaiting is the number of new sms wants to be sent
- * @return true if application is allowed to send the requested number
- * of new sms messages
+ * @return true if application is allowed to send the requested number
+ * of new sms messages
*/
boolean check(String appName, int smsWaiting) {
if (!mSmsStamp.containsKey(appName)) {
@@ -178,7 +197,7 @@ public abstract class SMSDispatcher extends Handler {
sent.remove(0);
}
-
+
if ( (sent.size() + smsWaiting) <= mMaxAllowed) {
for (int i = 0; i < smsWaiting; i++ ) {
sent.add(ct);
@@ -191,14 +210,16 @@ public abstract class SMSDispatcher extends Handler {
protected SMSDispatcher(PhoneBase phone) {
mPhone = phone;
- mWapPush = new WapPushOverSms(phone);
+ mWapPush = new WapPushOverSms(phone, this);
mContext = phone.getContext();
mResolver = mContext.getContentResolver();
mCm = phone.mCM;
mSTracker = null;
+ createWakelock();
+
int check_period = Settings.Gservices.getInt(mResolver,
- Settings.Gservices.SMS_OUTGOING_CEHCK_INTERVAL_MS,
+ Settings.Gservices.SMS_OUTGOING_CHECK_INTERVAL_MS,
DEFAULT_SMS_CHECK_PERIOD);
int max_count = Settings.Gservices.getInt(mResolver,
Settings.Gservices.SMS_OUTGOING_CEHCK_MAX_COUNT,
@@ -211,6 +232,15 @@ public abstract class SMSDispatcher extends Handler {
// Don't always start message ref at 0.
sConcatenatedRef = new Random().nextInt(256);
+
+ // Register for device storage intents. Use these to notify the RIL
+ // that storage for SMS is or is not available.
+ // TODO: Revisit this for a later release. Storage reporting should
+ // rely more on application indication.
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW);
+ filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
+ mContext.registerReceiver(mResultReceiver, filter);
}
public void dispose() {
@@ -252,16 +282,27 @@ public abstract class SMSDispatcher extends Handler {
ar = (AsyncResult) msg.obj;
- // FIXME only acknowledge on store
- acknowledgeLastIncomingSms(true, null);
-
if (ar.exception != null) {
Log.e(TAG, "Exception processing incoming SMS. Exception:" + ar.exception);
return;
}
sms = (SmsMessage) ar.result;
- dispatchMessage(sms.mWrappedSmsMessage);
+ try {
+ if (mStorageAvailable) {
+ int result = dispatchMessage(sms.mWrappedSmsMessage);
+ if (result != Activity.RESULT_OK) {
+ // RESULT_OK means that message was broadcast for app(s) to handle.
+ // Any other result, we should ack here.
+ boolean handled = (result == Intents.RESULT_SMS_HANDLED);
+ acknowledgeLastIncomingSms(handled, result, null);
+ }
+ } else {
+ acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_OUT_OF_MEMORY, null);
+ }
+ } catch (RuntimeException ex) {
+ acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
+ }
break;
@@ -298,13 +339,35 @@ public abstract class SMSDispatcher extends Handler {
sendMultipartSms(mSTracker);
} else {
sendSms(mSTracker);
- }
+ }
mSTracker = null;
}
break;
}
}
+ private void createWakelock() {
+ PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SMSDispatcher");
+ mWakeLock.setReferenceCounted(true);
+ }
+
+ /**
+ * Grabs a wake lock and sends intent as an ordered broadcast.
+ * The resultReceiver will check for errors and ACK/NACK back
+ * to the RIL.
+ *
+ * @param intent intent to broadcast
+ * @param permission Receivers are required to have this permission
+ */
+ void dispatch(Intent intent, String permission) {
+ // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
+ // receivers time to take their own wake locks.
+ mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
+ mContext.sendOrderedBroadcast(intent, permission, mResultReceiver,
+ this, Activity.RESULT_OK, null, null);
+ }
+
/**
* Called when SIM_FULL message is received from the RIL. Notifies interested
* parties that SIM storage for SMS messages is full.
@@ -312,7 +375,8 @@ public abstract class SMSDispatcher extends Handler {
private void handleIccFull(){
// broadcast SIM_FULL intent
Intent intent = new Intent(Intents.SIM_FULL_ACTION);
- mPhone.getContext().sendBroadcast(intent, "android.permission.RECEIVE_SMS");
+ mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
+ mContext.sendBroadcast(intent, "android.permission.RECEIVE_SMS");
}
/**
@@ -412,19 +476,28 @@ public abstract class SMSDispatcher extends Handler {
* Dispatches an incoming SMS messages.
*
* @param sms the incoming message from the phone
+ * @return a result code from {@link Telephony.Sms.Intents}, or
+ * {@link Activity#RESULT_OK} if the message has been broadcast
+ * to applications
*/
- protected abstract void dispatchMessage(SmsMessageBase sms);
+ protected abstract int dispatchMessage(SmsMessageBase sms);
/**
* If this is the last part send the parts out to the application, otherwise
* the part is stored for later processing.
+ *
+ * NOTE: concatRef (naturally) needs to be non-null, but portAddrs can be null.
+ * @return a result code from {@link Telephony.Sms.Intents}, or
+ * {@link Activity#RESULT_OK} if the message has been broadcast
+ * to applications
*/
- protected void processMessagePart(SmsMessageBase sms, int referenceNumber,
- int sequence, int count, int destinationPort) {
+ protected int processMessagePart(SmsMessageBase sms,
+ SmsHeader.ConcatRef concatRef, SmsHeader.PortAddrs portAddrs) {
+
// Lookup all other related parts
StringBuilder where = new StringBuilder("reference_number =");
- where.append(referenceNumber);
+ where.append(concatRef.refNumber);
where.append(" AND address = ?");
String[] whereArgs = new String[] {sms.getOriginatingAddress()};
@@ -433,28 +506,27 @@ public abstract class SMSDispatcher extends Handler {
try {
cursor = mResolver.query(mRawUri, RAW_PROJECTION, where.toString(), whereArgs, null);
int cursorCount = cursor.getCount();
- if (cursorCount != count - 1) {
+ if (cursorCount != concatRef.msgCount - 1) {
// We don't have all the parts yet, store this one away
ContentValues values = new ContentValues();
values.put("date", new Long(sms.getTimestampMillis()));
values.put("pdu", HexDump.toHexString(sms.getPdu()));
values.put("address", sms.getOriginatingAddress());
- values.put("reference_number", referenceNumber);
- values.put("count", count);
- values.put("sequence", sequence);
- if (destinationPort != -1) {
- values.put("destination_port", destinationPort);
+ values.put("reference_number", concatRef.refNumber);
+ values.put("count", concatRef.msgCount);
+ values.put("sequence", concatRef.seqNumber);
+ if (portAddrs != null) {
+ values.put("destination_port", portAddrs.destPort);
}
mResolver.insert(mRawUri, values);
-
- return;
+ return Intents.RESULT_SMS_HANDLED;
}
// All the parts are in place, deal with them
int pduColumn = cursor.getColumnIndex("pdu");
int sequenceColumn = cursor.getColumnIndex("sequence");
- pdus = new byte[count][];
+ pdus = new byte[concatRef.msgCount][];
for (int i = 0; i < cursorCount; i++) {
cursor.moveToNext();
int cursorSequence = (int)cursor.getLong(sequenceColumn);
@@ -462,43 +534,48 @@ public abstract class SMSDispatcher extends Handler {
cursor.getString(pduColumn));
}
// This one isn't in the DB, so add it
- pdus[sequence - 1] = sms.getPdu();
+ pdus[concatRef.seqNumber - 1] = sms.getPdu();
// Remove the parts from the database
mResolver.delete(mRawUri, where.toString(), whereArgs);
} catch (SQLException e) {
Log.e(TAG, "Can't access multipart SMS database", e);
- return; // TODO: NACK the message or something, don't just discard.
+ // TODO: Would OUT_OF_MEMORY be more appropriate?
+ return Intents.RESULT_SMS_GENERIC_ERROR;
} finally {
if (cursor != null) cursor.close();
}
+ /**
+ * TODO(cleanup): The following code has duplicated logic with
+ * the radio-specific dispatchMessage code, which is fragile,
+ * in addition to being redundant. Instead, if this method
+ * maybe returned the reassembled message (or just contents),
+ * the following code (which is not really related to
+ * reconstruction) could be better consolidated.
+ */
+
// Dispatch the PDUs to applications
- switch (destinationPort) {
- case SmsHeader.PORT_WAP_PUSH: {
- // Build up the data stream
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- for (int i = 0; i < count; i++) {
- SmsMessage msg = SmsMessage.createFromPdu(pdus[i]);
- byte[] data = msg.getUserData();
- output.write(data, 0, data.length);
+ if (portAddrs != null) {
+ if (portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) {
+ // Build up the data stream
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ for (int i = 0; i < concatRef.msgCount; i++) {
+ SmsMessage msg = SmsMessage.createFromPdu(pdus[i]);
+ byte[] data = msg.getUserData();
+ output.write(data, 0, data.length);
+ }
+ // Handle the PUSH
+ return mWapPush.dispatchWapPdu(output.toByteArray());
+ } else {
+ // The messages were sent to a port, so concoct a URI for it
+ dispatchPortAddressedPdus(pdus, portAddrs.destPort);
}
-
- // Handle the PUSH
- mWapPush.dispatchWapPdu(output.toByteArray());
- break;
- }
-
- case -1:
+ } else {
// The messages were not sent to a port
dispatchPdus(pdus);
- break;
-
- default:
- // The messages were sent to a port, so concoct a URI for it
- dispatchPortAddressedPdus(pdus, destinationPort);
- break;
}
+ return Activity.RESULT_OK;
}
/**
@@ -509,8 +586,7 @@ public abstract class SMSDispatcher extends Handler {
protected void dispatchPdus(byte[][] pdus) {
Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);
intent.putExtra("pdus", pdus);
- mPhone.getContext().sendBroadcast(
- intent, "android.permission.RECEIVE_SMS");
+ dispatch(intent, "android.permission.RECEIVE_SMS");
}
/**
@@ -523,8 +599,7 @@ public abstract class SMSDispatcher extends Handler {
Uri uri = Uri.parse("sms://localhost:" + port);
Intent intent = new Intent(Intents.DATA_SMS_RECEIVED_ACTION, uri);
intent.putExtra("pdus", pdus);
- mPhone.getContext().sendBroadcast(
- intent, "android.permission.RECEIVE_SMS");
+ dispatch(intent, "android.permission.RECEIVE_SMS");
}
@@ -649,7 +724,7 @@ public abstract class SMSDispatcher extends Handler {
/**
* Send the multi-part SMS based on multipart Sms tracker
- *
+ *
* @param tracker holds the multipart Sms tracker ready to be sent
*/
protected abstract void sendMultipartSms (SmsTracker tracker);
@@ -688,13 +763,15 @@ public abstract class SMSDispatcher extends Handler {
/**
* Send an acknowledge message.
* @param success indicates that last message was successfully received.
+ * @param result result code indicating any error
* @param response callback message sent when operation completes.
*/
- protected abstract void acknowledgeLastIncomingSms(boolean success, Message response);
+ protected abstract void acknowledgeLastIncomingSms(boolean success,
+ int result, Message response);
/**
* Check if a SmsTracker holds multi-part Sms
- *
+ *
* @param tracker a SmsTracker could hold a multi-part Sms
* @return true for tracker holds Multi-parts Sms
*/
@@ -725,7 +802,7 @@ public abstract class SMSDispatcher extends Handler {
mRetryCount = 0;
}
}
-
+
protected SmsTracker SmsTrackerFactory(HashMap data, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
return new SmsTracker(data, sentIntent, deliveryIntent);
@@ -741,4 +818,28 @@ public abstract class SMSDispatcher extends Handler {
}
}
};
+
+ private BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_LOW)) {
+ mStorageAvailable = false;
+ mCm.reportSmsMemoryStatus(false, null);
+ } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_OK)) {
+ mStorageAvailable = true;
+ mCm.reportSmsMemoryStatus(true, null);
+ } else {
+ // Assume the intent is one of the SMS receive intents that
+ // was sent as an ordered broadcast. Check result and ACK.
+ int rc = getResultCode();
+ boolean success = (rc == Activity.RESULT_OK)
+ || (rc == Intents.RESULT_SMS_HANDLED);
+
+ // For a multi-part message, this only ACKs the last part.
+ // Previous parts were ACK'd as they were received.
+ acknowledgeLastIncomingSms(success, rc, null);
+ }
+ }
+
+ };
}
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 7274e99..bdcf3f7 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -22,6 +22,7 @@ import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
/**
* {@hide}
@@ -50,6 +51,8 @@ public abstract class ServiceStateTracker extends Handler {
public ServiceState ss;
protected ServiceState newSS;
+ public SignalStrength mSignalStrength;
+
// Used as a unique identifier to track requests associated with a poll
// and ignore stale responses.The value is a count-down of expected responses
// in this pollingContext
@@ -104,13 +107,15 @@ public abstract class ServiceStateTracker extends Handler {
protected static final int EVENT_POLL_STATE_OPERATOR_CDMA = 25;
protected static final int EVENT_RUIM_READY = 26;
protected static final int EVENT_RUIM_RECORDS_LOADED = 27;
- protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE_CDMA = 28;
- protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA = 29;
- protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA = 30;
- protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA = 31;
- protected static final int EVENT_GET_LOC_DONE_CDMA = 32;
- protected static final int EVENT_SIGNAL_STRENGTH_UPDATE_CDMA = 33;
- protected static final int EVENT_NV_LOADED = 34;
+ protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA = 28;
+ protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA = 29;
+ protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA = 30;
+ protected static final int EVENT_GET_LOC_DONE_CDMA = 31;
+ protected static final int EVENT_SIGNAL_STRENGTH_UPDATE_CDMA = 32;
+ protected static final int EVENT_NV_LOADED = 33;
+ protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION = 34;
+ protected static final int EVENT_NV_READY = 35;
+ protected static final int EVENT_ERI_FILE_LOADED = 36;
//***** Time Zones
protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
@@ -142,12 +147,18 @@ public abstract class ServiceStateTracker extends Handler {
"uk", // U.K
};
+ //***** Registration denied reason
+ protected static final String REGISTRATION_DENIED_GEN = "General";
+ protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
//***** Constructors
public ServiceStateTracker() {
}
+ public boolean getDesiredPowerState() {
+ return mDesiredPowerState;
+ }
/**
* Registration point for combined roaming on
diff --git a/telephony/java/com/android/internal/telephony/SmsHeader.java b/telephony/java/com/android/internal/telephony/SmsHeader.java
index 64b884e..7872eec 100644
--- a/telephony/java/com/android/internal/telephony/SmsHeader.java
+++ b/telephony/java/com/android/internal/telephony/SmsHeader.java
@@ -16,227 +16,242 @@
package com.android.internal.telephony;
+import android.telephony.SmsMessage;
+
import com.android.internal.util.HexDump;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
import java.util.ArrayList;
/**
- * This class represents a SMS user data header.
- *
+ * SMS user data header, as specified in TS 23.040 9.2.3.24.
*/
public class SmsHeader {
- /** See TS 23.040 9.2.3.24 for description of this element ID. */
- public static final int CONCATENATED_8_BIT_REFERENCE = 0x00;
- /** See TS 23.040 9.2.3.24 for description of this element ID. */
- public static final int SPECIAL_SMS_MESSAGE_INDICATION = 0x01;
- /** See TS 23.040 9.2.3.24 for description of this element ID. */
- public static final int APPLICATION_PORT_ADDRESSING_8_BIT = 0x04;
- /** See TS 23.040 9.2.3.24 for description of this element ID. */
- public static final int APPLICATION_PORT_ADDRESSING_16_BIT= 0x05;
- /** See TS 23.040 9.2.3.24 for description of this element ID. */
- public static final int CONCATENATED_16_BIT_REFERENCE = 0x08;
- public static final int PORT_WAP_PUSH = 2948;
- public static final int PORT_WAP_WSP = 9200;
+ // TODO(cleanup): this datastructure is generally referred to as
+ // the 'user data header' or UDH, and so the class name should
+ // change to reflect this...
- private byte[] m_data;
- private ArrayList<Element> m_elements = new ArrayList<Element>();
- public int nbrOfHeaders;
-
- /**
- * Creates an SmsHeader object from raw user data header bytes.
- *
- * @param data is user data header bytes
- * @return an SmsHeader object
+ /** SMS user data header information element identifiers.
+ * (see TS 23.040 9.2.3.24)
*/
- public static SmsHeader parse(byte[] data) {
- SmsHeader header = new SmsHeader();
- header.m_data = data;
-
- int index = 0;
- header.nbrOfHeaders = 0;
- while (index < data.length) {
- int id = data[index++] & 0xff;
- int length = data[index++] & 0xff;
- byte[] elementData = new byte[length];
- System.arraycopy(data, index, elementData, 0, length);
- header.add(new Element(id, elementData));
- index += length;
- header.nbrOfHeaders++;
- }
+ public static final int ELT_ID_CONCATENATED_8_BIT_REFERENCE = 0x00;
+ public static final int ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION = 0x01;
+ public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT = 0x04;
+ public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT = 0x05;
+ public static final int ELT_ID_SMSC_CONTROL_PARAMS = 0x06;
+ public static final int ELT_ID_UDH_SOURCE_INDICATION = 0x07;
+ public static final int ELT_ID_CONCATENATED_16_BIT_REFERENCE = 0x08;
+ public static final int ELT_ID_WIRELESS_CTRL_MSG_PROTOCOL = 0x09;
+ public static final int ELT_ID_TEXT_FORMATTING = 0x0A;
+ public static final int ELT_ID_PREDEFINED_SOUND = 0x0B;
+ public static final int ELT_ID_USER_DEFINED_SOUND = 0x0C;
+ public static final int ELT_ID_PREDEFINED_ANIMATION = 0x0D;
+ public static final int ELT_ID_LARGE_ANIMATION = 0x0E;
+ public static final int ELT_ID_SMALL_ANIMATION = 0x0F;
+ public static final int ELT_ID_LARGE_PICTURE = 0x10;
+ public static final int ELT_ID_SMALL_PICTURE = 0x11;
+ public static final int ELT_ID_VARIABLE_PICTURE = 0x12;
+ public static final int ELT_ID_USER_PROMPT_INDICATOR = 0x13;
+ public static final int ELT_ID_EXTENDED_OBJECT = 0x14;
+ public static final int ELT_ID_REUSED_EXTENDED_OBJECT = 0x15;
+ public static final int ELT_ID_COMPRESSION_CONTROL = 0x16;
+ public static final int ELT_ID_OBJECT_DISTR_INDICATOR = 0x17;
+ public static final int ELT_ID_STANDARD_WVG_OBJECT = 0x18;
+ public static final int ELT_ID_CHARACTER_SIZE_WVG_OBJECT = 0x19;
+ public static final int ELT_ID_EXTENDED_OBJECT_DATA_REQUEST_CMD = 0x1A;
+ public static final int ELT_ID_RFC_822_EMAIL_HEADER = 0x20;
+ public static final int ELT_ID_HYPERLINK_FORMAT_ELEMENT = 0x21;
+ public static final int ELT_ID_REPLY_ADDRESS_ELEMENT = 0x22;
+ public static final int ELT_ID_ENHANCED_VOICE_MAIL_INFORMATION = 0x23;
- return header;
- }
+ public static final int PORT_WAP_PUSH = 2948;
+ public static final int PORT_WAP_WSP = 9200;
- public SmsHeader() { }
+ public static class PortAddrs {
+ public int destPort;
+ public int origPort;
+ public boolean areEightBits;
+ }
- /**
- * Returns the list of SmsHeader Elements that make up the header.
- *
- * @return the list of SmsHeader Elements.
- */
- public ArrayList<Element> getElements() {
- return m_elements;
+ public static class ConcatRef {
+ public int refNumber;
+ public int seqNumber;
+ public int msgCount;
+ public boolean isEightBits;
}
/**
- * Add an element to the SmsHeader.
- *
- * @param element to add.
+ * A header element that is not explicitly parsed, meaning not
+ * PortAddrs or ConcatRef.
*/
- public void add(Element element) {
- m_elements.add(element);
+ public static class MiscElt {
+ public int id;
+ public byte[] data;
}
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
-
- builder.append("UDH LENGTH: " + m_data.length + " octets");
- builder.append("UDH: ");
- builder.append(HexDump.toHexString(m_data));
- builder.append("\n");
-
- for (Element e : getElements()) {
- builder.append(" 0x" + HexDump.toHexString((byte)e.getID()) + " - ");
- switch (e.getID()) {
- case CONCATENATED_8_BIT_REFERENCE: {
- builder.append("Concatenated Short Message 8bit ref\n");
- byte[] data = e.getData();
- builder.append(" " + data.length + " (0x");
- builder.append(HexDump.toHexString((byte)data.length)
- + ") Bytes - Information Element\n");
- builder.append(" " + data[0] + " : SM reference number\n");
- builder.append(" " + data[1] + " : number of messages\n");
- builder.append(" " + data[2] + " : this SM sequence number\n");
- break;
- }
-
- case CONCATENATED_16_BIT_REFERENCE: {
- builder.append("Concatenated Short Message 16bit ref\n");
- byte[] data = e.getData();
- builder.append(" " + data.length + " (0x");
- builder.append(HexDump.toHexString((byte)data.length)
- + ") Bytes - Information Element\n");
- builder.append(" " + (data[0] & 0xff) * 256 + (data[1] & 0xff)
- + " : SM reference number\n");
- builder.append(" " + data[2] + " : number of messages\n");
- builder.append(" " + data[3] + " : this SM sequence number\n");
- break;
- }
-
- case APPLICATION_PORT_ADDRESSING_8_BIT:
- {
- builder.append("Application port addressing 8bit\n");
- byte[] data = e.getData();
-
- builder.append(" " + data.length + " (0x");
- builder.append(HexDump.toHexString(
- (byte)data.length) + ") Bytes - Information Element\n");
-
- int source = (data[0] & 0xff);
- builder.append(" " + source + " : DESTINATION port\n");
-
- int dest = (data[1] & 0xff);
- builder.append(" " + dest + " : SOURCE port\n");
- break;
- }
-
- case APPLICATION_PORT_ADDRESSING_16_BIT: {
- builder.append("Application port addressing 16bit\n");
- byte[] data = e.getData();
-
- builder.append(" " + data.length + " (0x");
- builder.append(HexDump.toHexString((byte)data.length)
- + ") Bytes - Information Element\n");
+ public PortAddrs portAddrs;
+ public ConcatRef concatRef;
+ public ArrayList<MiscElt> miscEltList = new ArrayList<MiscElt>();
- int source = (data[0] & 0xff) << 8;
- source |= (data[1] & 0xff);
- builder.append(" " + source + " : DESTINATION port\n");
+ public SmsHeader() {}
- int dest = (data[2] & 0xff) << 8;
- dest |= (data[3] & 0xff);
- builder.append(" " + dest + " : SOURCE port\n");
- break;
+ /**
+ * Create structured SmsHeader object from serialized byte array representation.
+ * (see TS 23.040 9.2.3.24)
+ * @param data is user data header bytes
+ * @return SmsHeader object
+ */
+ public static SmsHeader fromByteArray(byte[] data) {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(data);
+ SmsHeader smsHeader = new SmsHeader();
+ while (inStream.available() > 0) {
+ /**
+ * NOTE: as defined in the spec, ConcatRef and PortAddr
+ * fields should not reoccur, but if they do the last
+ * occurrence is to be used. Also, for ConcatRef
+ * elements, if the count is zero, sequence is zero, or
+ * sequence is larger than count, the entire element is to
+ * be ignored.
+ */
+ int id = inStream.read();
+ int length = inStream.read();
+ ConcatRef concatRef;
+ PortAddrs portAddrs;
+ switch (id) {
+ case ELT_ID_CONCATENATED_8_BIT_REFERENCE:
+ concatRef = new ConcatRef();
+ concatRef.refNumber = inStream.read();
+ concatRef.msgCount = inStream.read();
+ concatRef.seqNumber = inStream.read();
+ concatRef.isEightBits = true;
+ if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 &&
+ concatRef.seqNumber <= concatRef.msgCount) {
+ smsHeader.concatRef = concatRef;
}
-
- default: {
- builder.append("Unknown element\n");
- break;
+ break;
+ case ELT_ID_CONCATENATED_16_BIT_REFERENCE:
+ concatRef = new ConcatRef();
+ concatRef.refNumber = (inStream.read() << 8) | inStream.read();
+ concatRef.msgCount = inStream.read();
+ concatRef.seqNumber = inStream.read();
+ concatRef.isEightBits = false;
+ if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 &&
+ concatRef.seqNumber <= concatRef.msgCount) {
+ smsHeader.concatRef = concatRef;
}
+ break;
+ case ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT:
+ portAddrs = new PortAddrs();
+ portAddrs.destPort = inStream.read();
+ portAddrs.origPort = inStream.read();
+ portAddrs.areEightBits = true;
+ smsHeader.portAddrs = portAddrs;
+ break;
+ case ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT:
+ portAddrs = new PortAddrs();
+ portAddrs.destPort = (inStream.read() << 8) | inStream.read();
+ portAddrs.origPort = (inStream.read() << 8) | inStream.read();
+ portAddrs.areEightBits = false;
+ smsHeader.portAddrs = portAddrs;
+ break;
+ default:
+ MiscElt miscElt = new MiscElt();
+ miscElt.id = id;
+ miscElt.data = new byte[length];
+ inStream.read(miscElt.data, 0, length);
+ smsHeader.miscEltList.add(miscElt);
}
}
-
- return builder.toString();
- }
-
- private int calcSize() {
- int size = 1; // +1 for the UDHL field
- for (Element e : m_elements) {
- size += e.getData().length;
- size += 2; // 1 byte ID, 1 byte length
- }
-
- return size;
+ return smsHeader;
}
/**
- * Converts SmsHeader object to a byte array as specified in TS 23.040 9.2.3.24.
+ * Create serialized byte array representation from structured SmsHeader object.
+ * (see TS 23.040 9.2.3.24)
* @return Byte array representing the SmsHeader
*/
- public byte[] toByteArray() {
- if (m_elements.size() == 0) return null;
-
- if (m_data == null) {
- int size = calcSize();
- int cur = 1;
- m_data = new byte[size];
-
- m_data[0] = (byte) (size-1); // UDHL does not include itself
-
- for (Element e : m_elements) {
- int length = e.getData().length;
- m_data[cur++] = (byte) e.getID();
- m_data[cur++] = (byte) length;
- System.arraycopy(e.getData(), 0, m_data, cur, length);
- cur += length;
- }
+ public static byte[] toByteArray(SmsHeader smsHeader) {
+ if ((smsHeader.portAddrs == null) &&
+ (smsHeader.concatRef == null) &&
+ (smsHeader.miscEltList.size() == 0)) {
+ return null;
}
- return m_data;
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream(SmsMessage.MAX_USER_DATA_BYTES);
+ ConcatRef concatRef = smsHeader.concatRef;
+ if (concatRef != null) {
+ if (concatRef.isEightBits) {
+ outStream.write(ELT_ID_CONCATENATED_8_BIT_REFERENCE);
+ outStream.write(3);
+ outStream.write(concatRef.refNumber);
+ } else {
+ outStream.write(ELT_ID_CONCATENATED_16_BIT_REFERENCE);
+ outStream.write(4);
+ outStream.write(concatRef.refNumber >>> 8);
+ outStream.write(concatRef.refNumber & 0x00FF);
+ }
+ outStream.write(concatRef.msgCount);
+ outStream.write(concatRef.seqNumber);
+ }
+ PortAddrs portAddrs = smsHeader.portAddrs;
+ if (portAddrs != null) {
+ if (portAddrs.areEightBits) {
+ outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT);
+ outStream.write(2);
+ outStream.write(portAddrs.destPort);
+ outStream.write(portAddrs.origPort);
+ } else {
+ outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT);
+ outStream.write(4);
+ outStream.write(portAddrs.destPort >>> 8);
+ outStream.write(portAddrs.destPort & 0x00FF);
+ outStream.write(portAddrs.origPort >>> 8);
+ outStream.write(portAddrs.origPort & 0x00FF);
+ }
+ }
+ for (MiscElt miscElt : smsHeader.miscEltList) {
+ outStream.write(miscElt.id);
+ outStream.write(miscElt.data.length);
+ outStream.write(miscElt.data, 0, miscElt.data.length);
+ }
+ return outStream.toByteArray();
}
- /**
- * A single Element in the SMS User Data Header.
- *
- * See TS 23.040 9.2.3.24.
- *
- */
- public static class Element {
- private byte[] m_data;
- private int m_id;
-
- public Element(int id, byte[] data) {
- m_id = id;
- m_data = data;
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("UserDataHeader ");
+ builder.append("{ ConcatRef ");
+ if (concatRef == null) {
+ builder.append("unset");
+ } else {
+ builder.append("{ refNumber=" + concatRef.refNumber);
+ builder.append(", msgCount=" + concatRef.msgCount);
+ builder.append(", seqNumber=" + concatRef.seqNumber);
+ builder.append(", isEightBits=" + concatRef.isEightBits);
+ builder.append(" }");
}
-
- /**
- * Returns the Information Element Identifier for this element.
- *
- * @return the IE identifier.
- */
- public int getID() {
- return m_id;
+ builder.append(", PortAddrs ");
+ if (portAddrs == null) {
+ builder.append("unset");
+ } else {
+ builder.append("{ destPort=" + portAddrs.destPort);
+ builder.append(", origPort=" + portAddrs.origPort);
+ builder.append(", areEightBits=" + portAddrs.areEightBits);
+ builder.append(" }");
}
-
- /**
- * Returns the data portion of this element.
- *
- * @return element data.
- */
- public byte[] getData() {
- return m_data;
+ for (MiscElt miscElt : miscEltList) {
+ builder.append(", MiscElt ");
+ builder.append("{ id=" + miscElt.id);
+ builder.append(", length=" + miscElt.data.length);
+ builder.append(", data=" + HexDump.toHexString(miscElt.data));
+ builder.append(" }");
}
+ builder.append(" }");
+ return builder.toString();
}
+
}
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index 1aad38d..3c7dd45 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -86,6 +86,38 @@ public abstract class SmsMessageBase {
/** TP-Message-Reference - Message Reference of sent message. @hide */
public int messageRef;
+ /**
+ * For a specific text string, this object describes protocol
+ * properties of encoding it for transmission as message user
+ * data.
+ */
+ public static class TextEncodingDetails {
+ /**
+ *The number of SMS's required to encode the text.
+ */
+ public int msgCount;
+
+ /**
+ * The number of code units consumed so far, where code units
+ * are basically characters in the encoding -- for example,
+ * septets for the standard ASCII and GSM encodings, and 16
+ * bits for Unicode.
+ */
+ public int codeUnitCount;
+
+ /**
+ * How many code units are still available without spilling
+ * into an additional message.
+ */
+ public int codeUnitsRemaining;
+
+ /**
+ * The encoding code unit size (specified using
+ * android.telephony.SmsMessage ENCODING_*).
+ */
+ public int codeUnitSize;
+ }
+
public static abstract class SubmitPduBase {
public byte[] encodedScAddress; // Null if not applicable.
public byte[] encodedMessage;
@@ -245,8 +277,6 @@ public abstract class SmsMessageBase {
/**
* Returns an object representing the user data header
*
- * @return an object representing the user data header
- *
* {@hide}
*/
public SmsHeader getUserDataHeader() {
@@ -254,9 +284,14 @@ public abstract class SmsMessageBase {
}
/**
+ * TODO(cleanup): The term PDU is used in a seemingly non-unique
+ * manner -- for example, what is the difference between this byte
+ * array and the contents of SubmitPdu objects. Maybe a more
+ * illustrative term would be appropriate.
+ */
+
+ /**
* Returns the raw PDU for the message.
- *
- * @return the raw PDU for the message.
*/
public byte[] getPdu() {
return mPdu;
@@ -309,7 +344,9 @@ public abstract class SmsMessageBase {
}
protected void parseMessageBody() {
- if (originatingAddress.couldBeEmailGateway()) {
+ // originatingAddress could be null if this message is from a status
+ // report.
+ if (originatingAddress != null && originatingAddress.couldBeEmailGateway()) {
extractEmailAddressFromMessageBody();
}
}
diff --git a/telephony/java/com/android/internal/telephony/SmsResponse.java b/telephony/java/com/android/internal/telephony/SmsResponse.java
index 3c4df56..bd79e02 100644
--- a/telephony/java/com/android/internal/telephony/SmsResponse.java
+++ b/telephony/java/com/android/internal/telephony/SmsResponse.java
@@ -26,9 +26,15 @@ public class SmsResponse {
int messageRef;
/** ackPdu for the just-sent SMS. */
String ackPdu;
+ /**
+ * errorCode: See 3GPP 27.005, 3.2.5 for GSM/UMTS,
+ * 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
+ */
+ int errorCode;
- public SmsResponse(int messageRef, String ackPdu) {
+ public SmsResponse(int messageRef, String ackPdu, int errorCode) {
this.messageRef = messageRef;
this.ackPdu = ackPdu;
+ this.errorCode = errorCode;
}
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyEventLog.java b/telephony/java/com/android/internal/telephony/TelephonyEventLog.java
index 97f9d7d..cdce488 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyEventLog.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyEventLog.java
@@ -30,4 +30,6 @@ public final class TelephonyEventLog {
public static final int EVENT_LOG_CGREG_FAIL = 50107;
public static final int EVENT_LOG_DATA_STATE_RADIO_OFF = 50108;
public static final int EVENT_LOG_PDP_NETWORK_DROP = 50109;
+ public static final int EVENT_LOG_CDMA_DATA_SETUP_FAILED = 50110;
+ public static final int EVENT_LOG_CDMA_DATA_DROP = 50111;
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index c342233..9152211 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -51,9 +51,24 @@ public class TelephonyIntents {
* <p class="note">
* Requires no permission.
*/
- public static final String ACTION_RADIO_TECHNOLOGY_CHANGED
+ public static final String ACTION_RADIO_TECHNOLOGY_CHANGED
= "android.intent.action.RADIO_TECHNOLOGY";
-
+ /**
+ * <p>Broadcast Action: The emergency callback mode is changed.
+ * <ul>
+ * <li><em>phoneinECMState</em> - A boolean value,true=phone in ECM, false=ECM off</li>
+ * </ul>
+ * <p class="note">
+ * You can <em>not</em> receive this through components declared
+ * in manifests, only by explicitly registering for it with
+ * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver,
+ * android.content.IntentFilter) Context.registerReceiver()}.
+ *
+ * <p class="note">
+ * Requires no permission.
+ */
+ public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
+ = "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED";
/**
* Broadcast Action: The phone's signal strength has changed. The intent will have the
* following extra values:</p>
@@ -166,4 +181,34 @@ public class TelephonyIntents {
*/
public static final String ACTION_NETWORK_SET_TIMEZONE
= "android.intent.action.NETWORK_SET_TIMEZONE";
+
+ /**
+ * <p>Broadcast Action: It indicates the Emergency callback mode blocks datacall/sms
+ * <p class="note">.
+ * This is to pop up a notice to show user that the phone is in emergency callback mode
+ * and atacalls and outgoing sms are blocked.
+ */
+ public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS
+ = "android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS";
+
+ /**
+ * Broadcast Action: The MDN changed during the CDMA OTA Process
+ * The intent will have the following extra values:</p>
+ * <ul>
+ * <li><em>mdn</em> - An Integer of the updated MDN number.</li>
+ * </ul>
+ *
+ * <p class="note">
+ */
+ // TODO(Moto): Generally broadcast intents are for use to allow entities which
+ // may not know about each other to "communicate". This seems quite specific
+ // and maybe using the registrant style would be better.
+
+ // Moto: Since this is used for apps not in the same process of phone, can the
+ // registrant style be used? (Ling Li says: Maybe the "app" can request rather
+ // than save the MDN each time and this intent would not be necessary?)
+ // Moto response: Moto internal discussion is on-going.
+ public static final String ACTION_CDMA_OTA_MDN_CHANGED
+ = "android.intent.action.ACTION_MDN_STATE_CHANGED";
+
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index 396b42d..290e1fc 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -44,6 +44,7 @@ public interface TelephonyProperties
* Availability: when registered to a network
*/
static final String PROPERTY_OPERATOR_ALPHA = "gsm.operator.alpha";
+ //TODO: most of these proprieties are generic, substitute gsm. with phone. bug 1856959
/** Numeric name (MCC+MNC) of current registered operator.
* Availability: when registered to a network
@@ -68,6 +69,8 @@ public interface TelephonyProperties
*/
static final String PROPERTY_OPERATOR_ISO_COUNTRY = "gsm.operator.iso-country";
+ static final String CURRENT_ACTIVE_PHONE = "gsm.current.phone-type";
+
//****** SIM Card
/**
* One of <code>"UNKNOWN"</code> <code>"ABSENT"</code> <code>"PIN_REQUIRED"</code>
@@ -95,4 +98,12 @@ public interface TelephonyProperties
*/
static String PROPERTY_DATA_NETWORK_TYPE = "gsm.network.type";
+ /** Indicate if phone is in emergency callback mode */
+ static final String PROPERTY_INECM_MODE = "ril.cdma.inecmmode";
+
+ /** Indicate the timer value for exiting emergency callback mode */
+ static final String PROPERTY_ECM_EXIT_TIMER = "ro.cdma.ecmexittimer";
+
+ /** The international dialing prefix conversion string */
+ static final String PROPERTY_IDP_STRING = "ro.cdma.idpstring";
}
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
index 98899c9..9970940 100644
--- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
@@ -16,9 +16,10 @@
package com.android.internal.telephony;
+import android.app.Activity;
import android.content.Context;
import android.content.Intent;
-import android.os.PowerManager;
+import android.provider.Telephony;
import android.provider.Telephony.Sms.Intents;
import android.util.Config;
import android.util.Log;
@@ -34,18 +35,17 @@ public class WapPushOverSms {
private final Context mContext;
private WspTypeDecoder pduDecoder;
- private PowerManager.WakeLock mWakeLock;
+ private SMSDispatcher mSmsDispatcher;
/**
- * Hold the wake lock for 5 seconds, which should be enough time for
+ * Hold the wake lock for 5 seconds, which should be enough time for
* any receiver(s) to grab its own wake lock.
*/
private final int WAKE_LOCK_TIMEOUT = 5000;
- public WapPushOverSms(Phone phone) {
-
+ public WapPushOverSms(Phone phone, SMSDispatcher smsDispatcher) {
+ mSmsDispatcher = smsDispatcher;
mContext = phone.getContext();
- createWakelock();
}
/**
@@ -53,8 +53,11 @@ public class WapPushOverSms {
* wap-230-wsp-20010705-a section 8 for details on the WAP PDU format.
*
* @param pdu The WAP PDU, made up of one or more SMS PDUs
+ * @return a result code from {@link Telephony.Sms.Intents}, or
+ * {@link Activity#RESULT_OK} if the message has been broadcast
+ * to applications
*/
- public void dispatchWapPdu(byte[] pdu) {
+ public int dispatchWapPdu(byte[] pdu) {
if (Config.LOGD) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
@@ -66,7 +69,7 @@ public class WapPushOverSms {
if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
(pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
if (Config.LOGD) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
- return;
+ return Intents.RESULT_SMS_HANDLED;
}
pduDecoder = new WspTypeDecoder(pdu);
@@ -79,7 +82,7 @@ public class WapPushOverSms {
*/
if (pduDecoder.decodeUintvarInteger(index) == false) {
if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Length error.");
- return;
+ return Intents.RESULT_SMS_GENERIC_ERROR;
}
headerLength = (int)pduDecoder.getValue32();
index += pduDecoder.getDecodedDataLength();
@@ -100,7 +103,7 @@ public class WapPushOverSms {
*/
if (pduDecoder.decodeContentType(index) == false) {
if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
- return;
+ return Intents.RESULT_SMS_GENERIC_ERROR;
}
int binaryContentType;
String mimeType = pduDecoder.getValueString();
@@ -130,7 +133,7 @@ public class WapPushOverSms {
Log.w(LOG_TAG,
"Received PDU. Unsupported Content-Type = " + binaryContentType);
}
- return;
+ return Intents.RESULT_SMS_HANDLED;
}
} else {
if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML)) {
@@ -147,7 +150,7 @@ public class WapPushOverSms {
binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_MMS;
} else {
if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Unknown Content-Type = " + mimeType);
- return;
+ return Intents.RESULT_SMS_HANDLED;
}
}
index += pduDecoder.getDecodedDataLength();
@@ -169,6 +172,7 @@ public class WapPushOverSms {
if (dispatchedByApplication == false) {
dispatchWapPdu_default(pdu, transactionId, pduType, mimeType, dataIndex);
}
+ return Activity.RESULT_OK;
}
private void dispatchWapPdu_default(
@@ -184,7 +188,7 @@ public class WapPushOverSms {
intent.putExtra("pduType", pduType);
intent.putExtra("data", data);
- sendBroadcast(intent, "android.permission.RECEIVE_WAP_PUSH");
+ mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
}
private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType) {
@@ -194,7 +198,7 @@ public class WapPushOverSms {
intent.putExtra("pduType", pduType);
intent.putExtra("data", pdu);
- sendBroadcast(intent, "android.permission.RECEIVE_WAP_PUSH");
+ mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
}
private void dispatchWapPdu_MMS(byte[] pdu, int transactionId, int pduType, int dataIndex) {
@@ -209,20 +213,7 @@ public class WapPushOverSms {
intent.putExtra("pduType", pduType);
intent.putExtra("data", data);
- sendBroadcast(intent, "android.permission.RECEIVE_MMS");
- }
-
- private void createWakelock() {
- PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WapPushOverSms");
- mWakeLock.setReferenceCounted(true);
- }
-
- private void sendBroadcast(Intent intent, String permission) {
- // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
- // receivers time to take their own wake locks.
- mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
- mContext.sendBroadcast(intent, permission);
+ mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_MMS");
}
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 8ffb7ec..3362de8 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -16,7 +16,10 @@
package com.android.internal.telephony.cdma;
+import android.app.ActivityManagerNative;
import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
@@ -24,20 +27,22 @@ import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.SystemProperties;
+import android.preference.PreferenceManager;
import android.provider.Settings;
import android.telephony.CellLocation;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.text.TextUtils;
import android.util.Log;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
-
import com.android.internal.telephony.CallStateException;
+import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccException;
import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
import com.android.internal.telephony.IccSmsInterfaceManager;
@@ -48,10 +53,12 @@ import com.android.internal.telephony.PhoneNotifier;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.PhoneSubInfo;
import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
-import java.util.ArrayList;
import java.util.List;
-
+import java.util.Timer;
+import java.util.TimerTask;
/**
* {@hide}
*/
@@ -59,6 +66,12 @@ public class CDMAPhone extends PhoneBase {
static final String LOG_TAG = "CDMA";
private static final boolean LOCAL_DEBUG = true;
+ // Default Emergency Callback Mode exit timer
+ private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 30000;
+ static final String VM_COUNT_CDMA = "vm_count_key_cdma";
+ private static final String VM_NUMBER_CDMA = "vm_number_key_cdma";
+ private String mVmNumber = null;
+
//***** Instance Variables
CdmaCallTracker mCT;
CdmaSMSDispatcher mSMS;
@@ -71,11 +84,29 @@ public class CDMAPhone extends PhoneBase {
RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager;
RuimSmsInterfaceManager mRuimSmsInterfaceManager;
PhoneSubInfo mSubInfo;
+ EriManager mEriManager;
- protected RegistrantList mNvLoadedRegistrants = new RegistrantList();
+ // mNvLoadedRegistrants are informed after the EVENT_NV_READY
+ private RegistrantList mNvLoadedRegistrants = new RegistrantList();
+
+ // mEriFileLoadedRegistrants are informed after the ERI text has been loaded
+ private RegistrantList mEriFileLoadedRegistrants = new RegistrantList();
+
+ // mECMExitRespRegistrant is informed after the phone has been exited
+ //the emergency callback mode
+ //keep track of if phone is in emergency callback mode
+ private boolean mIsPhoneInECMState;
+ private Registrant mECMExitRespRegistrant;
private String mEsn;
private String mMeid;
+ // A runnable which is used to automatically exit from ECM after a period of time.
+ private Runnable mExitEcmRunnable = new Runnable() {
+ public void run() {
+ exitEmergencyCallbackMode();
+ }
+ };
+
Registrant mPostDialHandler;
@@ -102,6 +133,7 @@ public class CDMAPhone extends PhoneBase {
mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this);
mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this);
mSubInfo = new PhoneSubInfo(this);
+ mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML);
mCM.registerForAvailable(h, EVENT_RADIO_AVAILABLE, null);
mRuimRecords.registerForRecordsLoaded(h, EVENT_RUIM_RECORDS_LOADED, null);
@@ -111,10 +143,19 @@ public class CDMAPhone extends PhoneBase {
mCM.setOnCallRing(h, EVENT_CALL_RING, null);
mSST.registerForNetworkAttach(h, EVENT_REGISTERED_TO_NETWORK, null);
mCM.registerForNVReady(h, EVENT_NV_READY, null);
+ mCM.setEmergencyCallbackMode(h, EVENT_EMERGENCY_CALLBACK_MODE_ENTER, null);
+
//Change the system setting
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.CURRENT_ACTIVE_PHONE, RILConstants.CDMA_PHONE);
+ SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
+ new Integer(RILConstants.CDMA_PHONE).toString());
+
+ // This is needed to handle phone process crashes
+ String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
+ mIsPhoneInECMState = inEcm.equals("true");
+
+ // Notify voicemails.
+ notifier.notifyMessageWaitingChanged(this);
}
public void dispose() {
@@ -130,6 +171,7 @@ public class CDMAPhone extends PhoneBase {
mCM.unSetOnSuppServiceNotification(h);
mCM.unSetOnCallRing(h);
+
//Force all referenced classes to unregister their former registered events
mCT.dispose();
mDataConnection.dispose();
@@ -141,6 +183,7 @@ public class CDMAPhone extends PhoneBase {
mRuimPhoneBookInterfaceManager.dispose();
mRuimSmsInterfaceManager.dispose();
mSubInfo.dispose();
+ mEriManager.dispose();
}
}
@@ -155,6 +198,7 @@ public class CDMAPhone extends PhoneBase {
this.mDataConnection = null;
this.mCT = null;
this.mSST = null;
+ this.mEriManager = null;
}
protected void finalize() {
@@ -215,7 +259,7 @@ public class CDMAPhone extends PhoneBase {
public DataActivityState getDataActivityState() {
DataActivityState ret = DataActivityState.NONE;
- if (mSST.getCurrentCdmaDataConnectionState() != ServiceState.RADIO_TECHNOLOGY_UNKNOWN) {
+ if (mSST.getCurrentCdmaDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
switch (mDataConnection.getActivity()) {
case DATAIN:
@@ -229,6 +273,10 @@ public class CDMAPhone extends PhoneBase {
case DATAINANDOUT:
ret = DataActivityState.DATAINANDOUT;
break;
+
+ case DORMANT:
+ ret = DataActivityState.DORMANT;
+ break;
}
}
return ret;
@@ -249,26 +297,19 @@ public class CDMAPhone extends PhoneBase {
if (fc != null) {
//mMmiRegistrants.notifyRegistrants(new AsyncResult(null, fc, null));
fc.processCode();
- } else {
- FeatureCode digits = new FeatureCode(this);
- // use dial number as poundString
- digits.poundString = newDialString;
- digits.processCode();
+ return null;
}
- return null;
- } else {
- return mCT.dial(newDialString);
}
+ return mCT.dial(newDialString);
}
-
- public int getSignalStrengthASU() {
- return mSST.rssi == 99 ? -1 : mSST.rssi;
+ public SignalStrength getSignalStrength() {
+ return mSST.mSignalStrength;
}
public boolean
getMessageWaitingIndicator() {
- return mRuimRecords.getVoiceMessageWaiting();
+ return (getVoiceMessageCount() > 0);
}
public List<? extends MmiCode>
@@ -347,7 +388,15 @@ public class CDMAPhone extends PhoneBase {
}
public String getLine1Number() {
- return mRuimRecords.getMdnNumber();
+ return mSST.getMdnNumber();
+ }
+
+ public String getCdmaPrlVersion(){
+ return mRuimRecords.getPrlVersion();
+ }
+
+ public String getCdmaMIN() {
+ return mSST.getCdmaMin();
}
public void getCallWaiting(Message onComplete) {
@@ -378,8 +427,13 @@ public class CDMAPhone extends PhoneBase {
}
public String getSubscriberId() {
- Log.e(LOG_TAG, "method getSubscriberId for IMSI is NOT supported in CDMA!");
- return null;
+ // Subscriber ID is the combination of MCC+MNC+MIN as CDMA IMSI
+ // TODO(Moto): Replace with call to mRuimRecords.getIMSI_M() when implemented.
+ if ((getServiceState().getOperatorNumeric() != null) && (getCdmaMIN() != null)) {
+ return (getServiceState().getOperatorNumeric() + getCdmaMIN());
+ } else {
+ return null;
+ }
}
public boolean canConference() {
@@ -410,7 +464,7 @@ public class CDMAPhone extends PhoneBase {
}
public void setOnPostDialCharacter(Handler h, int what, Object obj) {
- Log.e(LOG_TAG, "setOnPostDialCharacter: not possible in CDMA");
+ mPostDialHandler = new Registrant(h, what, obj);
}
public boolean handlePinMmi(String dialString) {
@@ -454,14 +508,50 @@ public class CDMAPhone extends PhoneBase {
mDataConnection.setDataOnRoamingEnabled(enable);
}
+ public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
+ mCM.registerForCdmaOtaProvision(h, what, obj);
+ }
+
+ public void unregisterForCdmaOtaStatusChange(Handler h) {
+ mCM.unregisterForCdmaOtaProvision(h);
+ }
+
+ public void setOnEcbModeExitResponse(Handler h, int what, Object obj) {
+ mECMExitRespRegistrant = new Registrant (h, what, obj);
+ }
+
+ public void unsetOnEcbModeExitResponse(Handler h) {
+ mECMExitRespRegistrant.clear();
+ }
+
+ public void registerForCallWaiting(Handler h, int what, Object obj) {
+ mCT.registerForCallWaiting(h, what, obj);
+ }
+
+ public void unregisterForCallWaiting(Handler h) {
+ mCT.unregisterForCallWaiting(h);
+ }
+
public String getIpAddress(String apnType) {
return mDataConnection.getIpAddress();
}
public void
getNeighboringCids(Message response) {
- // WINK:TODO: implement after Cupcake merge
- mCM.getNeighboringCids(response); // workaround.
+ /*
+ * This is currently not implemented. At least as of June
+ * 2009, there is no neighbor cell information available for
+ * CDMA because some party is resisting making this
+ * information readily available. Consequently, calling this
+ * function can have no useful effect. This situation may
+ * (and hopefully will) change in the future.
+ */
+ if (response != null) {
+ CommandException ce = new CommandException(
+ CommandException.Error.REQUEST_NOT_SUPPORTED);
+ AsyncResult.forMessage(response).exception = ce;
+ response.sendToTarget();
+ }
}
public DataState getDataConnectionState() {
@@ -476,12 +566,11 @@ public class CDMAPhone extends PhoneBase {
ret = DataState.CONNECTED;
} else if (mSST == null) {
- // Radio Technology Change is ongoning, dispose() and removeReferences() have
- // already been called
+ // Radio Technology Change is ongoning, dispose() and removeReferences() have
+ // already been called
- ret = DataState.DISCONNECTED;
- } else if (mSST.getCurrentCdmaDataConnectionState()
- == ServiceState.RADIO_TECHNOLOGY_UNKNOWN) {
+ ret = DataState.DISCONNECTED;
+ } else if (mSST.getCurrentCdmaDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
// If we're out of service, open TCP sockets may still work
// but no data will flow
ret = DataState.DISCONNECTED;
@@ -541,6 +630,21 @@ public class CDMAPhone extends PhoneBase {
mCM.stopDtmf(null);
}
+ public void sendBurstDtmf(String dtmfString, Message onComplete) {
+ boolean check = true;
+ for (int itr = 0;itr < dtmfString.length(); itr++) {
+ if (!PhoneNumberUtils.is12Key(dtmfString.charAt(itr))) {
+ Log.e(LOG_TAG,
+ "sendDtmf called with invalid character '" + dtmfString.charAt(itr)+ "'");
+ check = false;
+ break;
+ }
+ }
+ if ((mCT.state == Phone.State.OFFHOOK)&&(check)) {
+ mCM.sendBurstDtmf(dtmfString, onComplete);
+ }
+ }
+
public void getAvailableNetworks(Message response) {
Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA");
}
@@ -554,7 +658,7 @@ public class CDMAPhone extends PhoneBase {
}
public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) {
- Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA");
+ Log.e(LOG_TAG, "setOutgoingCallerIdDisplay: not possible in CDMA");
}
public void enableLocationUpdates() {
@@ -583,15 +687,33 @@ public class CDMAPhone extends PhoneBase {
public void setVoiceMailNumber(String alphaTag,
String voiceMailNumber,
Message onComplete) {
- //mSIMRecords.setVoiceMailNumber(alphaTag, voiceMailNumber, onComplete);
- //TODO: Where do we have to store this value has to be clarified with QC
+ Message resp;
+ mVmNumber = voiceMailNumber;
+ resp = h.obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
+ mRuimRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
}
public String getVoiceMailNumber() {
- //TODO: Where can we get this value has to be clarified with QC
- //return mSIMRecords.getVoiceMailNumber();
-// throw new RuntimeException();
- return "12345";
+ String number = null;
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ // TODO(Moto): The default value of voicemail number should be read from a system property
+ number = sp.getString(VM_NUMBER_CDMA, "*86");
+ return number;
+ }
+
+ /* Returns Number of Voicemails
+ * @hide
+ */
+ public int getVoiceMessageCount() {
+ int voicemailCount = mRuimRecords.getVoiceMessageCount();
+ // If mRuimRecords.getVoiceMessageCount returns zero, then there is possibility
+ // that phone was power cycled and would have lost the voicemail count.
+ // So get the count from preferences.
+ if (voicemailCount == 0) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ voicemailCount = sp.getInt(VM_COUNT_CDMA, 0);
+ }
+ return voicemailCount;
}
public String getVoiceMailAlphaTag() {
@@ -609,7 +731,15 @@ public class CDMAPhone extends PhoneBase {
}
public boolean enableDataConnectivity() {
- return mDataConnection.setDataEnabled(true);
+
+ // block data activities when phone is in emergency callback mode
+ if (mIsPhoneInECMState) {
+ Intent intent = new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS);
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+ return false;
+ } else {
+ return mDataConnection.setDataEnabled(true);
+ }
}
public void disableLocationUpdates() {
@@ -652,7 +782,7 @@ public class CDMAPhone extends PhoneBase {
return null;
}
- /**
+ /**
* Notify any interested party of a Phone state change.
*/
/*package*/ void notifyPhoneStateChanged() {
@@ -697,15 +827,23 @@ public class CDMAPhone extends PhoneBase {
mUnknownConnectionRegistrants.notifyResult(this);
}
+ void sendEmergencyCallbackModeChange(){
+ //Send an Intent
+ Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
+ intent.putExtra(PHONE_IN_ECM_STATE, mIsPhoneInECMState);
+ ActivityManagerNative.broadcastStickyIntent(intent,null);
+ }
+
/*package*/ void
updateMessageWaitingIndicator(boolean mwi) {
// this also calls notifyMessageWaitingIndicator()
mRuimRecords.setVoiceMessageWaiting(1, mwi ? -1 : 0);
}
- public void
- notifyMessageWaitingIndicator() {
- mNotifier.notifyMessageWaitingChanged(this);
+ /* This function is overloaded to send number of voicemails instead of sending true/false */
+ /*package*/ void
+ updateMessageWaitingIndicator(int mwi) {
+ mRuimRecords.setVoiceMessageWaiting(1, mwi);
}
/**
@@ -722,6 +860,51 @@ public class CDMAPhone extends PhoneBase {
mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, fc, null));
}
+
+ @Override
+ public void exitEmergencyCallbackMode() {
+ // Send a message which will invoke handleExitEmergencyCallbackMode
+ mCM.exitEmergencyCallbackMode(h.obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE));
+ }
+
+ private void handleEnterEmergencyCallbackMode(Message msg) {
+ Log.d(LOG_TAG, "Event EVENT_EMERGENCY_CALLBACK_MODE Received");
+ // if phone is not in ECM mode, and it's changed to ECM mode
+ if (mIsPhoneInECMState == false) {
+ mIsPhoneInECMState = true;
+ // notify change
+ sendEmergencyCallbackModeChange();
+ setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true");
+
+ // Post this runnable so we will automatically exit
+ // if no one invokes exitEmergencyCallbackMode() directly.
+ long delayInMillis = SystemProperties.getLong(
+ TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE);
+ h.postDelayed(mExitEcmRunnable, delayInMillis);
+ }
+ }
+
+ private void handleExitEmergencyCallbackMode(Message msg) {
+ Log.d(LOG_TAG, "Event EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE Received");
+ AsyncResult ar = (AsyncResult)msg.obj;
+
+ // Remove pending exit ECM runnable, if any
+ h.removeCallbacks(mExitEcmRunnable);
+
+ if (mECMExitRespRegistrant != null) {
+ mECMExitRespRegistrant.notifyRegistrant(ar);
+ }
+ // if exiting ecm success
+ if (ar.exception == null) {
+ if (mIsPhoneInECMState) {
+ mIsPhoneInECMState = false;
+ setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false");
+ }
+ // send an Intent
+ sendEmergencyCallbackModeChange();
+ }
+ }
+
//***** Inner Classes
class MyHandler extends Handler {
MyHandler() {
@@ -731,6 +914,7 @@ public class CDMAPhone extends PhoneBase {
super(l);
}
+ @Override
public void handleMessage(Message msg) {
AsyncResult ar;
Message onComplete;
@@ -751,7 +935,7 @@ public class CDMAPhone extends PhoneBase {
}
if (LOCAL_DEBUG) Log.d(LOG_TAG, "Baseband version: " + ar.result);
- setSystemProperty(PROPERTY_BASEBAND_VERSION, (String)ar.result);
+ setSystemProperty(TelephonyProperties.PROPERTY_BASEBAND_VERSION, (String)ar.result);
}
break;
@@ -767,6 +951,16 @@ public class CDMAPhone extends PhoneBase {
}
break;
+ case EVENT_EMERGENCY_CALLBACK_MODE_ENTER:{
+ handleEnterEmergencyCallbackMode(msg);
+ }
+ break;
+
+ case EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE:{
+ handleExitEmergencyCallbackMode(msg);
+ }
+ break;
+
case EVENT_RUIM_RECORDS_LOADED:{
Log.d(LOG_TAG, "Event EVENT_RUIM_RECORDS_LOADED Received");
}
@@ -800,10 +994,30 @@ public class CDMAPhone extends PhoneBase {
case EVENT_NV_READY:{
Log.d(LOG_TAG, "Event EVENT_NV_READY Received");
//Inform the Service State Tracker
+ mEriManager.loadEriFile();
mNvLoadedRegistrants.notifyRegistrants();
+ if(mEriManager.isEriFileLoaded()) {
+ // when the ERI file is loaded
+ Log.d(LOG_TAG, "ERI read, notify registrants");
+ mEriFileLoadedRegistrants.notifyRegistrants();
+ }
+ setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE,"false");
}
break;
+ case EVENT_SET_VM_NUMBER_DONE:{
+ ar = (AsyncResult)msg.obj;
+ if (IccException.class.isInstance(ar.exception)) {
+ storeVoiceMailNumber(mVmNumber);
+ ar.exception = null;
+ }
+ onComplete = (Message) ar.userObj;
+ if (onComplete != null) {
+ AsyncResult.forMessage(onComplete, ar.result, ar.exception);
+ onComplete.sendToTarget();
+ }
+ }
+
default:{
throw new RuntimeException("unexpected event not handled");
}
@@ -811,26 +1025,26 @@ public class CDMAPhone extends PhoneBase {
}
}
- /**
- * Retrieves the PhoneSubInfo of the CDMAPhone
- */
- public PhoneSubInfo getPhoneSubInfo(){
+ /**
+ * Retrieves the PhoneSubInfo of the CDMAPhone
+ */
+ public PhoneSubInfo getPhoneSubInfo() {
return mSubInfo;
- }
+ }
- /**
- * Retrieves the IccSmsInterfaceManager of the CDMAPhone
- */
- public IccSmsInterfaceManager getIccSmsInterfaceManager(){
- return mRuimSmsInterfaceManager;
- }
+ /**
+ * Retrieves the IccSmsInterfaceManager of the CDMAPhone
+ */
+ public IccSmsInterfaceManager getIccSmsInterfaceManager() {
+ return mRuimSmsInterfaceManager;
+ }
- /**
- * Retrieves the IccPhoneBookInterfaceManager of the CDMAPhone
- */
- public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
- return mRuimPhoneBookInterfaceManager;
- }
+ /**
+ * Retrieves the IccPhoneBookInterfaceManager of the CDMAPhone
+ */
+ public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager() {
+ return mRuimPhoneBookInterfaceManager;
+ }
public void registerForNvLoaded(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
@@ -841,71 +1055,193 @@ public class CDMAPhone extends PhoneBase {
mNvLoadedRegistrants.remove(h);
}
- // override for allowing access from other classes of this package
- /**
- * {@inheritDoc}
- */
- public final void setSystemProperty(String property, String value) {
- super.setSystemProperty(property, value);
- }
+ public void registerForEriFileLoaded(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mEriFileLoadedRegistrants.add(r);
+ }
- /**
- * {@inheritDoc}
- */
- public Handler getHandler(){
- return h;
- }
+ public void unregisterForEriFileLoaded(Handler h) {
+ mEriFileLoadedRegistrants.remove(h);
+ }
- /**
- * {@inheritDoc}
- */
- public IccFileHandler getIccFileHandler(){
- return this.mIccFileHandler;
- }
+ // override for allowing access from other classes of this package
+ /**
+ * {@inheritDoc}
+ */
+ public final void setSystemProperty(String property, String value) {
+ super.setSystemProperty(property, value);
+ }
- /**
- * Set the TTY mode of the CDMAPhone
- */
- public void setTTYModeEnabled(boolean enable, Message onComplete) {
- this.mCM.setTTYModeEnabled(enable, onComplete);
-}
+ /**
+ * {@inheritDoc}
+ */
+ public Handler getHandler() {
+ return h;
+ }
- /**
- * Queries the TTY mode of the CDMAPhone
- */
- public void queryTTYModeEnabled(Message onComplete) {
- this.mCM.queryTTYModeEnabled(onComplete);
- }
+ /**
+ * {@inheritDoc}
+ */
+ public IccFileHandler getIccFileHandler() {
+ return this.mIccFileHandler;
+ }
- /**
- * Activate or deactivate cell broadcast SMS.
- *
- * @param activate
- * 0 = activate, 1 = deactivate
- * @param response
- * Callback message is empty on completion
- */
- public void activateCellBroadcastSms(int activate, Message response) {
- mSMS.activateCellBroadcastSms(activate, response);
- }
+ /**
+ * Set the TTY mode of the CDMAPhone
+ */
+ public void setTTYMode(int ttyMode, Message onComplete) {
+ this.mCM.setTTYMode(ttyMode, onComplete);
+ }
- /**
- * Query the current configuration of cdma cell broadcast SMS.
- *
- * @param response
- * Callback message is empty on completion
- */
- public void getCellBroadcastSmsConfig(Message response){
- mSMS.getCellBroadcastSmsConfig(response);
- }
+ /**
+ * Queries the TTY mode of the CDMAPhone
+ */
+ public void queryTTYMode(Message onComplete) {
+ this.mCM.queryTTYMode(onComplete);
+ }
+
+ /**
+ * Activate or deactivate cell broadcast SMS.
+ *
+ * @param activate 0 = activate, 1 = deactivate
+ * @param response Callback message is empty on completion
+ */
+ public void activateCellBroadcastSms(int activate, Message response) {
+ mSMS.activateCellBroadcastSms(activate, response);
+ }
+
+ /**
+ * Query the current configuration of cdma cell broadcast SMS.
+ *
+ * @param response Callback message is empty on completion
+ */
+ public void getCellBroadcastSmsConfig(Message response) {
+ mSMS.getCellBroadcastSmsConfig(response);
+ }
+
+ /**
+ * Configure cdma cell broadcast SMS.
+ *
+ * @param response Callback message is empty on completion
+ */
+ public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) {
+ mSMS.setCellBroadcastConfig(configValuesArray, response);
+ }
+
+ public static final String IS683A_FEATURE_CODE = "*228" ;
+ public static final int IS683A_FEATURE_CODE_NUM_DIGITS = 4 ;
+ public static final int IS683A_SYS_SEL_CODE_NUM_DIGITS = 2 ;
+ public static final int IS683A_SYS_SEL_CODE_OFFSET = 4;
+
+ private static final int IS683_CONST_800MHZ_A_BAND = 0;
+ private static final int IS683_CONST_800MHZ_B_BAND = 1;
+ private static final int IS683_CONST_1900MHZ_A_BLOCK = 2;
+ private static final int IS683_CONST_1900MHZ_B_BLOCK = 3;
+ private static final int IS683_CONST_1900MHZ_C_BLOCK = 4;
+ private static final int IS683_CONST_1900MHZ_D_BLOCK = 5;
+ private static final int IS683_CONST_1900MHZ_E_BLOCK = 6;
+ private static final int IS683_CONST_1900MHZ_F_BLOCK = 7;
+
+ private boolean isIs683OtaSpDialStr(String dialStr) {
+ int sysSelCodeInt;
+ boolean isOtaspDialString = false;
+ int dialStrLen = dialStr.length();
+
+ if (dialStrLen == IS683A_FEATURE_CODE_NUM_DIGITS) {
+ if (dialStr.equals(IS683A_FEATURE_CODE)) {
+ isOtaspDialString = true;
+ }
+ } else if ((dialStr.regionMatches(0, IS683A_FEATURE_CODE, 0,
+ IS683A_FEATURE_CODE_NUM_DIGITS) == true)
+ && (dialStrLen >=
+ (IS683A_FEATURE_CODE_NUM_DIGITS + IS683A_SYS_SEL_CODE_NUM_DIGITS))) {
+ StringBuilder sb = new StringBuilder(dialStr);
+ // Separate the System Selection Code into its own string
+ char[] sysSel = new char[2];
+ sb.delete(0, IS683A_SYS_SEL_CODE_OFFSET);
+ sb.getChars(0, IS683A_SYS_SEL_CODE_NUM_DIGITS, sysSel, 0);
+
+ if ((PhoneNumberUtils.isISODigit(sysSel[0]))
+ && (PhoneNumberUtils.isISODigit(sysSel[1]))) {
+ String sysSelCode = new String(sysSel);
+ sysSelCodeInt = Integer.parseInt((String)sysSelCode);
+ switch (sysSelCodeInt) {
+ case IS683_CONST_800MHZ_A_BAND:
+ case IS683_CONST_800MHZ_B_BAND:
+ case IS683_CONST_1900MHZ_A_BLOCK:
+ case IS683_CONST_1900MHZ_B_BLOCK:
+ case IS683_CONST_1900MHZ_C_BLOCK:
+ case IS683_CONST_1900MHZ_D_BLOCK:
+ case IS683_CONST_1900MHZ_E_BLOCK:
+ case IS683_CONST_1900MHZ_F_BLOCK:
+ isOtaspDialString = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ return isOtaspDialString;
+ }
/**
- * Configure cdma cell broadcast SMS.
+ * isOTASPNumber: checks a given number against the IS-683A OTASP dial string and carrier
+ * OTASP dial string.
*
- * @param response
- * Callback message is empty on completion
+ * @param dialStr the number to look up.
+ * @return true if the number is in IS-683A OTASP dial string or carrier OTASP dial string
*/
- public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){
- mSMS.setCellBroadcastConfig(configValuesArray, response);
+ @Override
+ public boolean isOtaSpNumber(String dialStr){
+ boolean isOtaSpNum = false;
+ if(dialStr != null){
+ isOtaSpNum=isIs683OtaSpDialStr(dialStr);
+ if(isOtaSpNum == false){
+ //TO DO:Add carrier specific OTASP number detection here.
+ }
+ }
+ return isOtaSpNum;
}
+
+ @Override
+ public int getCdmaEriIconIndex() {
+ int roamInd = getServiceState().getCdmaRoamingIndicator();
+ int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator();
+ return mEriManager.getCdmaEriIconIndex(roamInd, defRoamInd);
+ }
+
+ /**
+ * Returns the CDMA ERI icon mode,
+ * 0 - ON
+ * 1 - FLASHING
+ */
+ @Override
+ public int getCdmaEriIconMode() {
+ int roamInd = getServiceState().getCdmaRoamingIndicator();
+ int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator();
+ return mEriManager.getCdmaEriIconMode(roamInd, defRoamInd);
+ }
+
+ /**
+ * Returns the CDMA ERI text,
+ */
+ @Override
+ public String getCdmaEriText() {
+ int roamInd = getServiceState().getCdmaRoamingIndicator();
+ int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator();
+ return mEriManager.getCdmaEriText(roamInd, defRoamInd);
+ }
+
+ /**
+ * Store the voicemail number in preferences
+ */
+ private void storeVoiceMailNumber(String number) {
+ // Update the preference value of voicemail number
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putString(VM_NUMBER_CDMA, number);
+ editor.commit();
+ }
+
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
index ea557b2..fb5f0fa 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
@@ -25,26 +25,31 @@ package com.android.internal.telephony.cdma;
*
*/
public interface CallFailCause {
- static final int NORMAL_CLEARING = 16;
+ static final int NORMAL_CLEARING = 16;
// Busy Tone
- static final int USER_BUSY = 17;
-
-// // No Tone
-// static final int NUMBER_CHANGED = 22;
-// static final int STATUS_ENQUIRY = 30;
- static final int NORMAL_UNSPECIFIED = 31;
-//
-// // Congestion Tone
-// static final int NO_CIRCUIT_AVAIL = 34;
-// static final int TEMPORARY_FAILURE = 41;
-// static final int SWITCHING_CONGESTION = 42;
-// static final int CHANNEL_NOT_AVAIL = 44;
-// static final int QOS_NOT_AVAIL = 49;
-// static final int BEARER_NOT_AVAIL = 58;
-//
-// // others
-// static final int ACM_LIMIT_EXCEEDED = 68;
-// static final int CALL_BARRED = 240;
-// static final int FDN_BLOCKED = 241;
+ static final int USER_BUSY = 17;
+
+ static final int NORMAL_UNSPECIFIED = 31;
+
+ // Congestion Tone
+ static final int NO_CIRCUIT_AVAIL = 34;
+
+ // others
+ static final int ACM_LIMIT_EXCEEDED = 68;
+ static final int CALL_BARRED = 240;
+ static final int FDN_BLOCKED = 241;
+
+ static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000;
+ static final int CDMA_DROP = 1001;
+ static final int CDMA_INTERCEPT = 1002;
+ static final int CDMA_REORDER = 1003;
+ static final int CDMA_SO_REJECT = 1004;
+ static final int CDMA_RETRY_ORDER = 1005;
+ static final int CDMA_ACCESS_FAILURE = 1006;
+ static final int CDMA_PREEMPTED = 1007;
+
+ // For non-emergency number dialed while in emergency callback mode.
+ static final int CDMA_NOT_EMERGENCY = 1008;
+
static final int ERROR_UNSPECIFIED = 0xffff;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
index 34514d9..e8724c2 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
@@ -181,9 +181,7 @@ public final class CdmaCall extends Call {
*/
void
onHangupLocal() {
- for (int i = 0, s = connections.size()
- ; i < s; i++
- ) {
+ for (int i = 0, s = connections.size(); i < s; i++) {
CdmaConnection cn = (CdmaConnection)connections.get(i);
cn.onHangupLocal();
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index a1d362f..ed2ea90 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -24,6 +24,7 @@ import android.os.RegistrantList;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.util.Log;
+import android.os.SystemProperties;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CallTracker;
@@ -31,11 +32,12 @@ import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.DriverCall;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneProxy;
+import com.android.internal.telephony.TelephonyProperties;
import java.util.ArrayList;
import java.util.List;
+
/**
* {@hide}
*/
@@ -56,6 +58,7 @@ public final class CdmaCallTracker extends CallTracker {
CdmaConnection connections[] = new CdmaConnection[MAX_CONNECTIONS];
RegistrantList voiceCallEndedRegistrants = new RegistrantList();
RegistrantList voiceCallStartedRegistrants = new RegistrantList();
+ RegistrantList callWaitingRegistrants = new RegistrantList();
// connections dropped durin last poll
@@ -69,11 +72,12 @@ public final class CdmaCallTracker extends CallTracker {
CdmaConnection pendingMO;
boolean hangupPendingMO;
-
+ boolean pendingCallInECM=false;
CDMAPhone phone;
boolean desiredMute = false; // false = mute off
+ int pendingCallClirMode;
Phone.State state = Phone.State.IDLE;
@@ -90,13 +94,15 @@ public final class CdmaCallTracker extends CallTracker {
cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
+ cm.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null);
+ foregroundCall.setGeneric(false);
}
public void dispose() {
cm.unregisterForCallStateChanged(this);
cm.unregisterForOn(this);
cm.unregisterForNotAvailable(this);
-
+ cm.unregisterForCallWaitingInfo(this);
for(CdmaConnection c : connections) {
try {
if(c != null) hangup(c);
@@ -115,6 +121,7 @@ public final class CdmaCallTracker extends CallTracker {
}
+ @Override
protected void finalize() {
Log.d(LOG_TAG, "CdmaCallTracker finalized");
}
@@ -139,6 +146,15 @@ public final class CdmaCallTracker extends CallTracker {
voiceCallEndedRegistrants.remove(h);
}
+ public void registerForCallWaiting(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ callWaitingRegistrants.add(r);
+ }
+
+ public void unregisterForCallWaiting(Handler h) {
+ callWaitingRegistrants.remove(h);
+ }
+
private void
fakeHoldForegroundBeforeDial() {
List<Connection> connCopy;
@@ -166,34 +182,24 @@ public final class CdmaCallTracker extends CallTracker {
throw new CallStateException("cannot dial in current state");
}
+
+ // We are initiating a call therefore even if we previously
+ // didn't know the state (i.e. Generic was true) we now know
+ // and therefore can set Generic to false.
+ foregroundCall.setGeneric(false);
+
// The new call must be assigned to the foreground call.
// That call must be idle, so place anything that's
// there on hold
if (foregroundCall.getState() == CdmaCall.State.ACTIVE) {
- // this will probably be done by the radio anyway
- // but the dial might fail before this happens
- // and we need to make sure the foreground call is clear
- // for the newly dialed connection
- switchWaitingOrHoldingAndActive();
-
- // Fake local state so that
- // a) foregroundCall is empty for the newly dialed connection
- // b) hasNonHangupStateChanged remains false in the
- // next poll, so that we don't clear a failed dialing call
- fakeHoldForegroundBeforeDial();
- }
-
- if (foregroundCall.getState() != CdmaCall.State.IDLE) {
- //we should have failed in !canDial() above before we get here
- throw new CallStateException("cannot dial in current state");
+ return dialThreeWay(dialString);
}
pendingMO = new CdmaConnection(phone.getContext(), dialString, this, foregroundCall);
hangupPendingMO = false;
if (pendingMO.address == null || pendingMO.address.length() == 0
- || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0
- ) {
+ || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0) {
// Phone number is invalid
pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
@@ -204,7 +210,15 @@ public final class CdmaCallTracker extends CallTracker {
// Always unmute when initiating a new call
setMute(false);
- cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
+ String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
+ if(inEcm.equals("false")) {
+ cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
+ } else {
+ phone.exitEmergencyCallbackMode();
+ phone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
+ pendingCallClirMode=clirMode;
+ pendingCallInECM=true;
+ }
}
updatePhoneState();
@@ -219,19 +233,35 @@ public final class CdmaCallTracker extends CallTracker {
return dial(dialString, CommandsInterface.CLIR_DEFAULT);
}
- void
- acceptCall () throws CallStateException {
- // FIXME if SWITCH fails, should retry with ANSWER
- // in case the active/holding call disappeared and this
- // is no longer call waiting
+ private Connection
+ dialThreeWay (String dialString) {
+ if (!foregroundCall.isIdle()) {
+ // Attach the new connection to foregroundCall
+ pendingMO = new CdmaConnection(phone.getContext(),
+ dialString, this, foregroundCall);
+ cm.sendCDMAFeatureCode(pendingMO.address,
+ obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
+ return pendingMO;
+ }
+ return null;
+ }
+ void
+ acceptCall() throws CallStateException {
if (ringingCall.getState() == CdmaCall.State.INCOMING) {
Log.i("phone", "acceptCall: incoming...");
// Always unmute when answering a new call
setMute(false);
cm.acceptCall(obtainCompleteMessage());
} else if (ringingCall.getState() == CdmaCall.State.WAITING) {
- setMute(false);
+ CdmaConnection cwConn = (CdmaConnection)(ringingCall.getLatestConnection());
+
+ // Since there is no network response for supplimentary
+ // service for CDMA, we assume call waiting is answered.
+ // ringing Call state change to idle is in CdmaCall.detach
+ // triggered by updateParent.
+ cwConn.updateParent(ringingCall, foregroundCall);
+ cwConn.onConnectedInOrOut();
switchWaitingOrHoldingAndActive();
} else {
throw new CallStateException("phone not ringing");
@@ -255,14 +285,14 @@ public final class CdmaCallTracker extends CallTracker {
if (ringingCall.getState() == CdmaCall.State.INCOMING) {
throw new CallStateException("cannot be in the incoming state");
} else {
- cm.sendCDMAFeatureCode("", obtainCompleteMessage(EVENT_SWITCH_RESULT));
+ flashAndSetGenericTrue();
}
}
void
conference() throws CallStateException {
- // three way calls in CDMA will be handled by feature codes
- Log.e(LOG_TAG, "conference: not possible in CDMA");
+ // Should we be checking state?
+ flashAndSetGenericTrue();
}
void
@@ -295,6 +325,7 @@ public final class CdmaCallTracker extends CallTracker {
pendingMO == null
&& !ringingCall.isRinging()
&& (!foregroundCall.getState().isAlive()
+ || (foregroundCall.getState() == CdmaCall.State.ACTIVE)
|| !backgroundCall.getState().isAlive());
return ret;
@@ -483,9 +514,20 @@ public final class CdmaCallTracker extends CallTracker {
}
hasNonHangupStateChanged = true;
} else if (conn != null && dc == null) {
- // Connection missing in CLCC response that we were
- // tracking.
- droppedDuringPoll.add(conn);
+ int count = foregroundCall.connections.size();
+ if (count == 0) {
+ // Handle an unanswered MO/MT call, there is no
+ // foregroundCall connections at this time.
+ droppedDuringPoll.add(conn);
+ } else {
+ // Loop through foreground call connections as
+ // it contains the known logical connections.
+ for (int n = 0; n < count; n++) {
+ CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n);
+ droppedDuringPoll.add(cn);
+ }
+ }
+ foregroundCall.setGeneric(false);
// Dropped connections are removed from the CallTracker
// list but kept in the Call list
connections[i] = null;
@@ -536,6 +578,9 @@ public final class CdmaCallTracker extends CallTracker {
droppedDuringPoll.add(pendingMO);
pendingMO = null;
hangupPendingMO = false;
+ if( pendingCallInECM) {
+ pendingCallInECM = false;
+ }
}
if (newRinging != null) {
@@ -619,6 +664,22 @@ public final class CdmaCallTracker extends CallTracker {
if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
hangupPendingMO = true;
+ } else if ((conn.getCall() == ringingCall)
+ && (ringingCall.getState() == CdmaCall.State.WAITING)) {
+ // Handle call waiting hang up case.
+ //
+ // The ringingCall state will change to IDLE in CdmaCall.detach
+ // if the ringing call connection size is 0. We don't specifically
+ // set the ringing call state to IDLE here to avoid a race condition
+ // where a new call waiting could get a hang up from an old call
+ // waiting ringingCall.
+ //
+ // PhoneApp does the call log itself since only PhoneApp knows
+ // the hangup reason is user ignoring or timing out. So conn.onDisconnect()
+ // is not called here. Instead, conn.onLocalDisconnect() is called.
+ conn.onLocalDisconnect();
+ phone.notifyCallStateChanged();
+ return;
} else {
try {
cm.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage());
@@ -753,6 +814,16 @@ public final class CdmaCallTracker extends CallTracker {
return null;
}
+ private void flashAndSetGenericTrue() throws CallStateException {
+ cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
+
+ // Set generic to true because in CDMA it is not known what
+ // the status of the call is after a call waiting is answered,
+ // 3 way call merged or a switch between calls.
+ foregroundCall.setGeneric(true);
+ phone.notifyCallStateChanged();
+ }
+
private Phone.SuppService getFailedService(int what) {
switch (what) {
case EVENT_SWITCH_RESULT:
@@ -774,6 +845,30 @@ public final class CdmaCallTracker extends CallTracker {
pollCallsWhenSafe();
}
+ private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) {
+ if (callWaitingRegistrants != null) {
+ callWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null));
+ }
+ }
+
+ private void handleCallWaitingInfo (CdmaCallWaitingNotification cw) {
+ // Check how many connections in foregroundCall.
+ // If the connection in foregroundCall is more
+ // than one, then the connection information is
+ // not reliable anymore since it means either
+ // call waiting is connected or 3 way call is
+ // dialed before, so set generic.
+ if (foregroundCall.connections.size() > 1 ) {
+ foregroundCall.setGeneric(true);
+ }
+
+ // Create a new CdmaConnection which attaches itself to ringingCall.
+ ringingCall.setGeneric(false);
+ new CdmaConnection(phone.getContext(), cw, this, ringingCall);
+
+ // Finally notify application
+ notifyCallWaitingInfo(cw);
+ }
//****** Overridden from Handler
public void
@@ -796,13 +891,13 @@ public final class CdmaCallTracker extends CallTracker {
break;
case EVENT_OPERATION_COMPLETE:
- ar = (AsyncResult)msg.obj;
operationComplete();
break;
case EVENT_SWITCH_RESULT:
- ar = (AsyncResult)msg.obj;
- operationComplete();
+ // In GSM call operationComplete() here which gets the
+ // current call list. But in CDMA there is no list so
+ // there is nothing to do.
break;
case EVENT_GET_LAST_CALL_FAIL_CAUSE:
@@ -835,6 +930,7 @@ public final class CdmaCallTracker extends CallTracker {
droppedDuringPoll.clear();
break;
+ case EVENT_REPOLL_AFTER_DELAY:
case EVENT_CALL_STATE_CHANGE:
pollCallsWhenSafe();
break;
@@ -847,8 +943,33 @@ public final class CdmaCallTracker extends CallTracker {
handleRadioNotAvailable();
break;
+ case EVENT_EXIT_ECM_RESPONSE_CDMA:
+ //no matter the result, we still do the same here
+ if (pendingCallInECM) {
+ cm.dial(pendingMO.address, pendingCallClirMode, obtainCompleteMessage());
+ pendingCallInECM = false;
+ }
+ phone.unsetOnEcbModeExitResponse(this);
+ break;
+
+ case EVENT_CALL_WAITING_INFO_CDMA:
+ ar = (AsyncResult)msg.obj;
+ if (ar.exception == null) {
+ handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result);
+ Log.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received");
+ }
+ break;
+
+ case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA:
+ ar = (AsyncResult)msg.obj;
+ if (ar.exception == null) {
+ // Assume 3 way call is connected
+ pendingMO.onConnectedInOrOut();
+ }
+ break;
+
default:{
- throw new RuntimeException("unexpected event not handled");
+ throw new RuntimeException("unexpected event not handled");
}
}
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
new file mode 100644
index 0000000..54dec48
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.telephony.cdma;
+
+/**
+ * Represents a Supplementary Service Notification received from the network.
+ *
+ * {@hide}
+ */
+public class CdmaCallWaitingNotification {
+ public String number =null;
+ public int numberPresentation = 0;
+ public String name = null;
+ public int namePresentation = 0;
+ public int isPresent = 0;
+ public int signalType = 0;
+ public int alertPitch = 0;
+ public int signal = 0;
+
+
+ public String toString()
+ {
+ return super.toString() + "Call Waiting Notification "
+ + " number: " + number
+ + " numberPresentation: " + numberPresentation
+ + " name: " + name
+ + " namePresentation: " + namePresentation
+ + " isPresent: " + isPresent
+ + " signalType: " + signalType
+ + " alertPitch: " + alertPitch
+ + " signal: " + signal ;
+ }
+
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index cdad4a7..025382d 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -25,11 +25,14 @@ import android.os.Message;
import android.os.PowerManager;
import android.os.Registrant;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.util.Config;
import android.util.Log;
+import android.text.TextUtils;
+
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
-
+import com.android.internal.telephony.TelephonyProperties;
/**
* {@hide}
@@ -48,7 +51,7 @@ public class CdmaConnection extends Connection {
String postDialString; // outgoing calls only
boolean isIncoming;
boolean disconnected;
-
+ String cnapName;
int index; // index in CdmaCallTracker.connections[], -1 if unassigned
/*
@@ -74,6 +77,8 @@ public class CdmaConnection extends Connection {
DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED;
PostDialState postDialState = PostDialState.NOT_STARTED;
int numberPresentation = Connection.PRESENTATION_ALLOWED;
+ int cnapNamePresentation = Connection.PRESENTATION_ALLOWED;
+
Handler h;
@@ -84,11 +89,10 @@ public class CdmaConnection extends Connection {
static final int EVENT_PAUSE_DONE = 2;
static final int EVENT_NEXT_POST_DIAL = 3;
static final int EVENT_WAKE_LOCK_TIMEOUT = 4;
-
+
//***** Constants
- static final int PAUSE_DELAY_FIRST_MILLIS = 100;
- static final int PAUSE_DELAY_MILLIS = 3 * 1000;
static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000;
+ static final int PAUSE_DELAY_MILLIS = 2 * 1000;
//***** Inner Classes
@@ -126,6 +130,8 @@ public class CdmaConnection extends Connection {
isIncoming = dc.isMT;
createTime = System.currentTimeMillis();
+ cnapName = dc.name;
+ cnapNamePresentation = dc.namePresentation;
numberPresentation = dc.numberPresentation;
this.index = index;
@@ -134,16 +140,19 @@ public class CdmaConnection extends Connection {
parent.attach(this, dc);
}
- /** This is an MO call, created when dialing */
+ /** This is an MO call/three way call, created when dialing */
/*package*/
- CdmaConnection (Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) {
+ CdmaConnection(Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) {
createWakeLock(context);
acquireWakeLock();
-
+
owner = ct;
h = new MyHandler(owner.getLooper());
this.dialString = dialString;
+ Log.d(LOG_TAG, "[CDMAConn] CdmaConnection: dialString=" + dialString);
+ dialString = formatDialString(dialString);
+ Log.d(LOG_TAG, "[CDMAConn] CdmaConnection:formated dialString=" + dialString);
this.address = PhoneNumberUtils.extractNetworkPortion(dialString);
this.postDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
@@ -151,10 +160,41 @@ public class CdmaConnection extends Connection {
index = -1;
isIncoming = false;
+ cnapName = null;
+ cnapNamePresentation = 0;
+ numberPresentation = 0;
createTime = System.currentTimeMillis();
+ if (parent != null) {
+ this.parent = parent;
+
+ //for the three way call case, not change parent state
+ if (parent.state == CdmaCall.State.ACTIVE) {
+ parent.attachFake(this, CdmaCall.State.ACTIVE);
+ } else {
+ parent.attachFake(this, CdmaCall.State.DIALING);
+ }
+ }
+ }
+
+ /** This is a Call waiting call*/
+ CdmaConnection(Context context, CdmaCallWaitingNotification cw, CdmaCallTracker ct,
+ CdmaCall parent) {
+ createWakeLock(context);
+ acquireWakeLock();
+
+ owner = ct;
+ h = new MyHandler(owner.getLooper());
+ address = cw.number;
+ numberPresentation = cw.numberPresentation;
+ cnapName = cw.name;
+ cnapNamePresentation = cw.namePresentation;
+ index = -1;
+ isIncoming = true;
+ createTime = System.currentTimeMillis();
+ connectTime = 0;
this.parent = parent;
- parent.attachFake(this, CdmaCall.State.DIALING);
+ parent.attachFake(this, CdmaCall.State.WAITING);
}
public void dispose() {
@@ -186,10 +226,22 @@ public class CdmaConnection extends Connection {
return (isIncoming ? "incoming" : "outgoing");
}
+ public String getOrigDialString(){
+ return dialString;
+ }
+
public String getAddress() {
return address;
}
+ public String getCnapName() {
+ return cnapName;
+ }
+
+ public int getCnapNamePresentation() {
+ return cnapNamePresentation;
+ }
+
public CdmaCall getCall() {
return parent;
}
@@ -344,6 +396,32 @@ public class CdmaConnection extends Connection {
switch (causeCode) {
case CallFailCause.USER_BUSY:
return DisconnectCause.BUSY;
+ case CallFailCause.NO_CIRCUIT_AVAIL:
+ return DisconnectCause.CONGESTION;
+ case CallFailCause.ACM_LIMIT_EXCEEDED:
+ return DisconnectCause.LIMIT_EXCEEDED;
+ case CallFailCause.CALL_BARRED:
+ return DisconnectCause.CALL_BARRED;
+ case CallFailCause.FDN_BLOCKED:
+ return DisconnectCause.FDN_BLOCKED;
+ case CallFailCause.CDMA_LOCKED_UNTIL_POWER_CYCLE:
+ return DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE;
+ case CallFailCause.CDMA_DROP:
+ return DisconnectCause.CDMA_DROP;
+ case CallFailCause.CDMA_INTERCEPT:
+ return DisconnectCause.CDMA_INTERCEPT;
+ case CallFailCause.CDMA_REORDER:
+ return DisconnectCause.CDMA_REORDER;
+ case CallFailCause.CDMA_SO_REJECT:
+ return DisconnectCause.CDMA_SO_REJECT;
+ case CallFailCause.CDMA_RETRY_ORDER:
+ return DisconnectCause.CDMA_RETRY_ORDER;
+ case CallFailCause.CDMA_ACCESS_FAILURE:
+ return DisconnectCause.CDMA_ACCESS_FAILURE;
+ case CallFailCause.CDMA_PREEMPTED:
+ return DisconnectCause.CDMA_PREEMPTED;
+ case CallFailCause.CDMA_NOT_EMERGENCY:
+ return DisconnectCause.CDMA_NOT_EMERGENCY;
case CallFailCause.ERROR_UNSPECIFIED:
case CallFailCause.NORMAL_CLEARING:
default:
@@ -352,7 +430,7 @@ public class CdmaConnection extends Connection {
if (serviceState == ServiceState.STATE_POWER_OFF) {
return DisconnectCause.POWER_OFF;
} else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
- || serviceState == ServiceState.STATE_EMERGENCY_ONLY ) {
+ || serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
return DisconnectCause.OUT_OF_SERVICE;
} else if (phone.mCM.getRadioState() != CommandsInterface.RadioState.NV_READY
&& phone.getIccCard().getState() != RuimCard.State.READY) {
@@ -374,12 +452,7 @@ public class CdmaConnection extends Connection {
this.cause = cause;
if (!disconnected) {
- index = -1;
-
- disconnectTime = System.currentTimeMillis();
- duration = SystemClock.elapsedRealtime() - connectTimeReal;
- disconnected = true;
-
+ doDisconnect();
if (Config.LOGD) Log.d(LOG_TAG,
"[CDMAConn] onDisconnect: cause=" + cause);
@@ -392,6 +465,21 @@ public class CdmaConnection extends Connection {
releaseWakeLock();
}
+ /** Called when the call waiting connection has been hung up */
+ /*package*/ void
+ onLocalDisconnect() {
+ if (!disconnected) {
+ doDisconnect();
+ if (Config.LOGD) Log.d(LOG_TAG,
+ "[CDMAConn] onLoalDisconnect" );
+
+ if (parent != null) {
+ parent.detach(this);
+ }
+ }
+ releaseWakeLock();
+ }
+
// Returns true if state has changed, false if nothing changed
/*package*/ boolean
update (DriverCall dc) {
@@ -408,6 +496,21 @@ public class CdmaConnection extends Connection {
changed = true;
}
+ // A null cnapName should be the same as ""
+ if (TextUtils.isEmpty(dc.name)) {
+ if (!TextUtils.isEmpty(cnapName)) {
+ changed = true;
+ cnapName = "";
+ }
+ } else if (!dc.name.equals(cnapName)) {
+ changed = true;
+ cnapName = dc.name;
+ }
+
+ log("--dssds----"+cnapName);
+ cnapNamePresentation = dc.namePresentation;
+ numberPresentation = dc.numberPresentation;
+
if (newParent != parent) {
if (parent != null) {
parent.detach(this);
@@ -494,6 +597,14 @@ public class CdmaConnection extends Connection {
}
private void
+ doDisconnect() {
+ index = -1;
+ disconnectTime = System.currentTimeMillis();
+ duration = SystemClock.elapsedRealtime() - connectTimeReal;
+ disconnected = true;
+ }
+
+ private void
onStartedHolding() {
holdingStartTime = SystemClock.elapsedRealtime();
}
@@ -507,25 +618,13 @@ public class CdmaConnection extends Connection {
if (PhoneNumberUtils.is12Key(c)) {
owner.cm.sendDtmf(c, h.obtainMessage(EVENT_DTMF_DONE));
} else if (c == PhoneNumberUtils.PAUSE) {
- // From TS 22.101:
-
- // "The first occurrence of the "DTMF Control Digits Separator"
- // shall be used by the ME to distinguish between the addressing
- // digits (i.e. the phone number) and the DTMF digits...."
+ setPostDialState(PostDialState.PAUSE);
- if (nextPostDialChar == 1) {
- // The first occurrence.
- // We don't need to pause here, but wait for just a bit anyway
- h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
- PAUSE_DELAY_FIRST_MILLIS);
- } else {
- // It continues...
- // "Upon subsequent occurrences of the separator, the UE shall
- // pause again for 3 seconds (\u00B1 20 %) before sending any
- // further DTMF digits."
- h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
+ // Upon occurrences of the separator, the UE shall
+ // pause again for 2 seconds before sending any
+ // further DTMF digits.
+ h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
PAUSE_DELAY_MILLIS);
- }
} else if (c == PhoneNumberUtils.WAIT) {
setPostDialState(PostDialState.WAIT);
} else if (c == PhoneNumberUtils.WILD) {
@@ -537,19 +636,38 @@ public class CdmaConnection extends Connection {
return true;
}
- public String
- getRemainingPostDialString() {
+ public String getRemainingPostDialString() {
if (postDialState == PostDialState.CANCELLED
- || postDialState == PostDialState.COMPLETE
- || postDialString == null
- || postDialString.length() <= nextPostDialChar
- ) {
+ || postDialState == PostDialState.COMPLETE
+ || postDialString == null
+ || postDialString.length() <= nextPostDialChar) {
return "";
}
- return postDialString.substring(nextPostDialChar);
+ String subStr = postDialString.substring(nextPostDialChar);
+ if (subStr != null) {
+ int wIndex = subStr.indexOf(PhoneNumberUtils.WAIT);
+ int pIndex = subStr.indexOf(PhoneNumberUtils.PAUSE);
+
+ if (wIndex > 0 && (wIndex < pIndex || pIndex <= 0)) {
+ subStr = subStr.substring(0, wIndex);
+ } else if (pIndex > 0) {
+ subStr = subStr.substring(0, pIndex);
+ }
+ }
+ return subStr;
}
-
+
+ public void updateParent(CdmaCall oldParent, CdmaCall newParent){
+ if (newParent != oldParent) {
+ if (oldParent != null) {
+ oldParent.detach(this);
+ }
+ newParent.attachFake(this, CdmaCall.State.ACTIVE);
+ parent = newParent;
+ }
+ }
+
@Override
protected void finalize()
{
@@ -565,8 +683,7 @@ public class CdmaConnection extends Connection {
releaseWakeLock();
}
- private void
- processNextPostDialChar() {
+ void processNextPostDialChar() {
char c = 0;
Registrant postDialHandler;
@@ -583,7 +700,7 @@ public class CdmaConnection extends Connection {
c = 0;
} else {
boolean isValid;
-
+
setPostDialState(PostDialState.STARTED);
c = postDialString.charAt(nextPostDialChar++);
@@ -653,47 +770,164 @@ public class CdmaConnection extends Connection {
}
/**
- * Set post dial state and acquire wake lock while switching to "started"
- * state, the wake lock will be released if state switches out of "started"
- * state or after WAKE_LOCK_TIMEOUT_MILLIS.
+ * Set post dial state and acquire wake lock while switching to "started"
+ * state, the wake lock will be released if state switches out of "started"
+ * state or after WAKE_LOCK_TIMEOUT_MILLIS.
* @param s new PostDialState
*/
private void setPostDialState(PostDialState s) {
- if (postDialState != PostDialState.STARTED
+ if (postDialState != PostDialState.STARTED
&& s == PostDialState.STARTED) {
acquireWakeLock();
Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS);
- } else if (postDialState == PostDialState.STARTED
+ } else if (postDialState == PostDialState.STARTED
&& s != PostDialState.STARTED) {
h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
releaseWakeLock();
}
postDialState = s;
}
-
- private void
- createWakeLock(Context context) {
- PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+
+ private void createWakeLock(Context context) {
+ PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
}
-
- private void
- acquireWakeLock() {
+
+ private void acquireWakeLock() {
log("acquireWakeLock");
mPartialWakeLock.acquire();
}
- private void
- releaseWakeLock() {
- synchronized(mPartialWakeLock) {
+ private void releaseWakeLock() {
+ synchronized (mPartialWakeLock) {
if (mPartialWakeLock.isHeld()) {
log("releaseWakeLock");
mPartialWakeLock.release();
}
}
}
-
+
+ private static boolean isPause(char c) {
+ return c == PhoneNumberUtils.PAUSE;
+ }
+
+ private static boolean isWait(char c) {
+ return c == PhoneNumberUtils.WAIT;
+ }
+
+
+
+
+ // This function is to find the next PAUSE character index if
+ // multiple pauses in a row. Otherwise it finds the next non PAUSE or
+ // non WAIT character index.
+ private static int
+ findNextPCharOrNonPOrNonWCharIndex(String phoneNumber, int currIndex) {
+ boolean wMatched = false;
+ int index = currIndex + 1;
+ int length = phoneNumber.length();
+ while (index < length) {
+ char cNext = phoneNumber.charAt(index);
+ // if there is any W inside P/W sequence,mark it
+ if (isWait(cNext)) {
+ wMatched = true;
+ }
+ // if any characters other than P/W chars after P/W sequence
+ // we break out the loop and append the correct
+ if (!isWait(cNext) && !isPause(cNext)) {
+ break;
+ }
+ index++;
+ }
+
+ // It means the PAUSE character(s) is in the middle of dial string
+ // and it needs to be handled one by one.
+ if ((index < length) && (index > (currIndex + 1)) &&
+ ((wMatched == false) && isPause(phoneNumber.charAt(currIndex)))) {
+ return (currIndex + 1);
+ }
+ return index;
+ }
+
+ // This function returns either PAUSE or WAIT character to append.
+ // It is based on the next non PAUSE/WAIT character in the phoneNumber and the
+ // index for the current PAUSE/WAIT character
+ private static char
+ findPOrWCharToAppend(String phoneNumber, int currPwIndex, int nextNonPwCharIndex) {
+ char c = phoneNumber.charAt(currPwIndex);
+ char ret;
+
+ // Append the PW char
+ ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT;
+
+ // if there is a PAUSE in at the begining of PW character sequences, and this
+ // PW character sequences has more than 2 PAUSE and WAIT Characters,skip P, append W
+ if (isPause(c) && (nextNonPwCharIndex > (currPwIndex + 1))) {
+ ret = PhoneNumberUtils.WAIT;
+ }
+ return ret;
+ }
+
+
+ /**
+ * format orignal dial string
+ * 1) convert international dialing prefix "+" to
+ * string specified per region
+ *
+ * 2) handle corner cases for PAUSE/WAIT dialing:
+ *
+ * If PAUSE/WAIT sequence at the end, ignore them.
+ *
+ * If consecutive PAUSE/WAIT sequence in the middle of the string,
+ * and if there is any WAIT in PAUSE/WAIT sequence, treat them like WAIT.
+ */
+ public static String formatDialString(String phoneNumber) {
+ if (phoneNumber == null) {
+ return null;
+ }
+ int length = phoneNumber.length();
+ StringBuilder ret = new StringBuilder();
+ char c;
+ int currIndex = 0;
+ while (currIndex < length) {
+ c = phoneNumber.charAt(currIndex);
+ if (PhoneNumberUtils.isDialable(c)) {
+ if (c == '+') {
+ String ps = null;
+ SystemProperties.get(TelephonyProperties.PROPERTY_IDP_STRING, ps);
+ if (TextUtils.isEmpty(ps)) {
+ ps = "011";
+ }
+ ret.append(ps);
+ } else {
+ ret.append(c);
+ }
+ } else if (isPause(c) || isWait(c)) {
+ if (currIndex < length - 1) {
+ // if PW not at the end
+ int nextIndex = findNextPCharOrNonPOrNonWCharIndex(phoneNumber, currIndex);
+ // If there is non PW char following PW sequence
+ if (nextIndex < length) {
+ char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex);
+ ret.append(pC);
+ // If PW char is immediately followed by non-PW char
+ if (nextIndex > (currIndex + 1)) {
+ currIndex = nextIndex - 1;
+ }
+ } else if (nextIndex == length) {
+ // It means PW characters at the end, ignore
+ currIndex = length - 1;
+ }
+ }
+ } else {
+ ret.append(c);
+ }
+ currIndex++;
+ }
+ return ret.toString();
+ }
+
private void log(String msg) {
Log.d(LOG_TAG, "[CDMAConn] " + msg);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index 2cbad78..f2b07a8 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -146,12 +146,16 @@ public class CdmaDataConnection extends DataConnection {
null, obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
}
+ private void tearDownData(Message msg) {
+ if (phone.mCM.getRadioState().isOn()) {
+ phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
+ }
+ }
+
protected void disconnect(Message msg) {
onDisconnect = msg;
if (state == State.ACTIVE) {
- if (phone.mCM.getRadioState().isOn()) {
- phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
- }
+ tearDownData(msg);
} else if (state == State.ACTIVATING) {
receivedDisconnectReq = true;
} else {
@@ -229,7 +233,7 @@ public class CdmaDataConnection extends DataConnection {
switch (rilCause) {
case PS_NET_DOWN_REASON_OPERATOR_DETERMINED_BARRING:
- cause = FailCause.BARRED;
+ cause = FailCause.OPERATOR_BARRED;
break;
case PS_NET_DOWN_REASON_AUTH_FAILED:
cause = FailCause.USER_AUTHENTICATION;
@@ -280,7 +284,7 @@ public class CdmaDataConnection extends DataConnection {
// Don't bother reporting success if there's already a
// pending disconnect request, since DataConnectionTracker
// has already updated its state.
- disconnect(onDisconnect);
+ tearDownData(onDisconnect);
} else {
String[] response = ((String[]) ar.result);
cid = Integer.parseInt(response[0]);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 651c505..c3818f5 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -26,38 +26,31 @@ import android.content.SharedPreferences;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncResult;
-import android.os.Handler;
import android.os.INetStatService;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.preference.PreferenceManager;
import android.provider.Checkin;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
-import android.util.EventLog;
+import android.telephony.cdma.CdmaCellLocation;
import android.text.TextUtils;
+import android.util.EventLog;
import android.util.Log;
import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.DataConnection.FailCause;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.TelephonyEventLog;
import java.util.ArrayList;
/**
- * WINK:TODO: In GsmDataConnectionTracker there are
- * EventLog's used quite a few places maybe
- * more need to be added in this file?
- *
* {@hide}
*/
public final class CdmaDataConnectionTracker extends DataConnectionTracker {
@@ -69,6 +62,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
// Indicates baseband will not auto-attach
private boolean noAutoAttach = false;
long nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ private boolean mReregisterOnReconnectFailure = false;
private boolean mIsScreenOn = true;
//useful for debugging
@@ -98,6 +92,14 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
"com.android.internal.telephony.cdma-reconnect";
private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason";
+ /**
+ * Constants for the data connection activity:
+ * physical link down/up
+ */
+ private static final int DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE = 0;
+ private static final int DATA_CONNECTION_ACTIVE_PH_LINK_DOWN = 1;
+ private static final int DATA_CONNECTION_ACTIVE_PH_LINK_UP = 2;
+
// Possibly promoate to base class, the only difference is
// the INTENT_RECONNECT_ALARM action is a different string.
// Do consider technology changes if it is promoted.
@@ -258,14 +260,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
/**
- * Simply tear down data connections due to radio off
- * and don't setup again.
- */
- public void cleanConnectionBeforeRadioOff() {
- cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
- }
-
- /**
* The data connection is expected to be setup while device
* 1. has ruim card or non-volatile data store
* 2. registered to data connection service
@@ -304,13 +298,14 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
Log.d(LOG_TAG, "setDataEnabled("+enable+") isEnabled=" + isEnabled);
if (!isEnabled && enable) {
setEnabled(EXTERNAL_NETWORK_DEFAULT_ID, true);
- return trySetupData(Phone.REASON_DATA_ENABLED);
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
} else if (!enable) {
setEnabled(EXTERNAL_NETWORK_DEFAULT_ID, false);
- cleanUpConnection(true, Phone.REASON_DATA_DISABLED);
- return true;
- } else // isEnabled && enable
-
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 1; // tearDown is true
+ msg.obj = Phone.REASON_DATA_DISABLED;
+ sendMessage(msg);
+ }
return true;
}
@@ -355,16 +350,16 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
int psState = mCdmaPhone.mSST.getCurrentCdmaDataConnectionState();
boolean roaming = phone.getServiceState().getRoaming();
+ boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
if ((state == State.IDLE || state == State.SCANNING)
- && (psState == ServiceState.RADIO_TECHNOLOGY_1xRTT ||
- psState == ServiceState.RADIO_TECHNOLOGY_EVDO_0 ||
- psState == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
+ && (psState == ServiceState.STATE_IN_SERVICE)
&& ((phone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY) ||
mCdmaPhone.mRuimRecords.getRecordsLoaded())
&& (mCdmaPhone.mSST.isConcurrentVoiceAndData() ||
phone.getState() == Phone.State.IDLE )
- && isDataAllowed()) {
+ && isDataAllowed()
+ && desiredPowerState) {
return setupData(reason);
@@ -379,7 +374,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
" phoneState=" + phone.getState() +
" dataEnabled=" + getAnyDataEnabled() +
" roaming=" + roaming +
- " dataOnRoamingEnable=" + getDataOnRoamingEnabled());
+ " dataOnRoamingEnable=" + getDataOnRoamingEnabled() +
+ " desiredPowerState=" + desiredPowerState);
}
return false;
}
@@ -405,6 +401,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
mReconnectIntent = null;
}
+ setState(State.DISCONNECTING);
+
for (DataConnection connBase : dataConnectionList) {
CdmaDataConnection conn = (CdmaDataConnection) connBase;
@@ -420,24 +418,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
stopNetStatPoll();
- /*
- * If we've been asked to tear down the connection,
- * set the state to DISCONNECTING. However, there's
- * a race that can occur if for some reason we were
- * already in the IDLE state. In that case, the call
- * to conn.disconnect() above will immediately post
- * a message to the handler thread that the disconnect
- * is done, and if the handler runs before the code
- * below does, the handler will have set the state to
- * IDLE before the code below runs. If we didn't check
- * for that, future calls to trySetupData would fail,
- * and we would never get out of the DISCONNECTING state.
- */
if (!tearDown) {
setState(State.IDLE);
phone.notifyDataConnection(reason);
- } else if (state != State.IDLE) {
- setState(State.DISCONNECTING);
}
}
@@ -478,6 +461,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
startNetStatPoll();
// reset reconnect timer
nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ mReregisterOnReconnectFailure = false;
}
private void resetPollStats() {
@@ -515,7 +499,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
* override it with an unconditional power on.
*/
}
-
+
private Runnable mPollNetStat = new Runnable() {
public void run() {
@@ -570,7 +554,14 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
if (sentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) {
- // we already have NUMBER_SENT_PACKETS sent without ack
+ // Packets sent without ack exceeded threshold.
+
+ if (mNoRecvPollCount == 0) {
+ EventLog.writeEvent(
+ TelephonyEventLog.EVENT_LOG_RADIO_RESET_COUNTDOWN_TRIGGERED,
+ sentSinceLastRecv);
+ }
+
if (mNoRecvPollCount < NO_RECV_POLL_LIMIT) {
mNoRecvPollCount++;
// Slow down the poll interval to let things happen
@@ -582,6 +573,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
netStatPollEnabled = false;
stopNetStatPoll();
restartRadio();
+ EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_RADIO_RESET,
+ NO_RECV_POLL_LIMIT);
}
} else {
mNoRecvPollCount = 0;
@@ -608,22 +601,37 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
/**
* Return true if data connection need to be setup after disconnected due to
* reason.
- *
+ *
* @param reason the reason why data is disconnected
- * @return true if try setup data connection is need for this reason
+ * @return true if try setup data connection is need for this reason
*/
private boolean retryAfterDisconnected(String reason) {
boolean retry = true;
-
+
if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
- Phone.REASON_DATA_DISABLED.equals(reason) ) {
+ Phone.REASON_DATA_DISABLED.equals(reason) ) {
retry = false;
}
return retry;
- }
+ }
private void reconnectAfterFail(FailCause lastFailCauseCode, String reason) {
if (state == State.FAILED) {
+ if (nextReconnectDelay > RECONNECT_DELAY_MAX_MILLIS) {
+ if (mReregisterOnReconnectFailure) {
+ // We have already tried to re-register to the network.
+ // This might be a problem with the data network.
+ nextReconnectDelay = RECONNECT_DELAY_MAX_MILLIS;
+ } else {
+ // Try to Re-register to the network.
+ Log.d(LOG_TAG, "PDP activate failed, Reregistering to the network");
+ mReregisterOnReconnectFailure = true;
+ mCdmaPhone.mSST.reRegisterNetwork(null);
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ return;
+ }
+ }
+
Log.d(LOG_TAG, "Data Connection activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
@@ -639,9 +647,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
// double it for next time
nextReconnectDelay *= 2;
- if (nextReconnectDelay > RECONNECT_DELAY_MAX_MILLIS) {
- nextReconnectDelay = RECONNECT_DELAY_MAX_MILLIS;
- }
if (!shouldPostNotification(lastFailCauseCode)) {
Log.d(LOG_TAG,"NOT Posting Data Connection Unavailable notification "
@@ -660,7 +665,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
if (state == State.FAILED) {
cleanUpConnection(false, null);
}
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED));
}
protected void onNVReady() {
@@ -673,8 +678,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
- protected void onTrySetupData() {
- trySetupData(null);
+ protected void onTrySetupData(String reason) {
+ trySetupData(reason);
}
/**
@@ -721,6 +726,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
// Make sure our reconnect delay starts at the initial value
// next time the radio comes on
nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ mReregisterOnReconnectFailure = false;
if (phone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
@@ -751,13 +757,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
// No try for permanent failure
if (cause.isPermanentFail()) {
notifyNoData(cause);
+ return;
}
-
- if (tryAgain(cause)) {
- trySetupData(reason);
- } else {
- startDelayedRetry(cause, reason);
- }
+ startDelayedRetry(cause, reason);
}
}
@@ -800,17 +802,19 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
resetPollStats();
}
} else {
+ // reset reconnect timer
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ mReregisterOnReconnectFailure = false;
// in case data setup was attempted when we were on a voice call
trySetupData(Phone.REASON_VOICE_CALL_ENDED);
}
}
- private boolean tryAgain(FailCause cause) {
- return (cause != FailCause.RADIO_NOT_AVAILABLE)
- && (cause != FailCause.RADIO_OFF)
- && (cause != FailCause.RADIO_ERROR_RETRY)
- && (cause != FailCause.NO_SIGNAL)
- && (cause != FailCause.SIM_LOCKED);
+ /**
+ * @override com.android.internal.telephony.DataConnectionTracker
+ */
+ protected void onCleanUpConnection(boolean tearDown, String reason) {
+ cleanUpConnection(tearDown, reason);
}
private void createAllDataConnectionList() {
@@ -829,7 +833,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
}
- private void onCdmaDataAttached() {
+ private void onCdmaDataDetached() {
if (state == State.CONNECTED) {
startNetStatPoll();
phone.notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED);
@@ -837,12 +841,29 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
if (state == State.FAILED) {
cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED);
nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+
+ CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
+ int bsid = (loc != null) ? loc.getBaseStationId() : -1;
+
+ EventLog.List val = new EventLog.List(bsid,
+ TelephonyManager.getDefault().getNetworkType());
+ EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_CDMA_DATA_SETUP_FAILED, val);
}
trySetupData(Phone.REASON_CDMA_DATA_DETACHED);
}
}
+ private void writeEventLogCdmaDataDrop() {
+ CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
+ int bsid = (loc != null) ? loc.getBaseStationId() : -1;
+ EventLog.List val = new EventLog.List(bsid,
+ TelephonyManager.getDefault().getNetworkType());
+ EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_CDMA_DATA_DROP, val);
+ }
+
protected void onDataStateChanged (AsyncResult ar) {
+ ArrayList<DataCallState> dataCallStates = (ArrayList<DataCallState>)(ar.result);
+
if (ar.exception != null) {
// This is probably "radio not available" or something
// of that sort. If so, the whole connection is going
@@ -851,16 +872,37 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
if (state == State.CONNECTED) {
- Log.i(LOG_TAG, "Data connection has changed.");
-
- int cid = -1;
- EventLog.List val = new EventLog.List(cid,
- TelephonyManager.getDefault().getNetworkType());
- EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_PDP_NETWORK_DROP, val);
-
- cleanUpConnection(true, null);
+ if (dataCallStates.size() >= 1) {
+ switch (dataCallStates.get(0).active) {
+ case DATA_CONNECTION_ACTIVE_PH_LINK_UP:
+ Log.v(LOG_TAG, "onDataStateChanged: active=LINK_ACTIVE && CONNECTED, ignore");
+ activity = Activity.NONE;
+ phone.notifyDataActivity();
+ break;
+ case DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE:
+ Log.v(LOG_TAG,
+ "onDataStateChanged active=LINK_INACTIVE && CONNECTED, disconnecting/cleanup");
+ writeEventLogCdmaDataDrop();
+ cleanUpConnection(true, null);
+ break;
+ case DATA_CONNECTION_ACTIVE_PH_LINK_DOWN:
+ Log.v(LOG_TAG, "onDataStateChanged active=LINK_DOWN && CONNECTED, dormant");
+ activity = Activity.DORMANT;
+ phone.notifyDataActivity();
+ break;
+ default:
+ Log.v(LOG_TAG, "onDataStateChanged: IGNORE unexpected DataCallState.active="
+ + dataCallStates.get(0).active);
+ }
+ } else {
+ Log.v(LOG_TAG, "onDataStateChanged: network disconnected, clean up");
+ writeEventLogCdmaDataDrop();
+ cleanUpConnection(true, null);
+ }
+ } else {
+ // TODO: Do we need to do anything?
+ Log.i(LOG_TAG, "onDataStateChanged: not connected, state=" + state + " ignoring");
}
- Log.i(LOG_TAG, "Data connection has changed.");
}
String getInterfaceName() {
@@ -912,7 +954,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
break;
case EVENT_CDMA_DATA_DETACHED:
- onCdmaDataAttached();
+ onCdmaDataDetached();
break;
case EVENT_DATA_STATE_CHANGED:
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java
new file mode 100644
index 0000000..7402769
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java
@@ -0,0 +1,263 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.telephony.cdma;
+import static com.android.internal.telephony.RILConstants.*;
+import android.os.Parcel;
+
+public final class CdmaInformationRecords {
+ public Object record;
+
+ /**
+ * Record type identifier
+ */
+ public static final int RIL_CDMA_DISPLAY_INFO_REC = 0;
+ public static final int RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC = 1;
+ public static final int RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC = 2;
+ public static final int RIL_CDMA_CONNECTED_NUMBER_INFO_REC = 3;
+ public static final int RIL_CDMA_SIGNAL_INFO_REC = 4;
+ public static final int RIL_CDMA_REDIRECTING_NUMBER_INFO_REC = 5;
+ public static final int RIL_CDMA_LINE_CONTROL_INFO_REC = 6;
+ public static final int RIL_CDMA_EXTENDED_DISPLAY_INFO_REC = 7;
+ public static final int RIL_CDMA_T53_CLIR_INFO_REC = 8;
+ public static final int RIL_CDMA_T53_RELEASE_INFO_REC = 9;
+ public static final int RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC = 10;
+
+ public CdmaInformationRecords(Parcel p) {
+ int id = p.readInt();
+ switch (id) {
+ case RIL_CDMA_DISPLAY_INFO_REC:
+ case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
+ record = new CdmaDisplayInfoRec(id, p.readString());
+ break;
+
+ case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
+ case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
+ case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
+ record = new CdmaNumberInfoRec(id, p.readString(), p.readInt(), p.readInt(),
+ p.readInt(), p.readInt());
+ break;
+
+ case RIL_CDMA_SIGNAL_INFO_REC:
+ record = new CdmaSignalInfoRec(p.readInt(), p.readInt(), p.readInt(), p.readInt());
+ break;
+
+ case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
+ record = new CdmaRedirectingNumberInfoRec(p.readString(), p.readInt(), p.readInt(),
+ p.readInt(), p.readInt(), p.readInt());
+ break;
+
+ case RIL_CDMA_LINE_CONTROL_INFO_REC:
+ record = new CdmaLineControlInfoRec(p.readInt(), p.readInt(), p.readInt(),
+ p.readInt());
+ break;
+
+ case RIL_CDMA_T53_CLIR_INFO_REC:
+ record = new CdmaT53ClirInfoRec(p.readInt());
+ break;
+
+ case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
+ record = new CdmaT53AudioControlInfoRec(p.readInt(), p.readInt());
+ break;
+
+ case RIL_CDMA_T53_RELEASE_INFO_REC:
+ // TODO(Moto): WHAT to do, for now fall through and throw exception
+ default:
+ throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got "
+ + CdmaInformationRecords.idToString(id) + " ");
+
+ }
+ }
+
+ public static String idToString(int id) {
+ switch(id) {
+ case RIL_CDMA_DISPLAY_INFO_REC: return "RIL_CDMA_DISPLAY_INFO_REC";
+ case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: return "RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC";
+ case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: return "RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC";
+ case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: return "RIL_CDMA_CONNECTED_NUMBER_INFO_REC";
+ case RIL_CDMA_SIGNAL_INFO_REC: return "RIL_CDMA_SIGNAL_INFO_REC";
+ case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: return "RIL_CDMA_REDIRECTING_NUMBER_INFO_REC";
+ case RIL_CDMA_LINE_CONTROL_INFO_REC: return "RIL_CDMA_LINE_CONTROL_INFO_REC";
+ case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: return "RIL_CDMA_EXTENDED_DISPLAY_INFO_REC";
+ case RIL_CDMA_T53_CLIR_INFO_REC: return "RIL_CDMA_T53_CLIR_INFO_REC";
+ case RIL_CDMA_T53_RELEASE_INFO_REC: return "RIL_CDMA_T53_RELEASE_INFO_REC";
+ case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: return "RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC";
+ default: return "<unknown record>";
+ }
+ }
+
+ /**
+ * Signal Information record from 3GPP2 C.S005 3.7.5.5
+ */
+ public static class CdmaSignalInfoRec {
+ public boolean isPresent; /* non-zero if signal information record is present */
+ public int signalType;
+ public int alertPitch;
+ public int signal;
+
+ public CdmaSignalInfoRec() {}
+
+ public CdmaSignalInfoRec(int isPresent, int signalType, int alertPitch, int signal) {
+ this.isPresent = isPresent != 0;
+ this.signalType = signalType;
+ this.alertPitch = alertPitch;
+ this.signal = signal;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaSignalInfo: {" +
+ " isPresent: " + isPresent +
+ ", signalType: " + signalType +
+ ", alertPitch: " + alertPitch +
+ ", signal: " + signal +
+ " }";
+ }
+ }
+
+ public static class CdmaDisplayInfoRec {
+ public int id;
+ public String alpha;
+
+ public CdmaDisplayInfoRec(int id, String alpha) {
+ this.id = id;
+ this.alpha = alpha;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaDisplayInfoRec: {" +
+ " id: " + CdmaInformationRecords.idToString(id) +
+ ", alpha: " + alpha +
+ " }";
+ }
+ }
+
+ public static class CdmaNumberInfoRec {
+ public int id;
+ public String number;
+ public byte numberType;
+ public byte numberPlan;
+ public byte pi;
+ public byte si;
+
+ public CdmaNumberInfoRec(int id, String number, int numberType, int numberPlan, int pi,
+ int si) {
+ this.number = number;
+ this.numberType = (byte)numberType;
+ this.numberPlan = (byte)numberPlan;
+ this.pi = (byte)pi;
+ this.si = (byte)si;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaNumberInfoRec: {" +
+ " id: " + CdmaInformationRecords.idToString(id) +
+ ", number: " + number +
+ ", numberType: " + numberType +
+ ", numberPlan: " + numberPlan +
+ ", pi: " + pi +
+ ", si: " + si +
+ " }";
+ }
+ }
+
+ public static class CdmaRedirectingNumberInfoRec {
+ public static final int REASON_UNKNOWN = 0;
+ public static final int REASON_CALL_FORWARDING_BUSY = 1;
+ public static final int REASON_CALL_FORWARDING_NO_REPLY = 2;
+ public static final int REASON_CALLED_DTE_OUT_OF_ORDER = 9;
+ public static final int REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10;
+ public static final int REASON_CALL_FORWARDING_UNCONDITIONAL = 15;
+
+ public CdmaNumberInfoRec numberInfoRec;
+ public int redirectingReason;
+
+ public CdmaRedirectingNumberInfoRec(String number, int numberType, int numberPlan,
+ int pi, int si, int reason) {
+ numberInfoRec = new CdmaNumberInfoRec(RIL_CDMA_REDIRECTING_NUMBER_INFO_REC,
+ number, numberType, numberPlan, pi, si);
+ redirectingReason = reason;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaNumberInfoRec: {" +
+ " numberInfoRec: " + numberInfoRec +
+ ", redirectingReason: " + redirectingReason +
+ " }";
+ }
+ }
+
+ public static class CdmaLineControlInfoRec {
+ public byte lineCtrlPolarityIncluded;
+ public byte lineCtrlToggle;
+ public byte lineCtrlReverse;
+ public byte lineCtrlPowerDenial;
+
+ public CdmaLineControlInfoRec(int lineCtrlPolarityIncluded, int lineCtrlToggle,
+ int lineCtrlReverse, int lineCtrlPowerDenial) {
+ this.lineCtrlPolarityIncluded = (byte)lineCtrlPolarityIncluded;
+ this.lineCtrlToggle = (byte)lineCtrlToggle;
+ this.lineCtrlReverse = (byte)lineCtrlReverse;
+ this.lineCtrlPowerDenial = (byte)lineCtrlPowerDenial;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaLineControlInfoRec: {" +
+ " lineCtrlPolarityIncluded: " + lineCtrlPolarityIncluded +
+ " lineCtrlToggle: " + lineCtrlToggle +
+ " lineCtrlReverse: " + lineCtrlReverse +
+ " lineCtrlPowerDenial: " + lineCtrlPowerDenial +
+ " }";
+ }
+ }
+
+ public static class CdmaT53ClirInfoRec {
+ public byte cause;
+
+ public CdmaT53ClirInfoRec(int cause) {
+ this.cause = (byte)cause;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaT53ClirInfoRec: {" +
+ " cause: " + cause +
+ " }";
+ }
+ }
+
+ public static class CdmaT53AudioControlInfoRec {
+ public byte uplink;
+ public byte downlink;
+
+ public CdmaT53AudioControlInfoRec(int uplink, int downlink) {
+ this.uplink = (byte) uplink;
+ this.downlink = (byte) downlink;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaT53AudioControlInfoRec: {" +
+ " uplink: " + uplink +
+ " downlink: " + downlink +
+ " }";
+ }
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 42c0583..ecdc8f6 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -17,21 +17,27 @@
package com.android.internal.telephony.cdma;
+import android.app.Activity;
import android.app.PendingIntent;
import android.content.ContentValues;
+import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.SQLException;
import android.os.AsyncResult;
import android.os.Message;
+import android.provider.Telephony;
+import android.provider.Telephony.Sms.Intents;
+import android.preference.PreferenceManager;
import android.util.Config;
import android.util.Log;
+import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
import com.android.internal.telephony.SMSDispatcher;
-//import com.android.internal.telephony.SMSDispatcher.SmsTracker;
import com.android.internal.telephony.cdma.SmsMessage;
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.ByteArrayOutputStream;
@@ -42,8 +48,11 @@ import java.util.HashMap;
final class CdmaSMSDispatcher extends SMSDispatcher {
private static final String TAG = "CDMA";
+ private CDMAPhone mCdmaPhone;
+
CdmaSMSDispatcher(CDMAPhone phone) {
super(phone);
+ mCdmaPhone = phone;
}
/**
@@ -58,147 +67,88 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
Log.d(TAG, "handleStatusReport is a special GSM function, should never be called in CDMA!");
}
- /**
- * Dispatches an incoming SMS messages.
- *
- * @param smsb the incoming message from the phone
- */
- protected void dispatchMessage(SmsMessageBase smsb) {
+ /** {@inheritDoc} */
+ protected int dispatchMessage(SmsMessageBase smsb) {
// If sms is null, means there was a parsing error.
- // TODO: Should NAK this.
if (smsb == null) {
- return;
+ return Intents.RESULT_SMS_GENERIC_ERROR;
}
- SmsMessage sms = (SmsMessage) smsb;
- int teleService;
- boolean handled = false;
// Decode BD stream and set sms variables.
+ SmsMessage sms = (SmsMessage) smsb;
sms.parseSms();
- teleService = sms.getTeleService();
-
- // Teleservices W(E)MT and VMN are handled together:
- if ((SmsEnvelope.TELESERVICE_WMT == teleService)
- ||(SmsEnvelope.TELESERVICE_WEMT == teleService)
- ||(SmsEnvelope.TELESERVICE_VMN == teleService)){
- // From here on we need decoded BD.
- // Special case the message waiting indicator messages
- if (sms.isMWISetMessage()) {
- ((CDMAPhone) mPhone).updateMessageWaitingIndicator(true);
-
- if (sms.isMwiDontStore()) {
- handled = true;
- }
-
- if (Config.LOGD) {
- Log.d(TAG,
- "Received voice mail indicator set SMS shouldStore=" + !handled);
- }
- } else if (sms.isMWIClearMessage()) {
- ((CDMAPhone) mPhone).updateMessageWaitingIndicator(false);
-
- if (sms.isMwiDontStore()) {
- handled = true;
- }
-
- if (Config.LOGD) {
- Log.d(TAG,
- "Received voice mail indicator clear SMS shouldStore=" + !handled);
- }
- }
- }
+ int teleService = sms.getTeleService();
+ boolean handled = false;
- if (null == sms.getUserData()){
- handled = true;
+ if (sms.getUserData() == null) {
if (Config.LOGD) {
Log.d(TAG, "Received SMS without user data");
}
+ handled = true;
}
- if (handled) return;
-
- if (SmsEnvelope.TELESERVICE_WAP == teleService){
- processCdmaWapPdu(sms.getUserData(), sms.messageRef, sms.getOriginatingAddress());
- return;
+ if (handled) {
+ return Intents.RESULT_SMS_HANDLED;
}
- // Parse the headers to see if this is partial, or port addressed
- int referenceNumber = -1;
- int count = 0;
- int sequence = 0;
- int destPort = -1;
- // From here on we need BD distributed to SMS member variables.
-
- SmsHeader header = sms.getUserDataHeader();
- if (header != null) {
- for (SmsHeader.Element element : header.getElements()) {
- try {
- switch (element.getID()) {
- case SmsHeader.CONCATENATED_8_BIT_REFERENCE: {
- byte[] data = element.getData();
-
- referenceNumber = data[0] & 0xff;
- count = data[1] & 0xff;
- sequence = data[2] & 0xff;
-
- // Per TS 23.040, 9.2.3.24.1: If the count is zero, sequence
- // is zero, or sequence > count, ignore the entire element
- if (count == 0 || sequence == 0 || sequence > count) {
- referenceNumber = -1;
- }
- break;
- }
-
- case SmsHeader.CONCATENATED_16_BIT_REFERENCE: {
- byte[] data = element.getData();
-
- referenceNumber = (data[0] & 0xff) * 256 + (data[1] & 0xff);
- count = data[2] & 0xff;
- sequence = data[3] & 0xff;
-
- // Per TS 23.040, 9.2.3.24.8: If the count is zero, sequence
- // is zero, or sequence > count, ignore the entire element
- if (count == 0 || sequence == 0 || sequence > count) {
- referenceNumber = -1;
- }
- break;
- }
-
- case SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT: {
- byte[] data = element.getData();
-
- destPort = (data[0] & 0xff) << 8;
- destPort |= (data[1] & 0xff);
-
- break;
- }
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- Log.e(TAG, "Bad element in header", e);
- return; // TODO: NACK the message or something, don't just discard.
- }
- }
+ if (SmsEnvelope.TELESERVICE_WAP == teleService){
+ return processCdmaWapPdu(sms.getUserData(), sms.messageRef,
+ sms.getOriginatingAddress());
+ } else if (SmsEnvelope.TELESERVICE_VMN == teleService) {
+ // handling Voicemail
+ int voicemailCount = sms.getNumOfVoicemails();
+ Log.d(TAG, "Voicemail count=" + voicemailCount);
+ // Store the voicemail count in preferences.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
+ ((CDMAPhone) mPhone).getContext());
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount);
+ editor.commit();
+ ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount);
+ return Intents.RESULT_SMS_HANDLED;
}
- if (referenceNumber == -1) {
- // notify everyone of the message if it isn't partial
+ /**
+ * TODO(cleanup): Why are we using a getter method for this
+ * (and for so many other sms fields)? Trivial getters and
+ * setters like this are direct violations of the style guide.
+ * If the purpose is to protect agaist writes (by not
+ * providing a setter) then any protection is illusory (and
+ * hence bad) for cases where the values are not primitives,
+ * such as this call for the header. Since this is an issue
+ * with the public API it cannot be changed easily, but maybe
+ * something can be done eventually.
+ */
+ SmsHeader smsHeader = sms.getUserDataHeader();
+
+ /**
+ * TODO(cleanup): Since both CDMA and GSM use the same header
+ * format, this dispatch processing is naturally identical,
+ * and code should probably not be replicated explicitly.
+ */
+ // See if message is partial or port addressed.
+ if ((smsHeader == null) || (smsHeader.concatRef == null)) {
+ // Message is not partial (not part of concatenated sequence).
byte[][] pdus = new byte[1][];
pdus[0] = sms.getPdu();
- if (destPort != -1) {// GSM-style WAP indication
- if (destPort == SmsHeader.PORT_WAP_PUSH) {
- mWapPush.dispatchWapPdu(sms.getUserData());
+ if (smsHeader != null && smsHeader.portAddrs != null) {
+ if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) {
+ // GSM-style WAP indication
+ return mWapPush.dispatchWapPdu(sms.getUserData());
+ } else {
+ // The message was sent to a port, so concoct a URI for it.
+ dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort);
}
- // The message was sent to a port, so concoct a URI for it
- dispatchPortAddressedPdus(pdus, destPort);
} else {
- // It's a normal message, dispatch it
+ // Normal short and non-port-addressed message, dispatch it.
dispatchPdus(pdus);
}
+ return Activity.RESULT_OK;
} else {
- // Process the message part
- processMessagePart(sms, referenceNumber, sequence, count, destPort);
+ // Process the message part.
+ return processMessagePart(sms, smsHeader.concatRef, smsHeader.portAddrs);
}
}
@@ -208,29 +158,35 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
* WDP segments are gathered until a datagram completes and gets dispatched.
*
* @param pdu The WAP-WDP PDU segment
+ * @return a result code from {@link Telephony.Sms.Intents}, or
+ * {@link Activity#RESULT_OK} if the message has been broadcast
+ * to applications
*/
- protected void processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) {
+ protected int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) {
int segment;
int totalSegments;
int index = 0;
int msgType;
- int sourcePort;
- int destinationPort;
+ int sourcePort = 0;
+ int destinationPort = 0;
msgType = pdu[index++];
if (msgType != 0){
Log.w(TAG, "Received a WAP SMS which is not WDP. Discard.");
- return;
+ return Intents.RESULT_SMS_HANDLED;
}
totalSegments = pdu[index++]; // >=1
segment = pdu[index++]; // >=0
- //process WDP segment
- sourcePort = (0xFF & pdu[index++]) << 8;
- sourcePort |= 0xFF & pdu[index++];
- destinationPort = (0xFF & pdu[index++]) << 8;
- destinationPort |= 0xFF & pdu[index++];
+ // Only the first segment contains sourcePort and destination Port
+ if (segment == 0) {
+ //process WDP segment
+ sourcePort = (0xFF & pdu[index++]) << 8;
+ sourcePort |= 0xFF & pdu[index++];
+ destinationPort = (0xFF & pdu[index++]) << 8;
+ destinationPort |= 0xFF & pdu[index++];
+ }
// Lookup all other related parts
StringBuilder where = new StringBuilder("reference_number =");
@@ -260,7 +216,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
mResolver.insert(mRawUri, values);
- return;
+ return Intents.RESULT_SMS_HANDLED;
}
// All the parts are in place, deal with them
@@ -271,6 +227,11 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
for (int i = 0; i < cursorCount; i++) {
cursor.moveToNext();
int cursorSequence = (int)cursor.getLong(sequenceColumn);
+ // Read the destination port from the first segment
+ if (cursorSequence == 0) {
+ int destinationPortColumn = cursor.getColumnIndex("destination_port");
+ destinationPort = (int)cursor.getLong(destinationPortColumn);
+ }
pdus[cursorSequence] = HexDump.hexStringToByteArray(
cursor.getString(pduColumn));
}
@@ -280,7 +241,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
mResolver.delete(mRawUri, where.toString(), whereArgs);
} catch (SQLException e) {
Log.e(TAG, "Can't access multipart SMS database", e);
- return; // TODO: NACK the message or something, don't just discard.
+ return Intents.RESULT_SMS_GENERIC_ERROR;
} finally {
if (cursor != null) cursor.close();
}
@@ -300,55 +261,66 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
switch (destinationPort) {
case SmsHeader.PORT_WAP_PUSH:
// Handle the PUSH
- mWapPush.dispatchWapPdu(datagram);
- break;
+ return mWapPush.dispatchWapPdu(datagram);
default:{
pdus = new byte[1][];
pdus[0] = datagram;
// The messages were sent to any other WAP port
dispatchPortAddressedPdus(pdus, destinationPort);
- break;
+ return Activity.RESULT_OK;
}
}
}
/** {@inheritDoc} */
- protected void sendMultipartText(String destinationAddress, String scAddress,
+ protected void sendMultipartText(String destAddr, String scAddr,
ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
ArrayList<PendingIntent> deliveryIntents) {
- int ref = ++sConcatenatedRef & 0xff;
+ /**
+ * 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.
+ */
- for (int i = 0, count = parts.size(); i < count; i++) {
- // build SmsHeader data
- byte[] data = new byte[5];
- data[0] = (byte) SmsHeader.CONCATENATED_8_BIT_REFERENCE;
- data[1] = (byte) 3; // 3 bytes follow
- data[2] = (byte) ref; // reference #, unique per message
- data[3] = (byte) count; // total part count
- data[4] = (byte) (i + 1); // 1-based sequence
+ int refNumber = getNextConcatenatedRef() & 0x00FF;
- PendingIntent sentIntent = null;
- PendingIntent deliveryIntent = null;
+ for (int i = 0, msgCount = parts.size(); i < msgCount; i++) {
+ SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
+ concatRef.refNumber = refNumber;
+ concatRef.seqNumber = i + 1; // 1-based sequence
+ concatRef.msgCount = msgCount;
+ concatRef.isEightBits = true;
+ SmsHeader smsHeader = new SmsHeader();
+ smsHeader.concatRef = concatRef;
+ PendingIntent sentIntent = null;
if (sentIntents != null && sentIntents.size() > i) {
sentIntent = sentIntents.get(i);
}
+
+ PendingIntent deliveryIntent = null;
if (deliveryIntents != null && deliveryIntents.size() > i) {
deliveryIntent = deliveryIntents.get(i);
}
- SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
- parts.get(i), deliveryIntent != null, data);
+ UserData uData = new UserData();
+ uData.payloadStr = parts.get(i);
+ uData.userDataHeader = smsHeader;
+
+ SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destAddr,
+ uData, deliveryIntent != null);
- sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
+ sendSubmitPdu(submitPdu, sentIntent, deliveryIntent);
}
}
- protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
+ protected void sendSubmitPdu(SmsMessage.SubmitPdu submitPdu, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
- super.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
+ sendRawPdu(submitPdu.encodedScAddress, submitPdu.encodedMessage,
+ sentIntent, deliveryIntent);
}
/** {@inheritDoc} */
@@ -369,16 +341,16 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
}
/** {@inheritDoc} */
- protected void acknowledgeLastIncomingSms(boolean success, Message response){
+ protected void acknowledgeLastIncomingSms(boolean success, int result, Message response){
// FIXME unit test leaves cm == null. this should change
if (mCm != null) {
- mCm.acknowledgeLastIncomingCdmaSms(success, response);
+ mCm.acknowledgeLastIncomingCdmaSms(success, resultToCause(result), response);
}
}
/** {@inheritDoc} */
protected void activateCellBroadcastSms(int activate, Message response) {
- mCm.activateCdmaBroadcastSms(activate, response);
+ mCm.setCdmaBroadcastActivation((activate == 0), response);
}
/** {@inheritDoc} */
@@ -391,4 +363,17 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
mCm.setCdmaBroadcastConfig(configValuesArray, response);
}
+ private int resultToCause(int rc) {
+ switch (rc) {
+ case Activity.RESULT_OK:
+ case Intents.RESULT_SMS_HANDLED:
+ // Cause code is ignored on success.
+ return 0;
+ case Intents.RESULT_SMS_OUT_OF_MEMORY:
+ return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE;
+ case Intents.RESULT_SMS_GENERIC_ERROR:
+ default:
+ return CommandsInterface.CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM;
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index d5cad1c..e75a333 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -19,11 +19,15 @@ package com.android.internal.telephony.cdma;
import android.app.AlarmManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.ContentValues;
import android.content.Intent;
import android.database.ContentObserver;
+import android.database.SQLException;
+import android.net.Uri;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
+import android.os.PowerManager;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.SystemClock;
@@ -31,13 +35,17 @@ import android.os.SystemProperties;
import android.provider.Checkin;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
+import android.provider.Telephony;
import android.provider.Telephony.Intents;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
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 java.util.Calendar;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
@@ -65,14 +73,12 @@ import java.util.TimeZone;
* {@hide}
*/
final class CdmaServiceStateTracker extends ServiceStateTracker {
+
//***** Instance Variables
CDMAPhone phone;
CdmaCellLocation cellLoc;
CdmaCellLocation newCellLoc;
- int rssi = 99; // signal strength 0-31, 99=unknown
- // That's "received signal strength indication" fyi
-
/**
* The access technology currently in use: DATA_ACCESS_
*/
@@ -80,35 +86,66 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
private int newNetworkType = 0;
private boolean mCdmaRoaming = false;
+ private int mRoamingIndicator;
+ private boolean mIsInPrl;
+ private int mDefaultRoamingIndicator;
- private int cdmaDataConnectionState = -1;//Initial we assume no data connection
- private int newCdmaDataConnectionState = -1;//Initial we assume no data connection
+ // Initially we assume no data connection
+ private int cdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
+ private int newCdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
private int mRegistrationState = -1;
private RegistrantList cdmaDataConnectionAttachedRegistrants = new RegistrantList();
private RegistrantList cdmaDataConnectionDetachedRegistrants = new RegistrantList();
+ // Sometimes we get the NITZ time before we know what country we are in.
+ // Keep the time zone information from the NITZ string so we can fix
+ // the time zone once know the country.
+ private boolean mNeedFixZone = false;
+ private int mZoneOffset;
+ private boolean mZoneDst;
+ private long mZoneTime;
private boolean mGotCountryCode = false;
+ String mSavedTimeZone;
+ long mSavedTime;
+ long mSavedAtTime;
// We can't register for SIM_RECORDS_LOADED immediately because the
// SIMRecords object may not be instantiated yet.
- private boolean mNeedToRegForRuimLoaded;
+ private boolean mNeedToRegForRuimLoaded = false;
+
+ // Wake lock used while setting time of day.
+ private PowerManager.WakeLock mWakeLock;
+ private static final String WAKELOCK_TAG = "ServiceStateTracker";
// Keep track of SPN display rules, so we only broadcast intent if something changes.
private String curSpn = null;
- private String curPlmn = null;
+ private String curPlmn = null; // it contains the name of the registered network in CDMA can
+ // be the ONS or ERI text
private int curSpnRule = 0;
+ private String mMdn;
+ private int mHomeSystemId;
+ private int mHomeNetworkId;
+ private String mMin;
+
+ private boolean isEriTextLoaded = false;
+ private boolean isSubscriptionFromRuim = false;
+
+ // Registration Denied Reason, General/Authentication Failure, used only for debugging purposes
+ private String mRegistrationDeniedReason;
+
//***** Constants
static final String LOG_TAG = "CDMA";
- static final String TMUK = "23430";
private ContentResolver cr;
+ private String currentCarrier = null;
private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
Log.i("CdmaServiceStateTracker", "Auto time state called ...");
- //NOTE in CDMA NITZ is not used
+ revertToNitz();
+
}
};
@@ -124,16 +161,23 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
newSS = new ServiceState();
cellLoc = new CdmaCellLocation();
newCellLoc = new CdmaCellLocation();
+ mSignalStrength = new SignalStrength();
+
+ PowerManager powerManager =
+ (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null);
+ cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
cm.registerForRUIMReady(this, EVENT_RUIM_READY, null);
- phone.registerForNvLoaded(this, EVENT_NV_LOADED,null);
+ cm.registerForNVReady(this, EVENT_NV_READY, null);
+ phone.registerForEriFileLoaded(this, EVENT_ERI_FILE_LOADED, null);
// system setting property AIRPLANE_MODE_ON is set in Settings.
int airplaneMode = Settings.System.getInt(
@@ -145,7 +189,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
cr.registerContentObserver(
Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
mAutoTimeObserver);
- setRssiDefaultValues();
+ setSignalStrengthDefaultValues();
mNeedToRegForRuimLoaded = true;
}
@@ -156,14 +200,17 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
cm.unregisterForRadioStateChanged(this);
cm.unregisterForNetworkStateChanged(this);
cm.unregisterForRUIMReady(this);
- phone.unregisterForNvLoaded(this);
+ cm.unregisterForNVReady(this);
+ phone.unregisterForEriFileLoaded(this);
phone.mRuimRecords.unregisterForRecordsLoaded(this);
cm.unSetOnSignalStrengthUpdate(this);
+ cm.unSetOnNITZTime(this);
cr.unregisterContentObserver(this.mAutoTimeObserver);
}
+ @Override
protected void finalize() {
- if(DBG) Log.d(LOG_TAG, "CdmaServiceStateTracker finalized");
+ if (DBG) log("CdmaServiceStateTracker finalized");
}
void registerForNetworkAttach(Handler h, int what, Object obj) {
@@ -190,9 +237,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
Registrant r = new Registrant(h, what, obj);
cdmaDataConnectionAttachedRegistrants.add(r);
- if (cdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_1xRTT
- || cdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_EVDO_0
- || cdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_EVDO_A) {
+ if (cdmaDataConnectionState == ServiceState.STATE_IN_SERVICE) {
r.notifyRegistrant();
}
}
@@ -211,9 +256,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
Registrant r = new Registrant(h, what, obj);
cdmaDataConnectionDetachedRegistrants.add(r);
- if (cdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_1xRTT
- && cdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_EVDO_0
- && cdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_EVDO_A) {
+ if (cdmaDataConnectionState != ServiceState.STATE_IN_SERVICE) {
r.notifyRegistrant();
}
}
@@ -228,10 +271,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
EVENT_GET_LOC_DONE_CDMA, onComplete));
}
-
- //***** Overridden from ServiceStateTracker
- public void
- handleMessage (Message msg) {
+ @Override
+ public void handleMessage (Message msg) {
AsyncResult ar;
int[] ints;
String[] strings;
@@ -246,13 +287,21 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
// The RUIM is now ready i.e if it was locked
// it has been unlocked. At this stage, the radio is already
// powered on.
+ isSubscriptionFromRuim = true;
if (mNeedToRegForRuimLoaded) {
phone.mRuimRecords.registerForRecordsLoaded(this,
EVENT_RUIM_RECORDS_LOADED, null);
mNeedToRegForRuimLoaded = false;
}
// restore the previous network selection.
- phone.restoreSavedNetworkSelection(null);
+ pollState();
+
+ // Signal strength polling stops when radio is off
+ queueNextSignalStrengthPoll();
+ break;
+
+ case EVENT_NV_READY:
+ isSubscriptionFromRuim = false;
pollState();
// Signal strength polling stops when radio is off
queueNextSignalStrengthPoll();
@@ -328,9 +377,9 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
break;
- case EVENT_POLL_STATE_NETWORK_SELECTION_MODE_CDMA: //Fall through
- case EVENT_POLL_STATE_REGISTRATION_CDMA: //Fall through
+ case EVENT_POLL_STATE_REGISTRATION_CDMA:
case EVENT_POLL_STATE_OPERATOR_CDMA:
+ case EVENT_POLL_STATE_CDMA_SUBSCRIPTION:
ar = (AsyncResult) msg.obj;
handlePollStateResult(msg.what, ar);
break;
@@ -341,6 +390,15 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
break;
+ case EVENT_NITZ_TIME:
+ ar = (AsyncResult) msg.obj;
+
+ String nitzString = (String)((Object[])ar.result)[0];
+ long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
+
+ setTimeFromNITZString(nitzString, nitzReceiveTime);
+ break;
+
case EVENT_SIGNAL_STRENGTH_UPDATE:
// This is a notification from
// CommandsInterface.setOnSignalStrengthUpdate
@@ -355,7 +413,6 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
break;
case EVENT_RUIM_RECORDS_LOADED:
- case EVENT_NV_LOADED:
updateSpnDisplay();
break;
@@ -367,6 +424,12 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
break;
+ case EVENT_ERI_FILE_LOADED:
+ // Repoll the state once the ERI file has been loaded
+ if (DBG) log("[CdmaServiceStateTracker] ERI file has been loaded, repolling.");
+ pollState();
+ break;
+
default:
Log.e(LOG_TAG, "Unhandled message with number: " + msg.what);
break;
@@ -375,8 +438,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
//***** Private Instance Methods
- protected void setPowerStateToDesired()
- {
+ @Override
+ protected void setPowerStateToDesired() {
// If we want it on and it's off, turn it on
if (mDesiredPowerState
&& cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
@@ -390,14 +453,18 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
(dcTracker.getAnyDataEnabled() ? 1 : 0) );
EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_DATA_STATE_RADIO_OFF, val);
}
- dcTracker.cleanConnectionBeforeRadioOff();
-
- // poll data state up to 15 times, with a 100ms delay
+ Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 1; // tearDown is true
+ msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
+ dcTracker.sendMessage(msg);
+
+ // Poll data state up to 15 times, with a 100ms delay
// totaling 1.5 sec. Normal data disable action will finish in 100ms.
for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) {
- if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED
- && dcTracker.getState() != DataConnectionTracker.State.DISCONNECTING) {
- Log.d(LOG_TAG, "Data shutdown complete.");
+ DataConnectionTracker.State currentState = dcTracker.getState();
+ if (currentState != DataConnectionTracker.State.CONNECTED
+ && currentState != DataConnectionTracker.State.DISCONNECTING) {
+ if (DBG) log("Data shutdown complete.");
break;
}
SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
@@ -407,20 +474,31 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
} // Otherwise, we're in the desired state
}
+ @Override
protected void updateSpnDisplay() {
+ String spn = "";
+ boolean showSpn = false;
+ String plmn = "";
+ boolean showPlmn = false;
+ int rule = 0;
+ if (cm.getRadioState().isRUIMReady()) {
+ // TODO RUIM SPN is not implemnted, EF_SPN has to be read and Display Condition
+ // Character Encoding, Language Indicator and SPN has to be set
+ // rule = phone.mRuimRecords.getDisplayRule(ss.getOperatorNumeric());
+ // spn = phone.mSIMRecords.getServiceProvideName();
+ plmn = ss.getOperatorAlphaLong(); // mOperatorAlphaLong contains the ONS
+ // showSpn = (rule & ...
+ showPlmn = true; // showPlmn = (rule & ...
- // TODO Check this method again, because it is not sure at the moment how
- // the RUIM handles the SIM stuff
-
- //int rule = phone.mRuimRecords.getDisplayRule(ss.getOperatorNumeric());
- String spn = null; //phone.mRuimRecords.getServiceProviderName();
- String plmn = ss.getOperatorAlphaLong();
+ } else {
+ // In this case there is no SPN available from RUIM, we show the ERI text
+ plmn = ss.getOperatorAlphaLong(); // mOperatorAlphaLong contains the ERI text
+ showPlmn = true;
+ }
- if (!TextUtils.equals(this.curPlmn, plmn)) {
- //TODO (rule & SIMRecords.SPN_RULE_SHOW_SPN) == SIMRecords.SPN_RULE_SHOW_SPN;
- boolean showSpn = false;
- //TODO (rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_PLMN;
- boolean showPlmn = true;
+ if (rule != curSpnRule
+ || !TextUtils.equals(spn, curSpn)
+ || !TextUtils.equals(plmn, curPlmn)) {
Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION);
intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn);
intent.putExtra(Intents.EXTRA_SPN, spn);
@@ -429,17 +507,17 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
phone.getContext().sendStickyBroadcast(intent);
}
- //curSpnRule = rule;
- //curSpn = spn;
- this.curPlmn = plmn;
+ curSpnRule = rule;
+ curSpn = spn;
+ curPlmn = plmn;
}
/**
* Handle the result of one of the pollState()-related requests
*/
- protected void
- handlePollStateResult (int what, AsyncResult ar) {
+ @Override
+ protected void handlePollStateResult (int what, AsyncResult ar) {
int ints[];
String states[];
@@ -473,82 +551,129 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
} else try {
switch (what) {
- case EVENT_POLL_STATE_REGISTRATION_CDMA:
- //offset, because we don't want the first 3 values in the int-array
- final int offset = 3;
+ case EVENT_POLL_STATE_REGISTRATION_CDMA: // Handle RIL_REQUEST_REGISTRATION_STATE.
states = (String[])ar.result;
- int responseValuesRegistrationState[] = {
- -1, //[0] radioTechnology
- -1, //[1] baseStationId
- -1, //[2] baseStationLatitude
- -1, //[3] baseStationLongitude
- 0, //[4] cssIndicator; init with 0, because it is treated as a boolean
- -1, //[5] systemId
- -1, //[6] networkId
- -1, //[7] TSB-58 Roaming indicator // NEWRIL:TODO UNUSED
- -1, //[8] Indicates if current system is in PRL // NEWRIL:TODO UNUSED
- -1, //[9] Is default roaming indicator from PRL // NEWRIL:TODO UNUSED
- -1, //[10] If registration state is 3 this is reason for denial // NEWRIL:TODO UNUSED
- };
-
- if (states.length > 0) {
+ int registrationState = 4; //[0] registrationState
+ int radioTechnology = -1; //[3] radioTechnology
+ int baseStationId = -1; //[4] baseStationId
+ int baseStationLatitude = -1; //[5] baseStationLatitude
+ int baseStationLongitude = -1; //[6] baseStationLongitude
+ int cssIndicator = 0; //[7] init with 0, because it is treated as a boolean
+ int systemId = 0; //[8] systemId
+ int networkId = 0; //[9] networkId
+ int roamingIndicator = -1; //[10] Roaming indicator
+ int systemIsInPrl = 0; //[11] Indicates if current system is in PRL
+ int defaultRoamingIndicator = 0; //[12] Is default roaming indicator from PRL
+ int reasonForDenial = 0; //[13] Denial reason if registrationState = 3
+
+ if (states.length == 14) {
try {
- this.mRegistrationState = Integer.parseInt(states[0]);
- if (states.length >= 10) {
- for(int i = 0; i < states.length - offset; i++) {
- if (states[i + offset] != null
- && states[i + offset].length() > 0) {
- try {
- responseValuesRegistrationState[i] =
- Integer.parseInt(states[i + offset], 16);
- }
- catch(NumberFormatException ex) {
- Log.w(LOG_TAG, "Warning! There is an unexpected value"
- + "returned as response from "
- + "RIL_REQUEST_REGISTRATION_STATE.");
- }
- }
- }
- }
- else {
- Log.e(LOG_TAG, "Too less parameters returned from"
- + " RIL_REQUEST_REGISTRATION_STATE");
- }
- } catch (NumberFormatException ex) {
+ registrationState = Integer.parseInt(states[0]);
+ radioTechnology = Integer.parseInt(states[3]);
+ baseStationId = Integer.parseInt(states[4], 16);
+ baseStationLatitude = Integer.parseInt(states[5], 16);
+ baseStationLongitude = Integer.parseInt(states[6], 16);
+ cssIndicator = Integer.parseInt(states[7]);
+ systemId = Integer.parseInt(states[8]);
+ networkId = Integer.parseInt(states[9]);
+ roamingIndicator = Integer.parseInt(states[10]);
+ systemIsInPrl = Integer.parseInt(states[11]);
+ defaultRoamingIndicator = Integer.parseInt(states[12]);
+ reasonForDenial = Integer.parseInt(states[13]);
+ }
+ catch(NumberFormatException ex) {
Log.w(LOG_TAG, "error parsing RegistrationState: " + ex);
}
+ } else {
+ throw new RuntimeException("Warning! Wrong number of parameters returned from "
+ + "RIL_REQUEST_REGISTRATION_STATE: expected 14 got "
+ + states.length);
}
- mCdmaRoaming = regCodeIsRoaming(this.mRegistrationState);
- this.newCdmaDataConnectionState =
- radioTechnologyToServiceState(responseValuesRegistrationState[0]);
- newSS.setState (regCodeToServiceState(this.mRegistrationState));
- newSS.setRadioTechnology(responseValuesRegistrationState[0]);
- newSS.setCssIndicator(responseValuesRegistrationState[4]);
- newSS.setSystemAndNetworkId(responseValuesRegistrationState[5],
- responseValuesRegistrationState[6]);
+ mRegistrationState = registrationState;
+ mCdmaRoaming = regCodeIsRoaming(registrationState);
+ newSS.setState (regCodeToServiceState(registrationState));
+
+ this.newCdmaDataConnectionState = radioTechnologyToDataServiceState(radioTechnology);
+ newSS.setRadioTechnology(radioTechnology);
+ newNetworkType = radioTechnology;
+
+ newSS.setCssIndicator(cssIndicator);
+ newSS.setSystemAndNetworkId(systemId, networkId);
+ mRoamingIndicator = roamingIndicator;
+ mIsInPrl = (systemIsInPrl == 0) ? false : true;
+ mDefaultRoamingIndicator = defaultRoamingIndicator;
- newNetworkType = responseValuesRegistrationState[0];
// values are -1 if not available
- newCellLoc.setCellLocationData(responseValuesRegistrationState[1],
- responseValuesRegistrationState[2],
- responseValuesRegistrationState[3]);
+ newCellLoc.setCellLocationData(baseStationId, baseStationLatitude,
+ baseStationLongitude);
+
+ if (reasonForDenial == 0) {
+ mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_GEN;
+ } else if (reasonForDenial == 1) {
+ mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_AUTH;
+ } else {
+ mRegistrationDeniedReason = "";
+ }
+
+ if (mRegistrationState == 3) {
+ if (DBG) log("Registration denied, " + mRegistrationDeniedReason);
+ }
break;
- case EVENT_POLL_STATE_OPERATOR_CDMA:
+ case EVENT_POLL_STATE_OPERATOR_CDMA: // Handle RIL_REQUEST_OPERATOR
String opNames[] = (String[])ar.result;
if (opNames != null && opNames.length >= 3) {
- newSS.setOperatorName (opNames[0], opNames[1], opNames[2]);
+ if (cm.getRadioState().isNVReady()) {
+ // In CDMA in case on NV the ss.mOperatorAlphaLong is set later with the
+ // ERI text, so here it is ignored what is coming from the modem
+ newSS.setOperatorName(null, opNames[1], opNames[2]);
+ } else {
+ newSS.setOperatorName(opNames[0], opNames[1], opNames[2]);
+ }
+
+ if (!(opNames[2].equals(currentCarrier))) {
+ // TODO(Moto): jsh asks, "This uses the MCC+MNC of the current registered
+ // network to set the "current" entry in the APN table. But the correct
+ // entry should be the MCC+MNC that matches the subscribed operator
+ // (eg, phone issuer). These can be different when roaming."
+ try {
+ // Set the current field of the telephony provider according to
+ // the CDMA's operator
+ Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
+ ContentValues map = new ContentValues();
+ map.put(Telephony.Carriers.NUMERIC, opNames[2]);
+ cr.insert(uri, map);
+ // save current carrier for the next time check
+ currentCarrier = opNames[2];
+ } catch (SQLException e) {
+ Log.e(LOG_TAG, "Can't store current operator", e);
+ }
+ } else {
+ Log.i(LOG_TAG, "current carrier is not changed");
+ }
+ } else {
+ Log.w(LOG_TAG, "error parsing opNames");
}
break;
- case EVENT_POLL_STATE_NETWORK_SELECTION_MODE_CDMA:
- ints = (int[])ar.result;
- newSS.setIsManualSelection(ints[0] == 1);
+ case EVENT_POLL_STATE_CDMA_SUBSCRIPTION: // Handle RIL_CDMA_SUBSCRIPTION
+ String cdmaSubscription[] = (String[])ar.result;
+
+ if (cdmaSubscription != null && cdmaSubscription.length >= 4) {
+ mMdn = cdmaSubscription[0];
+ mHomeSystemId = Integer.parseInt(cdmaSubscription[1], 16);
+ mHomeNetworkId = Integer.parseInt(cdmaSubscription[2], 16);
+ mMin = cdmaSubscription[3];
+
+ } else {
+ Log.w(LOG_TAG, "error parsing cdmaSubscription");
+ }
break;
+
default:
Log.e(LOG_TAG, "RIL response handle in wrong phone!"
+ " Expected CDMA RIL request and get GSM RIL request.");
@@ -563,29 +688,55 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
pollingContext[0]--;
if (pollingContext[0] == 0) {
- newSS.setRoaming(isRoamingBetweenOperators(mCdmaRoaming, newSS));
+ boolean namMatch = false;
+ if ((mHomeSystemId != 0) && (mHomeSystemId == newSS.getSystemId()) ) {
+ namMatch = true;
+ }
- switch(this.mRegistrationState) {
- case ServiceState.REGISTRATION_STATE_HOME_NETWORK:
- newSS.setExtendedCdmaRoaming(ServiceState.REGISTRATION_STATE_HOME_NETWORK);
- break;
- case ServiceState.REGISTRATION_STATE_ROAMING:
- newSS.setExtendedCdmaRoaming(ServiceState.REGISTRATION_STATE_ROAMING);
- break;
- case ServiceState.REGISTRATION_STATE_ROAMING_AFFILIATE:
- newSS.setExtendedCdmaRoaming(ServiceState.REGISTRATION_STATE_ROAMING_AFFILIATE);
- break;
- default:
- Log.w(LOG_TAG, "Received a different registration state, "
- + "but don't changed the extended cdma roaming mode.");
+ // Setting SS Roaming (general)
+ if (isSubscriptionFromRuim) {
+ newSS.setRoaming(isRoamingBetweenOperators(mCdmaRoaming, newSS));
+ } else {
+ newSS.setRoaming(mCdmaRoaming);
+ }
+
+ // Setting SS CdmaRoamingIndicator and CdmaDefaultRoamingIndicator
+ // TODO(Teleca): Validate this is correct.
+ if (mIsInPrl) {
+ if (namMatch && (mRoamingIndicator <= 2)) {
+ // System is acquired, prl match, nam match and mRoamingIndicator <= 2
+ newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF);
+ } else {
+ // System is acquired, prl match, no nam match or mRoamingIndicator > 2
+ newSS.setCdmaRoamingIndicator(mRoamingIndicator);
+ }
+ } else {
+ if (mRegistrationState == 5) {
+ // System is acquired but prl not loaded or no prl match
+ newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH);
+ } else {
+ // Use the default indicator
+ }
+ }
+
+ newSS.setCdmaDefaultRoamingIndicator(mDefaultRoamingIndicator);
+
+ // NOTE: Some operator may require to override the mCdmaRoaming (set by the modem)
+ // depending on the mRoamingIndicator.
+
+ if (DBG) {
+ log("Set CDMA Roaming Indicator to: " + newSS.getCdmaRoamingIndicator()
+ + ". mCdmaRoaming = " + mCdmaRoaming + ", namMatch = " + namMatch
+ + ", mIsInPrl = " + mIsInPrl + ", mRoamingIndicator = " + mRoamingIndicator
+ + ", mDefaultRoamingIndicator= " + mDefaultRoamingIndicator);
}
pollStateDone();
}
}
- private void setRssiDefaultValues() {
- rssi = 99;
+ private void setSignalStrengthDefaultValues() {
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, false);
}
/**
@@ -606,7 +757,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
case RADIO_UNAVAILABLE:
newSS.setStateOutOfService();
newCellLoc.setStateInvalid();
- setRssiDefaultValues();
+ setSignalStrengthDefaultValues();
mGotCountryCode = false;
pollStateDone();
@@ -615,7 +766,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
case RADIO_OFF:
newSS.setStateOff();
newCellLoc.setStateInvalid();
- setRssiDefaultValues();
+ setSignalStrengthDefaultValues();
mGotCountryCode = false;
pollStateDone();
@@ -627,10 +778,10 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
log("Radio Technology Change ongoing, setting SS to off");
newSS.setStateOff();
newCellLoc.setStateInvalid();
- setRssiDefaultValues();
+ setSignalStrengthDefaultValues();
mGotCountryCode = false;
- pollStateDone();
+ //NOTE: pollStateDone() is not needed in this case
break;
default:
@@ -639,20 +790,21 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
// are allowed to arrive out-of-order
pollingContext[0]++;
- //RIL_REQUEST_OPERATOR is necessary for CDMA
- cm.getOperator(
- obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
-
- pollingContext[0]++;
- //RIL_REQUEST_REGISTRATION_STATE is necessary for CDMA
- cm.getRegistrationState(
- obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, pollingContext));
-
- pollingContext[0]++;
- //RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE necessary for CDMA
- cm.getNetworkSelectionMode(
- obtainMessage(EVENT_POLL_STATE_NETWORK_SELECTION_MODE_CDMA, pollingContext));
- break;
+ // RIL_REQUEST_CDMA_SUBSCRIPTION is necessary for CDMA
+ cm.getCDMASubscription(
+ obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION, pollingContext));
+
+ pollingContext[0]++;
+ // RIL_REQUEST_OPERATOR is necessary for CDMA
+ cm.getOperator(
+ obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
+
+ pollingContext[0]++;
+ // RIL_REQUEST_REGISTRATION_STATE is necessary for CDMA
+ cm.getRegistrationState(
+ obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, pollingContext));
+
+ break;
}
}
@@ -683,14 +835,45 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
return ret;
}
- private void
- pollStateDone() {
- if (DBG) {
- Log.d(LOG_TAG, "Poll ServiceState done: " +
- " oldSS=[" + ss );
- Log.d(LOG_TAG, "Poll ServiceState done: " +
- " newSS=[" + newSS);
+ private void fixTimeZone(String isoCountryCode) {
+ TimeZone zone = null;
+ // If the offset is (0, false) and the time zone property
+ // is set, use the time zone property rather than GMT.
+ String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
+ if ((mZoneOffset == 0) && (mZoneDst == false) && (zoneName != null)
+ && (zoneName.length() > 0)
+ && (Arrays.binarySearch(GMT_COUNTRY_CODES, isoCountryCode) < 0)) {
+ // For NITZ string without time zone,
+ // need adjust time to reflect default time zone setting
+ zone = TimeZone.getDefault();
+ long tzOffset;
+ tzOffset = zone.getOffset(System.currentTimeMillis());
+ if (getAutoTime()) {
+ setAndBroadcastNetworkSetTime(System.currentTimeMillis() - tzOffset);
+ } else {
+ // Adjust the saved NITZ time to account for tzOffset.
+ mSavedTime = mSavedTime - tzOffset;
+ }
+ } else if (isoCountryCode.equals("")) {
+ // Country code not found. This is likely a test network.
+ // Get a TimeZone based only on the NITZ parameters (best guess).
+ zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
+ } else {
+ zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, isoCountryCode);
+ }
+
+ mNeedFixZone = false;
+
+ if (zone != null) {
+ if (getAutoTime()) {
+ setAndBroadcastNetworkSetTimeZone(zone.getID());
+ }
+ saveNitzTimeZone(zone.getID());
}
+ }
+
+ private void pollStateDone() {
+ if (DBG) log("Poll ServiceState done: oldSS=[" + ss + "] newSS=[" + newSS + "]");
boolean hasRegistered =
ss.getState() != ServiceState.STATE_IN_SERVICE
@@ -701,20 +884,12 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
&& newSS.getState() != ServiceState.STATE_IN_SERVICE;
boolean hasCdmaDataConnectionAttached =
- (this.cdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_1xRTT
- && this.cdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_EVDO_0
- && this.cdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_EVDO_A)
- && (this.newCdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_1xRTT
- || this.newCdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_EVDO_0
- || this.newCdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_EVDO_A);
+ this.cdmaDataConnectionState != ServiceState.STATE_IN_SERVICE
+ && this.newCdmaDataConnectionState == ServiceState.STATE_IN_SERVICE;
boolean hasCdmaDataConnectionDetached =
- (this.cdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_1xRTT
- || this.cdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_EVDO_0
- || this.cdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
- && (this.newCdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_1xRTT
- && this.newCdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_EVDO_0
- && this.newCdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_EVDO_A);
+ this.cdmaDataConnectionState == ServiceState.STATE_IN_SERVICE
+ && this.newCdmaDataConnectionState != ServiceState.STATE_IN_SERVICE;
boolean hasCdmaDataConnectionChanged =
cdmaDataConnectionState != newCdmaDataConnectionState;
@@ -757,6 +932,20 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
if (hasChanged) {
+ if (cm.getRadioState().isNVReady()) {
+ String eriText;
+ // Now the CDMAPhone sees the new ServiceState so it can get the new ERI text
+ if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
+ eriText = phone.getCdmaEriText();
+ } else {
+ // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used for
+ // mRegistrationState 0,2,3 and 4
+ eriText = phone.getContext().getText(
+ com.android.internal.R.string.roamingTextSearching).toString();
+ }
+ ss.setCdmaEriText(eriText);
+ }
+
String operatorNumeric;
phone.setSystemProperty(PROPERTY_OPERATOR_ALPHA,
@@ -768,9 +957,9 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
if (operatorNumeric == null) {
phone.setSystemProperty(PROPERTY_OPERATOR_ISO_COUNTRY, "");
} else {
- String iso = "";
+ String isoCountryCode = "";
try{
- iso = MccTable.countryCodeForMcc(Integer.parseInt(
+ isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(
operatorNumeric.substring(0,3)));
} catch ( NumberFormatException ex){
Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
@@ -778,14 +967,15 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
}
- phone.setSystemProperty(PROPERTY_OPERATOR_ISO_COUNTRY, iso);
+ phone.setSystemProperty(PROPERTY_OPERATOR_ISO_COUNTRY, isoCountryCode);
mGotCountryCode = true;
+ if (mNeedFixZone) {
+ fixTimeZone(isoCountryCode);
+ }
}
phone.setSystemProperty(PROPERTY_OPERATOR_ISROAMING,
ss.getRoaming() ? "true" : "false");
- phone.setSystemProperty(PROPERTY_OPERATOR_ISMANUAL,
- ss.getIsManualSelection() ? "true" : "false");
updateSpnDisplay();
phone.notifyServiceStateChanged(ss);
@@ -825,10 +1015,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
// Couldn't find a proper timezone. Perhaps the DST data is wrong.
guess = findTimeZone(offset, !dst, when);
}
- if (DBG) {
- Log.d(LOG_TAG, "getNitzTimeZone returning "
- + (guess == null ? guess : guess.getID()));
- }
+ if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
return guess;
}
@@ -852,6 +1039,12 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
return guess;
}
+ /**
+ * TODO: This code is exactly the same as in GsmServiceStateTracker
+ * and has a TODO to not poll signal strength if screen is off.
+ * This code should probably be hoisted to the base class so
+ * the fix, when added, works for both.
+ */
private void
queueNextSignalStrengthPoll() {
if (dontPollSignalStrength || (cm.getRadioState().isGsm())) {
@@ -865,48 +1058,56 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
msg = obtainMessage();
msg.what = EVENT_POLL_SIGNAL_STRENGTH;
- // TODO Done't poll signal strength if screen is off
+ // TODO Don't poll signal strength if screen is off
sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
}
/**
- * send signal-strength-changed notification if rssi changed
+ * send signal-strength-changed notification if changed
* Called both for solicited and unsolicited signal stength updates
*/
private void
onSignalStrengthResult(AsyncResult ar) {
- int oldRSSI = rssi;
+ SignalStrength oldSignalStrength = mSignalStrength;
if (ar.exception != null) {
- // 99 = unknown
- // most likely radio is resetting/disconnected
- rssi = 99;
+ // Most likely radio is resetting/disconnected change to default values.
+ setSignalStrengthDefaultValues();
} else {
int[] ints = (int[])ar.result;
-
- // bug 658816 seems to be a case where the result is 0-length
- if (ints.length != 0) {
- rssi = ints[0];
- } else {
- Log.e(LOG_TAG, "Bogus signal strength response");
- rssi = 99;
+ int offset = 2;
+
+ int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -1;
+ int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -1;
+
+ int evdoRssi = -1;
+ int evdoEcio = -1;
+ int evdoSnr = -1;
+ if ((networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
+ || (networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_A)) {
+ evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -1;
+ evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1;
+ evdoSnr = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1;
}
+
+ mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio,
+ evdoRssi, evdoEcio, evdoSnr, false);
}
- if (rssi != oldRSSI) {
+ if (!mSignalStrength.equals(oldSignalStrength)) {
try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after
// POLL_PERIOD_MILLIS) during Radio Technology Change)
phone.notifySignalStrength();
} catch (NullPointerException ex) {
- log("onSignalStrengthResult() Phone already destroyed: " + ex
- + "Signal Stranth not notified");
+ log("onSignalStrengthResult() Phone already destroyed: " + ex
+ + "SignalStrength not notified");
}
}
}
- private int radioTechnologyToServiceState(int code) {
- int retVal = ServiceState.RADIO_TECHNOLOGY_UNKNOWN;
+ private int radioTechnologyToDataServiceState(int code) {
+ int retVal = ServiceState.STATE_OUT_OF_SERVICE;
switch(code) {
case 0:
case 1:
@@ -915,14 +1116,10 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
case 4:
case 5:
break;
- case 6:
- retVal = ServiceState.RADIO_TECHNOLOGY_1xRTT;
- break;
- case 7:
- retVal = ServiceState.RADIO_TECHNOLOGY_EVDO_0;
- break;
- case 8:
- retVal = ServiceState.RADIO_TECHNOLOGY_EVDO_A;
+ case 6: // RADIO_TECHNOLOGY_1xRTT
+ case 7: // RADIO_TECHNOLOGY_EVDO_0
+ case 8: // RADIO_TECHNOLOGY_EVDO_A
+ retVal = ServiceState.STATE_IN_SERVICE;
break;
default:
Log.e(LOG_TAG, "Wrong radioTechnology code.");
@@ -943,9 +1140,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
case 3: // 3 is "registration denied", fall through
case 4: // 4 is "unknown" no vaild in current baseband
return ServiceState.STATE_OUT_OF_SERVICE;
- case 5:// fall through
- case 6:
- // Registered and: roaming (5) or roaming affiliates (6)
+ case 5:// 5 is "Registered, roaming"
return ServiceState.STATE_IN_SERVICE;
default:
@@ -983,6 +1178,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
boolean isRoamingBetweenOperators(boolean cdmaRoaming, ServiceState s) {
String spn = SystemProperties.get(PROPERTY_ICC_OPERATOR_ALPHA, "empty");
+ // NOTE: in case of RUIM we should completely ignore the ERI data file and
+ // mOperatorAlphaLong is set from RIL_REQUEST_OPERATOR response 0 (alpha ONS)
String onsl = s.getOperatorAlphaLong();
String onss = s.getOperatorAlphaShort();
@@ -992,6 +1189,169 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
return cdmaRoaming && !(equalsOnsl || equalsOnss);
}
+
+ /**
+ * nitzReceiveTime is time_t that the NITZ time was posted
+ */
+
+ private
+ void setTimeFromNITZString (String nitz, long nitzReceiveTime)
+ {
+ // "yy/mm/dd,hh:mm:ss(+/-)tz"
+ // tz is in number of quarter-hours
+
+ long start = SystemClock.elapsedRealtime();
+ Log.i(LOG_TAG, "NITZ: " + nitz + "," + nitzReceiveTime +
+ " start=" + start + " delay=" + (start - nitzReceiveTime));
+
+ try {
+ /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
+ * offset as well (which we won't worry about until later) */
+ Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+
+ c.clear();
+ c.set(Calendar.DST_OFFSET, 0);
+
+ String[] nitzSubs = nitz.split("[/:,+-]");
+
+ int year = 2000 + Integer.parseInt(nitzSubs[0]);
+ c.set(Calendar.YEAR, year);
+
+ // month is 0 based!
+ int month = Integer.parseInt(nitzSubs[1]) - 1;
+ c.set(Calendar.MONTH, month);
+
+ int date = Integer.parseInt(nitzSubs[2]);
+ c.set(Calendar.DATE, date);
+
+ int hour = Integer.parseInt(nitzSubs[3]);
+ c.set(Calendar.HOUR, hour);
+
+ int minute = Integer.parseInt(nitzSubs[4]);
+ c.set(Calendar.MINUTE, minute);
+
+ int second = Integer.parseInt(nitzSubs[5]);
+ c.set(Calendar.SECOND, second);
+
+ boolean sign = (nitz.indexOf('-') == -1);
+
+ int tzOffset = Integer.parseInt(nitzSubs[6]);
+
+ int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
+ : 0;
+
+ // The zone offset received from NITZ is for current local time,
+ // so DST correction is already applied. Don't add it again.
+ //
+ // tzOffset += dst * 4;
+ //
+ // We could unapply it if we wanted the raw offset.
+
+ tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
+
+ TimeZone zone = null;
+
+ // As a special extension, the Android emulator appends the name of
+ // the host computer's timezone to the nitz string. this is zoneinfo
+ // timezone name of the form Area!Location or Area!Location!SubLocation
+ // so we need to convert the ! into /
+ if (nitzSubs.length >= 9) {
+ String tzname = nitzSubs[8].replace('!','/');
+ zone = TimeZone.getTimeZone( tzname );
+ }
+
+ String iso = SystemProperties.get(PROPERTY_OPERATOR_ISO_COUNTRY);
+
+ if (zone == null) {
+
+ if (mGotCountryCode) {
+ if (iso != null && iso.length() > 0) {
+ zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
+ c.getTimeInMillis(),
+ iso);
+ } else {
+ // We don't have a valid iso country code. This is
+ // most likely because we're on a test network that's
+ // using a bogus MCC (eg, "001"), so get a TimeZone
+ // based only on the NITZ parameters.
+ zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
+ }
+ }
+ }
+
+ if (zone == null) {
+ // We got the time before the country, so we don't know
+ // how to identify the DST rules yet. Save the information
+ // and hope to fix it up later.
+
+ mNeedFixZone = true;
+ mZoneOffset = tzOffset;
+ mZoneDst = dst != 0;
+ mZoneTime = c.getTimeInMillis();
+ }
+
+ if (zone != null) {
+ if (getAutoTime()) {
+ setAndBroadcastNetworkSetTimeZone(zone.getID());
+ }
+ saveNitzTimeZone(zone.getID());
+ }
+
+ String ignore = SystemProperties.get("gsm.ignore-nitz");
+ if (ignore != null && ignore.equals("yes")) {
+ Log.i(LOG_TAG, "NITZ: Not setting clock because gsm.ignore-nitz is set");
+ return;
+ }
+
+ try {
+ mWakeLock.acquire();
+
+ if (getAutoTime()) {
+ long millisSinceNitzReceived
+ = SystemClock.elapsedRealtime() - nitzReceiveTime;
+
+ if (millisSinceNitzReceived < 0) {
+ // Sanity check: something is wrong
+ Log.i(LOG_TAG, "NITZ: not setting time, clock has rolled "
+ + "backwards since NITZ time was received, "
+ + nitz);
+ return;
+ }
+
+ if (millisSinceNitzReceived > Integer.MAX_VALUE) {
+ // If the time is this far off, something is wrong > 24 days!
+ Log.i(LOG_TAG, "NITZ: not setting time, processing has taken "
+ + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
+ + " days");
+ return;
+ }
+
+ // Note: with range checks above, cast to int is safe
+ c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
+
+ Log.i(LOG_TAG, "NITZ: Setting time of day to " + c.getTime()
+ + " NITZ receive delay(ms): " + millisSinceNitzReceived
+ + " gained(ms): "
+ + (c.getTimeInMillis() - System.currentTimeMillis())
+ + " from " + nitz);
+
+ setAndBroadcastNetworkSetTime(c.getTimeInMillis());
+ Log.i(LOG_TAG, "NITZ: after Setting time of day");
+ }
+ SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
+ saveNitzTime(c.getTimeInMillis());
+ if (Config.LOGV) {
+ long end = SystemClock.elapsedRealtime();
+ Log.v(LOG_TAG, "NITZ: end=" + end + " dur=" + (end - start));
+ }
+ } finally {
+ mWakeLock.release();
+ }
+ } catch (RuntimeException ex) {
+ Log.e(LOG_TAG, "NITZ: Parsing NITZ time " + nitz, ex);
+ }
+ }
+
private boolean getAutoTime() {
try {
return Settings.System.getInt(phone.getContext().getContentResolver(),
@@ -1001,6 +1361,58 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
}
+ private void saveNitzTimeZone(String zoneId) {
+ mSavedTimeZone = zoneId;
+ }
+
+ private void saveNitzTime(long time) {
+ mSavedTime = time;
+ mSavedAtTime = SystemClock.elapsedRealtime();
+ }
+
+ /**
+ * Set the timezone and send out a sticky broadcast so the system can
+ * determine if the timezone was set by the carrier.
+ *
+ * @param zoneId timezone set by carrier
+ */
+ private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
+ AlarmManager alarm =
+ (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
+ alarm.setTimeZone(zoneId);
+ Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
+ intent.putExtra("time-zone", zoneId);
+ phone.getContext().sendStickyBroadcast(intent);
+ }
+
+ /**
+ * Set the time and Send out a sticky broadcast so the system can determine
+ * if the time was set by the carrier.
+ *
+ * @param time time set by network
+ */
+ private void setAndBroadcastNetworkSetTime(long time) {
+ SystemClock.setCurrentTimeMillis(time);
+ Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
+ intent.putExtra("time", time);
+ phone.getContext().sendStickyBroadcast(intent);
+ }
+
+ private void revertToNitz() {
+ if (Settings.System.getInt(phone.getContext().getContentResolver(),
+ Settings.System.AUTO_TIME, 0) == 0) {
+ return;
+ }
+ Log.d(LOG_TAG, "Reverting to NITZ: tz='" + mSavedTimeZone
+ + "' mSavedTime=" + mSavedTime
+ + " mSavedAtTime=" + mSavedAtTime);
+ if (mSavedTimeZone != null && mSavedTime != 0 && mSavedAtTime != 0) {
+ setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
+ setAndBroadcastNetworkSetTime(mSavedTime
+ + (SystemClock.elapsedRealtime() - mSavedAtTime));
+ }
+ }
+
/**
* @return true if phone is camping on a technology
* that could support voice and data simultaneously.
@@ -1017,4 +1429,12 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
Log.d(LOG_TAG, "[CdmaServiceStateTracker] " + s);
}
+ public String getMdnNumber() {
+ return mMdn;
+ }
+
+ public String getCdmaMin() {
+ return mMin;
+ }
+
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/EriInfo.java b/telephony/java/com/android/internal/telephony/cdma/EriInfo.java
new file mode 100644
index 0000000..5c8e23e
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/EriInfo.java
@@ -0,0 +1,43 @@
+/*
+ * 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.cdma;
+
+public final class EriInfo {
+
+ public static final int ROAMING_INDICATOR_ON = 0;
+ public static final int ROAMING_INDICATOR_OFF = 1;
+ public static final int ROAMING_INDICATOR_FLASH = 2;
+
+ public static final int ROAMING_ICON_MODE_NORMAL = 0;
+ public static final int ROAMING_ICON_MODE_FLASH = 1;
+
+ public int mRoamingIndicator;
+ public int mIconIndex;
+ public int mIconMode;
+ public String mEriText;
+ public int mCallPromptId;
+ public int mAlertId;
+
+ public EriInfo (int roamingIndicator, int iconIndex, int iconMode, String eriText,
+ int callPromptId, int alertId) {
+
+ this.mRoamingIndicator = roamingIndicator;
+ this.mIconIndex = iconIndex;
+ this.mIconMode = iconMode;
+ this.mEriText = eriText;
+ this.mCallPromptId = callPromptId;
+ this.mAlertId = alertId;
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/EriManager.java b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
new file mode 100644
index 0000000..6c1384c
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
@@ -0,0 +1,436 @@
+/*
+ * 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.cdma;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.os.Message;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneBase;
+
+import com.android.internal.util.XmlUtils;
+
+import java.util.HashMap;
+
+/**
+ * EriManager loads the ERI file definitions and manages the CDMA roaming information.
+ *
+ */
+public final class EriManager {
+
+ class EriFile {
+
+ public int mVersionNumber; // File version number
+ public int mNumberOfEriEntries; // Number of entries
+ public int mEriFileType; // Eri Phase 0/1
+ //public int mNumberOfIconImages; // reserved for future use
+ //public int mIconImageType; // reserved for future use
+ public String[] mCallPromptId; // reserved for future use
+ public HashMap<Integer, EriInfo> mRoamIndTable; // Roaming Indicator Table
+
+ public EriFile() {
+ this.mVersionNumber = -1;
+ this.mNumberOfEriEntries = 0;
+ this.mEriFileType = -1;
+ this.mCallPromptId = new String[] { "", "", "" };
+ this.mRoamIndTable = new HashMap<Integer, EriInfo>();
+ }
+ }
+
+ class EriDisplayInformation {
+ public int mEriIconIndex;
+ public int mEriIconMode;
+ public String mEriIconText;
+
+ public EriDisplayInformation(int eriIconIndex, int eriIconMode, String eriIconText) {
+ mEriIconIndex = eriIconIndex;
+ mEriIconMode = eriIconMode;
+ mEriIconText = eriIconText;
+ }
+
+// public void setParameters(int eriIconIndex, int eriIconMode, String eriIconText){
+// this.mEriIconIndex = eriIconIndex;
+// this.mEriIconMode = eriIconMode;
+// this.mEriIconText = eriIconText;
+// }
+
+ @Override
+ public String toString() {
+ return "EriDisplayInformation: {" + " IconIndex: " + mEriIconIndex + " EriIconMode: "
+ + mEriIconMode + " EriIconText: " + mEriIconText + " }";
+ }
+ }
+
+ static final String LOG_TAG = "CDMA";
+
+ public static final int ERI_FROM_XML = 0;
+ public static final int ERI_FROM_FILE_SYSTEM = 1;
+ public static final int ERI_FROM_MODEM = 2;
+
+ private PhoneBase mPhone;
+ private Context mContext;
+ private int mEriFileSource = ERI_FROM_XML;
+ private boolean isEriFileLoaded;
+ private EriFile mEriFile;
+
+ public EriManager(PhoneBase phone, Context context, int eriFileSource) {
+ this.mPhone = phone;
+ this.mContext = context;
+ this.mEriFileSource = eriFileSource;
+ this.mEriFile = new EriFile();
+ }
+
+ public void dispose() {
+ mEriFile = new EriFile();
+ isEriFileLoaded = false;
+ }
+
+
+ public void loadEriFile() {
+ switch (mEriFileSource) {
+ case ERI_FROM_MODEM:
+ loadEriFileFromModem();
+ break;
+
+ case ERI_FROM_FILE_SYSTEM:
+ loadEriFileFromFileSystem();
+ break;
+
+ case ERI_FROM_XML:
+ default:
+ loadEriFileFromXml();
+ break;
+ }
+ }
+
+ /**
+ * Load the ERI file from the MODEM through chipset specific RIL_REQUEST_OEM_HOOK
+ *
+ * In this case the ERI file can be updated from the Phone Support Tool available
+ * from the Chipset vendor
+ */
+ private void loadEriFileFromModem() {
+ // NOT IMPLEMENTED, Chipset vendor/Operator specific
+ }
+
+ /**
+ * Load the ERI file from a File System file
+ *
+ * In this case the a Phone Support Tool to update the ERI file must be provided
+ * to the Operator
+ */
+ private void loadEriFileFromFileSystem() {
+ // NOT IMPLEMENTED, Chipset vendor/Operator specific
+ }
+
+ /**
+ * Load the ERI file from the application framework resources encoded in XML
+ *
+ */
+ private void loadEriFileFromXml() {
+ Resources r = mContext.getResources();
+ XmlResourceParser parser = r.getXml(com.android.internal.R.xml.eri);
+ try {
+ XmlUtils.beginDocument(parser, "EriFile");
+ mEriFile.mVersionNumber = Integer.parseInt(
+ parser.getAttributeValue(null, "VersionNumber"));
+ mEriFile.mNumberOfEriEntries = Integer.parseInt(
+ parser.getAttributeValue(null, "NumberOfEriEntries"));
+ mEriFile.mEriFileType = Integer.parseInt(
+ parser.getAttributeValue(null, "EriFileType"));
+
+ int parsedEriEntries = 0;
+ while(true) {
+ XmlUtils.nextElement(parser);
+ String name = parser.getName();
+ if (name == null) {
+ if (parsedEriEntries != mEriFile.mNumberOfEriEntries)
+ Log.e(LOG_TAG, "Error Parsing ERI file: " + mEriFile.mNumberOfEriEntries
+ + " defined, " + parsedEriEntries + " parsed!");
+ break;
+ } else if (name.equals("CallPromptId")) {
+ int id = Integer.parseInt(parser.getAttributeValue(null, "Id"));
+ String text = parser.getAttributeValue(null, "CallPromptText");
+ if (id >= 0 && id <= 2) {
+ mEriFile.mCallPromptId[id] = text;
+ } else {
+ Log.e(LOG_TAG, "Error Parsing ERI file: found" + id + " CallPromptId");
+ }
+
+ } else if (name.equals("EriInfo")) {
+ int roamingIndicator = Integer.parseInt(
+ parser.getAttributeValue(null, "RoamingIndicator"));
+ int iconIndex = Integer.parseInt(parser.getAttributeValue(null, "IconIndex"));
+ int iconMode = Integer.parseInt(parser.getAttributeValue(null, "IconMode"));
+ String eriText = parser.getAttributeValue(null, "EriText");
+ int callPromptId = Integer.parseInt(
+ parser.getAttributeValue(null, "CallPromptId"));
+ int alertId = Integer.parseInt(parser.getAttributeValue(null, "AlertId"));
+ parsedEriEntries++;
+ mEriFile.mRoamIndTable.put(roamingIndicator, new EriInfo (roamingIndicator,
+ iconIndex, iconMode, eriText, callPromptId, alertId));
+ }
+ }
+
+ isEriFileLoaded = true;
+
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Got exception while loading ERI file.", e);
+ } finally {
+ parser.close();
+ }
+ }
+
+ /**
+ * Returns the version of the ERI file
+ *
+ */
+ public int getEriFileVersion() {
+ return mEriFile.mVersionNumber;
+ }
+
+ /**
+ * Returns the number of ERI entries parsed
+ *
+ */
+ public int getEriNumberOfEntries() {
+ return mEriFile.mNumberOfEriEntries;
+ }
+
+ /**
+ * Returns the ERI file type value ( 0 for Phase 0, 1 for Phase 1)
+ *
+ */
+ public int getEriFileType() {
+ return mEriFile.mEriFileType;
+ }
+
+ /**
+ * Returns if the ERI file has been loaded
+ *
+ */
+ public boolean isEriFileLoaded() {
+ return isEriFileLoaded;
+ }
+
+ /**
+ * Returns the EriInfo record associated with roamingIndicator
+ * or null if the entry is not found
+ */
+ private EriInfo getEriInfo(int roamingIndicator) {
+ if (mEriFile.mRoamIndTable.containsKey(roamingIndicator)) {
+ return mEriFile.mRoamIndTable.get(roamingIndicator);
+ } else {
+ return null;
+ }
+ }
+
+ private EriDisplayInformation getEriDisplayInformation(int roamInd, int defRoamInd){
+ //int iconIndex = -1;
+ //int iconMode = -1;
+ //String iconText = "ERI text";
+ EriDisplayInformation ret;
+
+ switch (roamInd) {
+ // Handling the standard roaming indicator (non-ERI)
+ case EriInfo.ROAMING_INDICATOR_ON:
+ ret = new EriDisplayInformation(
+ EriInfo.ROAMING_INDICATOR_ON,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText0).toString());
+ break;
+
+ case EriInfo.ROAMING_INDICATOR_OFF:
+ ret = new EriDisplayInformation(
+ EriInfo.ROAMING_INDICATOR_OFF,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText1).toString());
+ break;
+
+ case EriInfo.ROAMING_INDICATOR_FLASH:
+ ret = new EriDisplayInformation(
+ EriInfo.ROAMING_INDICATOR_FLASH,
+ EriInfo.ROAMING_ICON_MODE_FLASH,
+ mContext.getText(com.android.internal.R.string.roamingText2).toString());
+ break;
+
+
+ // Handling the standard ERI
+ case 3:
+ ret = new EriDisplayInformation(
+ roamInd,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText3).toString());
+ break;
+
+ case 4:
+ ret = new EriDisplayInformation(
+ roamInd,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText4).toString());
+ break;
+
+ case 5:
+ ret = new EriDisplayInformation(
+ roamInd,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText5).toString());
+ break;
+
+ case 6:
+ ret = new EriDisplayInformation(
+ roamInd,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText6).toString());
+ break;
+
+ case 7:
+ ret = new EriDisplayInformation(
+ roamInd,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText7).toString());
+ break;
+
+ case 8:
+ ret = new EriDisplayInformation(
+ roamInd,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText8).toString());
+ break;
+
+ case 9:
+ ret = new EriDisplayInformation(
+ roamInd,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText9).toString());
+ break;
+
+ case 10:
+ ret = new EriDisplayInformation(
+ roamInd,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText10).toString());
+ break;
+
+ case 11:
+ ret = new EriDisplayInformation(
+ roamInd,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText11).toString());
+ break;
+
+ case 12:
+ ret = new EriDisplayInformation(
+ roamInd,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal.R.string.roamingText12).toString());
+ break;
+
+ // Handling the non standard Enhanced Roaming Indicator (roamInd > 63)
+ default:
+ if (!isEriFileLoaded) {
+ // ERI file NOT loaded
+ Log.d(LOG_TAG, "ERI File not loaded");
+ if(defRoamInd > 2) {
+ Log.d(LOG_TAG, "ERI defRoamInd > 2 ...flashing");
+ ret = new EriDisplayInformation(
+ EriInfo.ROAMING_INDICATOR_FLASH,
+ EriInfo.ROAMING_ICON_MODE_FLASH,
+ mContext.getText(com.android.internal
+ .R.string.roamingText2).toString());
+ } else {
+ Log.d(LOG_TAG, "ERI defRoamInd <= 2");
+ switch (defRoamInd) {
+ case EriInfo.ROAMING_INDICATOR_ON:
+ ret = new EriDisplayInformation(
+ EriInfo.ROAMING_INDICATOR_ON,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal
+ .R.string.roamingText0).toString());
+ break;
+
+ case EriInfo.ROAMING_INDICATOR_OFF:
+ ret = new EriDisplayInformation(
+ EriInfo.ROAMING_INDICATOR_OFF,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal
+ .R.string.roamingText1).toString());
+ break;
+
+ case EriInfo.ROAMING_INDICATOR_FLASH:
+ ret = new EriDisplayInformation(
+ EriInfo.ROAMING_INDICATOR_FLASH,
+ EriInfo.ROAMING_ICON_MODE_FLASH,
+ mContext.getText(com.android.internal
+ .R.string.roamingText2).toString());
+ break;
+
+ default:
+ ret = new EriDisplayInformation(-1, -1, "ERI text");
+ }
+ }
+ } else {
+ // ERI file loaded
+ Log.d(LOG_TAG, "ERI File loaded");
+ EriInfo eriInfo = getEriInfo(roamInd);
+ EriInfo defEriInfo = getEriInfo(defRoamInd);
+ if (eriInfo == null) {
+ Log.d(LOG_TAG, "ERI roamInd " + roamInd
+ + " not found in ERI file ...using defRoamInd " + defRoamInd);
+ if(defEriInfo == null) {
+ Log.e(LOG_TAG, "ERI defRoamInd " + defRoamInd
+ + " not found in ERI file ...on");
+ ret = new EriDisplayInformation(
+ EriInfo.ROAMING_INDICATOR_ON,
+ EriInfo.ROAMING_ICON_MODE_NORMAL,
+ mContext.getText(com.android.internal
+ .R.string.roamingText0).toString());
+
+ } else {
+ Log.d(LOG_TAG, "ERI defRoamInd " + defRoamInd + " found in ERI file");
+ ret = new EriDisplayInformation(
+ defEriInfo.mIconIndex,
+ defEriInfo.mIconMode,
+ defEriInfo.mEriText);
+ }
+ } else {
+ Log.d(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file");
+ ret = new EriDisplayInformation(
+ eriInfo.mIconIndex,
+ eriInfo.mIconMode,
+ eriInfo.mEriText);
+ }
+ }
+ break;
+ }
+ Log.d(LOG_TAG, "Displaying ERI " + ret.toString());
+ return ret;
+ }
+
+ public int getCdmaEriIconIndex(int roamInd, int defRoamInd){
+ return getEriDisplayInformation(roamInd, defRoamInd).mEriIconIndex;
+ }
+
+ public int getCdmaEriIconMode(int roamInd, int defRoamInd){
+ return getEriDisplayInformation(roamInd, defRoamInd).mEriIconMode;
+ }
+
+ public String getCdmaEriText(int roamInd, int defRoamInd){
+ return getEriDisplayInformation(roamInd, defRoamInd).mEriIconText;
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java b/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java
index c226b62..23a4ac7 100644
--- a/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java
+++ b/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java
@@ -84,7 +84,6 @@ public final class FeatureCode extends Handler implements MmiCode {
CDMAPhone phone;
Context context;
-
String action; // '*' in CDMA
String sc; // Service Code
String poundString; // Entire Flash string
@@ -237,10 +236,9 @@ public final class FeatureCode extends Handler implements MmiCode {
}
/** Process a Flash Code...anything that isn't a dialing number */
- void processCode () {
+ void processCode() {
Log.d(LOG_TAG, "send feature code...");
- phone.mCM.sendCDMAFeatureCode(this.poundString,
- obtainMessage(EVENT_CDMA_FLASH_COMPLETED));
+ phone.mCM.sendCDMAFeatureCode(this.poundString, obtainMessage(EVENT_CDMA_FLASH_COMPLETED));
}
/** Called from CDMAPhone.handleMessage; not a Handler subclass */
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
index 9de6c42..3e2a29b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
@@ -68,7 +68,12 @@ public final class RuimFileHandler extends IccFileHandler {
}
protected String getEFPath(int efid) {
- // TODO(): Implement for CDMA EFs.
+ switch(efid) {
+ case EF_SMS:
+ case EF_CST:
+ case EF_RUIM_SPN:
+ return MF_SIM + DF_CDMA;
+ }
return getCommonIccEFPath(efid);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index b18a3f1..c7e61da 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -16,19 +16,17 @@
package com.android.internal.telephony.cdma;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.Registrant;
import android.util.Log;
-import static com.android.internal.telephony.TelephonyProperties.*;
import com.android.internal.telephony.AdnRecord;
import com.android.internal.telephony.AdnRecordCache;
import com.android.internal.telephony.AdnRecordLoader;
import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.cdma.RuimCard;
import com.android.internal.telephony.gsm.MccTable;
@@ -39,6 +37,10 @@ import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.PhoneProxy;
+import com.android.internal.telephony.TelephonyIntents;
+import android.app.ActivityManagerNative;
+import android.content.Intent;
+
/**
* {@hide}
@@ -47,15 +49,17 @@ public final class RuimRecords extends IccRecords {
static final String LOG_TAG = "CDMA";
private static final boolean DBG = true;
+ private boolean m_ota_commited=false;
//***** Instance Variables
- String imsi_m;
- String mdn = null; // My mobile number
- String h_sid;
- String h_nid;
- String min2_min1; // 10 digit MIN value MIN2+MIN1 NEWRIL:TODO currently unused
- // is not initialized
+ private String mImsi;
+ private String mMyMobileNumber;
+ private String mSid;
+ private String mNid;
+ private String mMin2Min1;
+
+ private String mPrlVersion;
//***** Event Constants
@@ -63,6 +67,7 @@ public final class RuimRecords extends IccRecords {
private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
private static final int EVENT_GET_DEVICE_IDENTITY_DONE = 4;
private static final int EVENT_GET_ICCID_DONE = 5;
+ private static final int EVENT_NV_READY = 9;
private static final int EVENT_GET_CDMA_SUBSCRIPTION_DONE = 10;
private static final int EVENT_UPDATE_DONE = 14;
private static final int EVENT_GET_SST_DONE = 17;
@@ -73,8 +78,7 @@ public final class RuimRecords extends IccRecords {
private static final int EVENT_GET_SMS_DONE = 22;
private static final int EVENT_RUIM_REFRESH = 31;
-
- //***** Constructor
+ private static final int EVENT_OTA_PROVISION_STATUS_CHANGE = 32;
RuimRecords(CDMAPhone p) {
super(p);
@@ -88,12 +92,14 @@ public final class RuimRecords extends IccRecords {
p.mCM.registerForRUIMReady(this, EVENT_RUIM_READY, null);
+ p.mCM.registerForNVReady(this, EVENT_NV_READY, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
// NOTE the EVENT_SMS_ON_RUIM is not registered
p.mCM.setOnIccRefresh(this, EVENT_RUIM_REFRESH, null);
// Start off by setting empty state
onRadioOffOrNotAvailable();
+ p.mCM.registerForCdmaOtaProvision(this,EVENT_OTA_PROVISION_STATUS_CHANGE, null);
}
@@ -102,12 +108,16 @@ public final class RuimRecords extends IccRecords {
phone.mCM.unregisterForRUIMReady(this);
phone.mCM.unregisterForOffOrNotAvailable( this);
phone.mCM.unSetOnIccRefresh(this);
+ phone.mCM.unregisterForNVReady(this);
+ phone.mCM.unregisterForCdmaOtaProvision(this);
}
+ @Override
protected void finalize() {
if(DBG) Log.d(LOG_TAG, "RuimRecords finalized");
}
+ @Override
protected void onRadioOffOrNotAvailable() {
countVoiceMessages = 0;
mncLength = 0;
@@ -115,8 +125,8 @@ public final class RuimRecords extends IccRecords {
adnCache.reset();
- phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null);
- phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, null);
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
// recordsRequested is set to false indicating that the SIM
// read requests made so far are not valid. This is set to
@@ -124,17 +134,26 @@ public final class RuimRecords extends IccRecords {
recordsRequested = false;
}
- //***** Public Methods
-
/** Returns null if RUIM is not yet ready */
public String getIMSI_M() {
- return imsi_m;
+ // TODO(Moto): mImsi is not initialized, fix.
+ return mImsi;
}
public String getMdnNumber() {
- return mdn;
+ return mMyMobileNumber;
+ }
+
+ public String getCdmaMin() {
+ return mMin2Min1;
}
+ /** Returns null if RUIM is not yet ready */
+ public String getPrlVersion() {
+ return mPrlVersion;
+ }
+
+ @Override
public void setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete){
// In CDMA this is Operator/OEM dependent
AsyncResult.forMessage((onComplete)).exception =
@@ -148,6 +167,7 @@ public final class RuimRecords extends IccRecords {
* @param fileChanged indicates whether any files changed
* @param fileList if non-null, a list of EF files that changed
*/
+ @Override
public void onRefresh(boolean fileChanged, int[] fileList) {
if (fileChanged) {
// A future optimization would be to inspect fileList and
@@ -157,32 +177,31 @@ public final class RuimRecords extends IccRecords {
}
}
- /** Returns the 5 or 6 digit MCC/MNC of the operator that
+ /**
+ * Returns the 5 or 6 digit MCC/MNC of the operator that
* provided the RUIM card. Returns null of RUIM is not yet ready
*/
- String getRUIMOperatorNumeric() {
- if (imsi_m == null) {
+ public String getRUIMOperatorNumeric() {
+ if (mImsi == null) {
return null;
}
+ // TODO(Moto): mncLength is not set anywhere.
if (mncLength != 0) {
// Length = length of MCC + length of MNC
// TODO: change spec name
// length of mcc = 3 (3GPP2 C.S0005 - Section 2.3)
- return imsi_m.substring(0, 3 + mncLength);
+ return mImsi.substring(0, 3 + mncLength);
}
// Guess the MNC length based on the MCC if we don't
// have a valid value in ef[ad]
- int mcc;
-
- mcc = Integer.parseInt(imsi_m.substring(0,3));
-
- return imsi_m.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
+ int mcc = Integer.parseInt(mImsi.substring(0,3));
+ return mImsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
}
- //***** Overridden from Handler
+ @Override
public void handleMessage(Message msg) {
AsyncResult ar;
@@ -194,7 +213,9 @@ public final class RuimRecords extends IccRecords {
case EVENT_RUIM_READY:
onRuimReady();
break;
-
+ case EVENT_NV_READY:
+ onNvReady();
+ break;
case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
onRadioOffOrNotAvailable();
break;
@@ -211,15 +232,22 @@ public final class RuimRecords extends IccRecords {
if (ar.exception != null) {
break;
}
-
- mdn = localTemp[0];
- h_sid = localTemp[1];
- h_nid = localTemp[2];
- if (localTemp.length >= 3) { // NEWRIL:TODO remove when new ril always returns min2_min1
- min2_min1 = localTemp[3];
+ if (m_ota_commited) {
+ if (mMyMobileNumber != localTemp[0]) {
+ Intent intent = new Intent(TelephonyIntents.ACTION_CDMA_OTA_MDN_CHANGED);
+ intent.putExtra("mdn", localTemp[0]);
+ Log.d(LOG_TAG,"Broadcasting intent MDN Change in OTA ");
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+ }
+ m_ota_commited = false;
}
+ mMyMobileNumber = localTemp[0];
+ mSid = localTemp[1];
+ mNid = localTemp[2];
+ mMin2Min1 = localTemp[3];
+ mPrlVersion = localTemp[4];
- Log.d(LOG_TAG, "MDN: " + mdn);
+ Log.d(LOG_TAG, "MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1);
break;
@@ -266,6 +294,21 @@ public final class RuimRecords extends IccRecords {
}
break;
+ case EVENT_OTA_PROVISION_STATUS_CHANGE:
+ m_ota_commited=false;
+ ar = (AsyncResult)msg.obj;
+ if (ar.exception == null) {
+ int[] ints = (int[]) ar.result;
+ int otaStatus = ints[0];
+ if (otaStatus == phone.CDMA_OTA_PROVISION_STATUS_COMMITTED) {
+ m_ota_commited=true;
+ phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
+ } else if (otaStatus == phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED) {
+ phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
+ }
+ }
+ break;
+
}}catch (RuntimeException exc) {
// I don't want these exceptions to be fatal
Log.w(LOG_TAG, "Exception parsing RUIM record", exc);
@@ -277,6 +320,7 @@ public final class RuimRecords extends IccRecords {
}
}
+ @Override
protected void onRecordLoaded() {
// One record loaded successfully or failed, In either case
// we need to update the recordsToLoad count
@@ -290,6 +334,7 @@ public final class RuimRecords extends IccRecords {
}
}
+ @Override
protected void onAllRecordsLoaded() {
Log.d(LOG_TAG, "RuimRecords: record load complete");
@@ -301,9 +346,6 @@ public final class RuimRecords extends IccRecords {
RuimCard.INTENT_VALUE_ICC_LOADED, null);
}
-
- //***** Private Methods
-
private void onRuimReady() {
/* broadcast intent ICC_READY here so that we can make sure
READY is sent before IMSI ready
@@ -318,6 +360,11 @@ public final class RuimRecords extends IccRecords {
}
+ private void onNvReady() {
+ phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
+
+ }
+
private void fetchRuimRecords() {
recordsRequested = true;
@@ -364,17 +411,17 @@ public final class RuimRecords extends IccRecords {
switch ((result[0])) {
case CommandsInterface.SIM_REFRESH_FILE_UPDATED:
- if (DBG) log("handleRuimRefresh with SIM_REFRESH_FILE_UPDATED");
+ if (DBG) log("handleRuimRefresh with SIM_REFRESH_FILE_UPDATED");
adnCache.reset();
fetchRuimRecords();
break;
case CommandsInterface.SIM_REFRESH_INIT:
- if (DBG) log("handleRuimRefresh with SIM_REFRESH_INIT");
+ if (DBG) log("handleRuimRefresh with SIM_REFRESH_INIT");
// need to reload all files (that we care about)
fetchRuimRecords();
break;
case CommandsInterface.SIM_REFRESH_RESET:
- if (DBG) log("handleRuimRefresh with SIM_REFRESH_RESET");
+ if (DBG) log("handleRuimRefresh with SIM_REFRESH_RESET");
phone.mCM.setRadioPower(false, null);
/* Note: no need to call setRadioPower(true). Assuming the desired
* radio power state is still ON (as tracked by ServiceStateTracker),
@@ -386,14 +433,14 @@ public final class RuimRecords extends IccRecords {
break;
default:
// unknown refresh operation
- if (DBG) log("handleRuimRefresh with unknown operation");
+ if (DBG) log("handleRuimRefresh with unknown operation");
break;
}
}
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[RuimRecords] " + s);
}
}
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
new file mode 100644
index 0000000..44958e9
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
@@ -0,0 +1,280 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.telephony.cdma;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import android.util.Log;
+import android.media.ToneGenerator;
+
+public class SignalToneUtil {
+ /** A marker that isn't a valid TONE */
+ public static final int CDMA_INVALID_TONE = -1;
+
+ // public final int int IS95_CONST_IR_SIGNAL_TYPE_TYPE;
+ static public final int IS95_CONST_IR_SIGNAL_TONE = 0;
+ static public final int IS95_CONST_IR_SIGNAL_ISDN = 1;
+ static public final int IS95_CONST_IR_SIGNAL_IS54B = 2;
+ static public final int IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT = 4;
+
+ // public final int int IS95_CONST_IR_ALERT_PITCH_TYPE;
+ static public final int IS95_CONST_IR_ALERT_MED = 0;
+ static public final int IS95_CONST_IR_ALERT_HIGH = 1;
+ static public final int IS95_CONST_IR_ALERT_LOW = 2;
+ static public final int TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN = 255;
+
+ // public final int int IS95_CONST_IR_SIGNAL_TYPE;
+ static public final int IS95_CONST_IR_SIG_ISDN_NORMAL = 0;
+ static public final int IS95_CONST_IR_SIG_ISDN_INTGRP = 1;
+ static public final int IS95_CONST_IR_SIG_ISDN_SP_PRI = 2;
+ static public final int IS95_CONST_IR_SIG_ISDN_PAT_3 = 3;
+ static public final int IS95_CONST_IR_SIG_ISDN_PING = 4;
+ static public final int IS95_CONST_IR_SIG_ISDN_PAT_5 = 5;
+ static public final int IS95_CONST_IR_SIG_ISDN_PAT_6 = 6;
+ static public final int IS95_CONST_IR_SIG_ISDN_PAT_7 = 7;
+ static public final int IS95_CONST_IR_SIG_ISDN_OFF = 15;
+ static public final int IS95_CONST_IR_SIG_TONE_DIAL = 0;
+ static public final int IS95_CONST_IR_SIG_TONE_RING = 1;
+ static public final int IS95_CONST_IR_SIG_TONE_INT = 2;
+ static public final int IS95_CONST_IR_SIG_TONE_ABB_INT = 3;
+ static public final int IS95_CONST_IR_SIG_TONE_REORDER = 4;
+ static public final int IS95_CONST_IR_SIG_TONE_ABB_RE = 5;
+ static public final int IS95_CONST_IR_SIG_TONE_BUSY = 6;
+ static public final int IS95_CONST_IR_SIG_TONE_CONFIRM = 7;
+ static public final int IS95_CONST_IR_SIG_TONE_ANSWER = 8;
+ static public final int IS95_CONST_IR_SIG_TONE_CALL_W = 9;
+ static public final int IS95_CONST_IR_SIG_TONE_PIP = 10;
+ static public final int IS95_CONST_IR_SIG_TONE_NO_TONE = 63;
+ static public final int IS95_CONST_IR_SIG_IS54B_NO_TONE = 0;
+ static public final int IS95_CONST_IR_SIG_IS54B_L = 1;
+ static public final int IS95_CONST_IR_SIG_IS54B_SS = 2;
+ static public final int IS95_CONST_IR_SIG_IS54B_SSL = 3;
+ static public final int IS95_CONST_IR_SIG_IS54B_SS_2 = 4;
+ static public final int IS95_CONST_IR_SIG_IS54B_SLS = 5;
+ static public final int IS95_CONST_IR_SIG_IS54B_S_X4 = 6;
+ static public final int IS95_CONST_IR_SIG_IS54B_PBX_L = 7;
+ static public final int IS95_CONST_IR_SIG_IS54B_PBX_SS = 8;
+ static public final int IS95_CONST_IR_SIG_IS54B_PBX_SSL = 9;
+ static public final int IS95_CONST_IR_SIG_IS54B_PBX_SLS = 10;
+ static public final int IS95_CONST_IR_SIG_IS54B_PBX_S_X4 = 11;
+ static public final int IS95_CONST_IR_SIG_TONE_ABBR_ALRT = 0;
+
+ // Hashmap to map signalInfo To AudioTone
+ static private HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
+
+ private static Integer signalParamHash(int signalType, int alertPitch, int signal) {
+ if ((signalType < 0) || (signalType > 256) || (alertPitch > 256) ||
+ (alertPitch < 0) || (signal > 256) || (signal < 0)) {
+ return new Integer(CDMA_INVALID_TONE);
+ }
+ return new Integer(signalType * 256 * 256 + alertPitch * 256 + signal);
+ }
+
+ public static int getAudioToneFromSignalInfo(int signalType, int alertPitch, int signal) {
+ Integer result = hm.get(signalParamHash(signalType, alertPitch, signal));
+ if (result == null) {
+ return CDMA_INVALID_TONE;
+ }
+ return result;
+ }
+
+ static {
+
+ /* SIGNAL_TYPE_ISDN */
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_ISDN_NORMAL), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_ISDN_INTGRP),
+ ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_ISDN_SP_PRI), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_ISDN_PAT_3), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT3);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_ISDN_PING), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_ISDN_PAT_5), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT5);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_ISDN_PAT_6), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT6);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_ISDN_PAT_7), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT7);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_ISDN_OFF), ToneGenerator.TONE_CDMA_SIGNAL_OFF);
+
+ /* SIGNAL_TYPE_TONE */
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_DIAL), ToneGenerator.TONE_CDMA_DIAL_TONE_LITE);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_RING), ToneGenerator.TONE_CDMA_NETWORK_USA_RINGBACK);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_INT), ToneGenerator.TONE_SUP_INTERCEPT);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_ABB_INT), ToneGenerator.TONE_SUP_INTERCEPT_ABBREV);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_REORDER), ToneGenerator.TONE_CDMA_REORDER);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_ABB_RE), ToneGenerator.TONE_CDMA_ABBR_REORDER);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_BUSY), ToneGenerator.TONE_CDMA_NETWORK_BUSY);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_CONFIRM), ToneGenerator.TONE_SUP_CONFIRM);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_ANSWER), ToneGenerator.TONE_CDMA_ANSWER);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_ABB_RE), ToneGenerator.TONE_CDMA_NETWORK_CALLWAITING);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_PIP), ToneGenerator.TONE_CDMA_PIP);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_TONE_NO_TONE), ToneGenerator.TONE_CDMA_SIGNAL_OFF);
+
+ /* SIGNAL_TYPE_IS54B */
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_HIGH_L);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_MED_L);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_LOW_L);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_HIGH_SS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_MED_SS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_LOW_SS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_HIGH_SSL);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_MED_SSL);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_LOW_SSL);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_HIGH_SS_2);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_MED_SS_2);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_LOW_SS_2);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_HIGH_SLS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_MED_SLS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_LOW_SLS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_HIGH_S_X4);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_MED_S_X4);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_LOW_S_X4);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_HIGH_PBX_L);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_MED_PBX_L);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_LOW_PBX_L);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_HIGH_PBX_SS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_MED_PBX_SS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_LOW_PBX_SS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_HIGH_PBX_SSL);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_MED_PBX_SSL);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_LOW_PBX_SSL);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_HIGH_PBX_SLS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_MED_PBX_SLS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_LOW_PBX_SLS);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
+ IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_HIGH_PBX_S_X4);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
+ IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_MED_PBX_S_X4);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
+ IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_LOW_PBX_S_X4);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
+ IS95_CONST_IR_SIG_IS54B_NO_TONE), ToneGenerator.TONE_CDMA_SIGNAL_OFF);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT,
+ TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, IS95_CONST_IR_SIG_TONE_ABBR_ALRT),
+ ToneGenerator.TONE_CDMA_ABBR_ALERT);
+
+ hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT,
+ TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, IS95_CONST_IR_SIG_TONE_NO_TONE),
+ ToneGenerator.TONE_CDMA_ABBR_ALERT);
+
+ }
+
+ // suppress default constructor for noninstantiability
+ private SignalToneUtil() {
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 343a22e..3a92064 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -277,6 +277,15 @@ public class SmsMessage extends SmsMessageBase {
}
/**
+ * TODO(cleanup): why do getSubmitPdu methods take an scAddr input
+ * and do nothing with it? GSM allows us to specify a SC (eg,
+ * when responding to an SMS that explicitly requests the response
+ * is sent to a specific SC), or pass null to use the default
+ * value. Is there no similar notion in CDMA? Or do we just not
+ * have it hooked up?
+ */
+
+ /**
* Get an SMS-SUBMIT PDU for a destination address and a message
*
* @param scAddr Service Centre address. Null means use default.
@@ -290,88 +299,53 @@ public class SmsMessage extends SmsMessageBase {
* Returns null on encode error.
* @hide
*/
- public static SubmitPdu getSubmitPdu(String scAddr,
- String destAddr, String message,
- boolean statusReportRequested, byte[] headerData) {
+ public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message,
+ boolean statusReportRequested, SmsHeader smsHeader) {
+
/**
- * TODO(cleanup): why does this method take an scAddr input
- * and do nothing with it? GSM allows us to specify a SC (eg,
- * when responding to an SMS that explicitly requests the
- * response is sent to a specific SC), or pass null to use the
- * default value. Is there no similar notion in CDMA? Or do
- * we just not have it hooked up?
+ * TODO(cleanup): Do we really want silent failure like this?
+ * Would it not be much more reasonable to make sure we don't
+ * call this function if we really want nothing done?
*/
-
if (message == null || destAddr == null) {
return null;
}
UserData uData = new UserData();
uData.payloadStr = message;
- if(headerData != null) {
- /**
- * TODO(cleanup): we force the outside to deal with _all_
- * of the raw details of properly constructing serialized
- * headers, unserialze here, and then promptly reserialze
- * during encoding -- rather undesirable.
- */
- uData.userDataHeader = SmsHeader.parse(headerData);
- }
-
- return privateGetSubmitPdu(destAddr, statusReportRequested, uData, (headerData == null));
- }
-
-
- /**
- * Get an SMS-SUBMIT PDU for a destination address and a message
- *
- * @param scAddress Service Centre address. Null means use default.
- * @return a <code>SubmitPdu</code> containing the encoded SC
- * address, if applicable, and the encoded message.
- * Returns null on encode error.
- */
- public static SubmitPdu getSubmitPdu(String scAddress,
- String destinationAddress, String message,
- boolean statusReportRequested) {
- return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, null);
+ uData.userDataHeader = smsHeader;
+ return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
}
/**
* Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
*
- * @param scAddress Service Centre address. null == use default
- * @param destinationAddress the address of the destination for the message
- * @param destinationPort the port to deliver the message to at the
+ * @param scAddr Service Centre address. null == use default
+ * @param destAddr the address of the destination for the message
+ * @param destPort the port to deliver the message to at the
* destination
* @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.
*/
- public static SubmitPdu getSubmitPdu(String scAddress,
- String destAddr, short destinationPort, byte[] data,
- boolean statusReportRequested) {
+ public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, short destPort,
+ byte[] data, boolean statusReportRequested) {
/**
- * TODO(cleanup): if we had properly exposed SmsHeader
- * information, this mess of many getSubmitPdu public
- * interface methods that currently pollute the api could have
- * been much more cleanly collapsed into one.
+ * TODO(cleanup): this is not a general-purpose SMS creation
+ * method, but rather something specialized to messages
+ * containing OCTET encoded (meaning non-human-readable) user
+ * data. The name should reflect that, and not just overload.
*/
- /**
- * TODO(cleanup): header serialization should be put somewhere
- * canonical to allow proper debugging and reuse.
- */
- byte[] destPort = new byte[4];
- destPort[0] = (byte) ((destinationPort >> 8) & 0xFF); // MSB of destination port
- destPort[1] = (byte) (destinationPort & 0xFF); // LSB of destination port
- destPort[2] = 0x00; // MSB of originating port
- destPort[3] = 0x00; // LSB of originating port
+ SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs();
+ portAddrs.destPort = destPort;
+ portAddrs.origPort = 0;
+ portAddrs.areEightBits = false;
+
SmsHeader smsHeader = new SmsHeader();
- smsHeader.add(
- new SmsHeader.Element(SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT, destPort));
- smsHeader.nbrOfHeaders = smsHeader.getElements().size();
+ smsHeader.portAddrs = portAddrs;
UserData uData = new UserData();
uData.userDataHeader = smsHeader;
@@ -379,40 +353,22 @@ public class SmsMessage extends SmsMessageBase {
uData.msgEncodingSet = true;
uData.payload = data;
- return privateGetSubmitPdu(destAddr, statusReportRequested, uData, true);
+ return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
}
- static class PduParser {
-
- PduParser() {
- }
-
- /**
- * Parses an SC timestamp and returns a currentTimeMillis()-style
- * timestamp
- */
- static long getSCTimestampMillis(byte[] timestamp) {
- // TP-Service-Centre-Time-Stamp
- int year = IccUtils.beBcdByteToInt(timestamp[0]);
- int month = IccUtils.beBcdByteToInt(timestamp[1]);
- int day = IccUtils.beBcdByteToInt(timestamp[2]);
- int hour = IccUtils.beBcdByteToInt(timestamp[3]);
- int minute = IccUtils.beBcdByteToInt(timestamp[4]);
- int second = IccUtils.beBcdByteToInt(timestamp[5]);
-
- Time time = new Time(Time.TIMEZONE_UTC);
-
- // C.S0015-B v2.0, 4.5.4: range is 1996-2095
- time.year = year >= 96 ? year + 1900 : year + 2000;
- time.month = month - 1;
- time.monthDay = day;
- time.hour = hour;
- time.minute = minute;
- time.second = second;
-
- return time.toMillis(true);
- }
-
+ /**
+ * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
+ *
+ * @param destAddr the address of the destination for the message
+ * @param userDara the data for the message
+ * @param statusReportRequested Indicates whether a report is requested for this message.
+ * @return a <code>SubmitPdu</code> containing the encoded SC
+ * address, if applicable, and the encoded message.
+ * Returns null on encode error.
+ */
+ public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
+ boolean statusReportRequested) {
+ return privateGetSubmitPdu(destAddr, statusReportRequested, userData);
}
/**
@@ -445,31 +401,23 @@ public class SmsMessage extends SmsMessageBase {
* {@inheritDoc}
*/
public boolean isMWIClearMessage() {
- if ((mBearerData != null) && (0 == mBearerData.numberOfMessages)) {
- return true;
- }
- return false;
+ return ((mBearerData != null) && (mBearerData.numberOfMessages == 0));
}
/**
* {@inheritDoc}
*/
public boolean isMWISetMessage() {
- if ((mBearerData != null) && (mBearerData.numberOfMessages >0)) {
- return true;
- }
- return false;
+ return ((mBearerData != null) && (mBearerData.numberOfMessages > 0));
}
/**
* {@inheritDoc}
*/
public boolean isMwiDontStore() {
- if ((mBearerData != null) && (mBearerData.numberOfMessages >0)
- && (null == mBearerData.userData)) {
- return true;
- }
- return false;
+ return ((mBearerData != null) &&
+ (mBearerData.numberOfMessages > 0) &&
+ (mBearerData.userData == null));
}
/**
@@ -478,7 +426,7 @@ public class SmsMessage extends SmsMessageBase {
* shifted to the bits 31-16.
*/
public int getStatus() {
- return(status<<16);
+ return (status << 16);
}
/**
@@ -498,6 +446,18 @@ public class SmsMessage extends SmsMessageBase {
}
/**
+ * Calculate the number of septets needed to encode the message.
+ *
+ * @param messageBody the message to encode
+ * @param use7bitOnly ignore (but still count) illegal characters if true
+ * @return TextEncodingDetails
+ */
+ public static TextEncodingDetails calculateLength(CharSequence messageBody,
+ boolean use7bitOnly) {
+ return BearerData.calcTextEncodingDetails(messageBody.toString(), use7bitOnly);
+ }
+
+ /**
* Returns the teleservice type of the message.
* @return the teleservice:
* {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_NOT_SET},
@@ -518,7 +478,7 @@ public class SmsMessage extends SmsMessageBase {
*/
private void parsePdu(byte[] pdu) {
ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
- DataInputStream dis = new DataInputStream(new BufferedInputStream(bais));
+ DataInputStream dis = new DataInputStream(bais);
byte length;
int bearerDataLength;
SmsEnvelope env = new SmsEnvelope();
@@ -568,90 +528,42 @@ public class SmsMessage extends SmsMessageBase {
protected void parseSms() {
mBearerData = BearerData.decode(mEnvelope.bearerData);
messageRef = mBearerData.messageId;
+ if (mBearerData.userData != null) {
+ userData = mBearerData.userData.payload;
+ userDataHeader = mBearerData.userData.userDataHeader;
+ messageBody = mBearerData.userData.payloadStr;
+ }
- // TP-Message-Type-Indicator
- // (See 3GPP2 C.S0015-B, v2, 4.5.1)
- int messageType = mBearerData.messageType;
-
- switch (messageType) {
+ // TP-Message-Type-Indicator (See 3GPP2 C.S0015-B, v2, 4.5.1)
+ switch (mBearerData.messageType) {
case BearerData.MESSAGE_TYPE_USER_ACK:
case BearerData.MESSAGE_TYPE_READ_ACK:
case BearerData.MESSAGE_TYPE_DELIVER:
- // Deliver (mobile-terminated only)
- parseSmsDeliver();
- break;
case BearerData.MESSAGE_TYPE_DELIVERY_ACK:
- parseSmsDeliveryAck();
break;
-
default:
- // the rest of these
- throw new RuntimeException("Unsupported message type: " + messageType);
+ throw new RuntimeException("Unsupported message type: " + mBearerData.messageType);
}
- }
- /**
- * TODO(cleanup): why are there two nearly identical functions
- * below? More rubbish...
- */
-
- /**
- * Parses a SMS-DELIVER message. (mobile-terminated only)
- * See 3GPP2 C.S0015-B, v2, 4.4.1
- */
- private void parseSmsDeliver() {
if (originatingAddress != null) {
originatingAddress.address = new String(originatingAddress.origBytes);
if (Config.LOGV) Log.v(LOG_TAG, "SMS originating address: "
+ originatingAddress.address);
}
- if (mBearerData.timeStamp != null) {
- scTimeMillis = PduParser.getSCTimestampMillis(mBearerData.timeStamp);
+ if (mBearerData.msgCenterTimeStamp != null) {
+ scTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true);
}
if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
- parseUserData(mBearerData.userData);
- }
-
- /**
- * Parses a SMS-DELIVER message. (mobile-terminated only)
- * See 3GPP2 C.S0015-B, v2, 4.4.1
- */
- private void parseSmsDeliveryAck() {
- if (originatingAddress != null) {
- originatingAddress.address = new String(originatingAddress.origBytes);
- if (Config.LOGV) Log.v(LOG_TAG, "SMS originating address: "
- + originatingAddress.address);
- }
-
- if (mBearerData.timeStamp != null) {
- scTimeMillis = PduParser.getSCTimestampMillis(mBearerData.timeStamp);
- }
-
- if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
-
- if (mBearerData.errorClass != BearerData.ERROR_UNDEFINED) {
+ // TODO(Teleca): do we really want this test to occur only for DELIVERY_ACKs?
+ if ((mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) &&
+ (mBearerData.errorClass != BearerData.ERROR_UNDEFINED)) {
status = mBearerData.errorClass << 8;
status |= mBearerData.messageStatus;
}
- parseUserData(mBearerData.userData);
- }
-
- /**
- * Copy parsed user data out from internal datastructures.
- */
- private void parseUserData(UserData uData) {
- if (uData == null) {
- return;
- }
-
- userData = uData.payload;
- userDataHeader = uData.userDataHeader;
- messageBody = uData.payloadStr;
-
if (messageBody != null) {
if (Config.LOGV) Log.v(LOG_TAG, "SMS message body: '" + messageBody + "'");
parseMessageBody();
@@ -708,7 +620,7 @@ public class SmsMessage extends SmsMessageBase {
* @return byte stream for SubmitPdu.
*/
private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested,
- UserData userData, boolean useNewId) {
+ UserData userData) {
/**
* TODO(cleanup): give this function a more meaningful name.
@@ -720,7 +632,7 @@ public class SmsMessage extends SmsMessageBase {
BearerData bearerData = new BearerData();
bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT;
- if (useNewId) setNextMessageId();
+ if (userData != null) setNextMessageId();
bearerData.messageId = nextMessageId;
bearerData.deliveryAckReq = statusReportRequested;
@@ -731,12 +643,15 @@ public class SmsMessage extends SmsMessageBase {
bearerData.userData = userData;
bearerData.hasUserDataHeader = (userData.userDataHeader != null);
+ int teleservice = bearerData.hasUserDataHeader ?
+ SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT;
+
byte[] encodedBearerData = BearerData.encode(bearerData);
if (encodedBearerData == null) return null;
SmsEnvelope envelope = new SmsEnvelope();
envelope.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
- envelope.teleService = SmsEnvelope.TELESERVICE_WMT;
+ envelope.teleService = teleservice;
envelope.destAddress = destAddr;
envelope.bearerReply = RETURN_ACK;
envelope.bearerData = encodedBearerData;
@@ -812,6 +727,15 @@ public class SmsMessage extends SmsMessageBase {
dos.write(env.bearerData, 0, env.bearerData.length);
dos.close();
+ /**
+ * TODO(cleanup) -- This is the only place where mPdu is
+ * defined, and this is not obviously the only place where
+ * it needs to be defined. It would be much nicer if
+ * accessing the serialized representation used a less
+ * fragile mechanism. Maybe the getPdu method could
+ * generate a representation if there was not yet one?
+ */
+
mPdu = baos.toByteArray();
} catch (IOException ex) {
Log.e(LOG_TAG, "createPdu: conversion from object to byte array failed: " + ex);
@@ -849,6 +773,12 @@ public class SmsMessage extends SmsMessageBase {
return asciiDigit;
}
+ /** This function shall be called to get the number of voicemails.
+ * @hide
+ */
+ /*package*/ int getNumOfVoicemails() {
+ return mBearerData.numberOfMessages;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/package.html b/telephony/java/com/android/internal/telephony/cdma/package.html
index cf1ad4a..4eb1f9c 100644
--- a/telephony/java/com/android/internal/telephony/cdma/package.html
+++ b/telephony/java/com/android/internal/telephony/cdma/package.html
@@ -1,6 +1,6 @@
<HTML>
<BODY>
-Provides classes to control or read data from CDMA phones.
+Provides classes to control or read data from CDMA phones.
@hide
</BODY>
</HTML>
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 e64d022..ef3afff 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -17,12 +17,17 @@
package com.android.internal.telephony.cdma.sms;
import android.util.Log;
+import android.util.SparseIntArray;
import android.telephony.SmsMessage;
+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;
@@ -32,21 +37,22 @@ import com.android.internal.util.BitwiseOutputStream;
/**
* An object to encode and decode CDMA SMS bearer data.
*/
-public final class BearerData{
+public final class BearerData {
private final static String LOG_TAG = "SMS";
/**
* Bearer Data Subparameter Indentifiers
* (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_MESSAGE_CENTER_TIME_STAMP = 0x03;
- //private final static byte SUBPARAM_VALIDITY_PERIOD_ABSOLUTE = 0x04;
- //private final static byte SUBPARAM_VALIDITY_PERIOD_RELATIVE = 0x05;
- //private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE = 0x06;
- //private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE = 0x07;
+ private final static byte SUBPARAM_VALIDITY_PERIOD_ABSOLUTE = 0x04;
+ private final static byte SUBPARAM_VALIDITY_PERIOD_RELATIVE = 0x05;
+ private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE = 0x06;
+ private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE = 0x07;
private final static byte SUBPARAM_PRIORITY_INDICATOR = 0x08;
private final static byte SUBPARAM_PRIVACY_INDICATOR = 0x09;
private final static byte SUBPARAM_REPLY_OPTION = 0x0A;
@@ -56,7 +62,7 @@ public final class BearerData{
private final static byte SUBPARAM_CALLBACK_NUMBER = 0x0E;
private final static byte SUBPARAM_MESSAGE_DISPLAY_MODE = 0x0F;
//private final static byte SUBPARAM_MULTIPLE_ENCODING_USER_DATA = 0x10;
- //private final static byte SUBPARAM_MESSAGE_DEPOSIT_INDEX = 0x11;
+ private final static byte SUBPARAM_MESSAGE_DEPOSIT_INDEX = 0x11;
//private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA = 0x12;
//private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS = 0x13;
private final static byte SUBPARAM_MESSAGE_STATUS = 0x14;
@@ -77,7 +83,7 @@ public final class BearerData{
public static final int MESSAGE_TYPE_DELIVER_REPORT = 0x07;
public static final int MESSAGE_TYPE_SUBMIT_REPORT = 0x08;
- public byte messageType;
+ public int messageType;
/**
* 16-bit value indicating the message ID, which increments modulo 65536.
@@ -96,7 +102,7 @@ public final class BearerData{
public static final int PRIORITY_EMERGENCY = 0x3;
public boolean priorityIndicatorSet = false;
- public byte priority = PRIORITY_NORMAL;
+ public int priority = PRIORITY_NORMAL;
/**
* Supported privacy modes for CDMA SMS messages
@@ -108,7 +114,7 @@ public final class BearerData{
public static final int PRIVACY_SECRET = 0x3;
public boolean privacyIndicatorSet = false;
- public byte privacy = PRIVACY_NOT_RESTRICTED;
+ public int privacy = PRIVACY_NOT_RESTRICTED;
/**
* Supported alert priority modes for CDMA SMS messages
@@ -133,7 +139,7 @@ public final class BearerData{
public static final int DISPLAY_MODE_USER = 0x2;
public boolean displayModeSet = false;
- public byte displayMode = DISPLAY_MODE_DEFAULT;
+ public int displayMode = DISPLAY_MODE_DEFAULT;
/**
* Language Indicator values. NOTE: the spec (3GPP2 C.S0015-B,
@@ -189,8 +195,12 @@ public final class BearerData{
public int messageStatus = STATUS_UNDEFINED;
/**
- * 1-bit value that indicates whether a User Data Header is present.
+ * 1-bit value that indicates whether a User Data Header (UDH) is present.
* (See 3GPP2 C.S0015-B, v2, 4.5.1)
+ *
+ * NOTE: during encoding, this value will be set based on the
+ * presence of a UDH in the structured data, any existing setting
+ * will be overwritten.
*/
public boolean hasUserDataHeader;
@@ -201,23 +211,94 @@ public final class BearerData{
*/
public UserData userData;
- //public UserResponseCode userResponseCode;
+ /**
+ * The User Response Code subparameter is used in the SMS User
+ * Acknowledgment Message to respond to previously received short
+ * messages. This message center-specific element carries the
+ * identifier of a predefined response. (See 3GPP2 C.S.0015-B, v2,
+ * 4.5.3)
+ */
+ public boolean userResponseCodeSet = false;
+ public int userResponseCode;
/**
* 6-byte-field, see 3GPP2 C.S0015-B, v2, 4.5.4
- * year, month, day, hours, minutes, seconds;
*/
- public byte[] timeStamp;
+ public static class TimeStamp extends Time {
- //public SmsTime validityPeriodAbsolute;
- //public SmsRelTime validityPeriodRelative;
- //public SmsTime deferredDeliveryTimeAbsolute;
- //public SmsRelTime deferredDeliveryTimeRelative;
+ public TimeStamp() {
+ super(Time.TIMEZONE_UTC);
+ }
+
+ public static TimeStamp fromByteArray(byte[] data) {
+ TimeStamp ts = new TimeStamp();
+ // C.S0015-B v2.0, 4.5.4: range is 1996-2095
+ int year = IccUtils.beBcdByteToInt(data[0]);
+ if (year > 99 || year < 0) return null;
+ ts.year = year >= 96 ? year + 1900 : year + 2000;
+ int month = IccUtils.beBcdByteToInt(data[1]);
+ if (month < 1 || month > 12) return null;
+ ts.month = month - 1;
+ int day = IccUtils.beBcdByteToInt(data[2]);
+ if (day < 1 || day > 31) return null;
+ ts.monthDay = day;
+ int hour = IccUtils.beBcdByteToInt(data[3]);
+ if (hour < 0 || hour > 23) return null;
+ ts.hour = hour;
+ int minute = IccUtils.beBcdByteToInt(data[4]);
+ if (minute < 0 || minute > 59) return null;
+ ts.minute = minute;
+ int second = IccUtils.beBcdByteToInt(data[5]);
+ if (second < 0 || second > 59) return null;
+ ts.second = second;
+ return ts;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("TimeStamp ");
+ builder.append("{ year=" + year);
+ builder.append(", month=" + month);
+ builder.append(", day=" + monthDay);
+ builder.append(", hour=" + hour);
+ builder.append(", minute=" + minute);
+ builder.append(", second=" + second);
+ builder.append(" }");
+ return builder.toString();
+ }
+ }
+
+ public TimeStamp msgCenterTimeStamp;
+ public TimeStamp validityPeriodAbsolute;
+ public TimeStamp deferredDeliveryTimeAbsolute;
+
+ /**
+ * Relative time is specified as one byte, the value of which
+ * falls into a series of ranges, as specified below. The idea is
+ * that shorter time intervals allow greater precision -- the
+ * value means minutes from zero until the MINS_LIMIT (inclusive),
+ * upon which it means hours until the HOURS_LIMIT, and so
+ * forth. (See 3GPP2 C.S0015-B, v2, 4.5.6-1)
+ */
+ public static final int RELATIVE_TIME_MINS_LIMIT = 143;
+ public static final int RELATIVE_TIME_HOURS_LIMIT = 167;
+ public static final int RELATIVE_TIME_DAYS_LIMIT = 196;
+ public static final int RELATIVE_TIME_WEEKS_LIMIT = 244;
+ public static final int RELATIVE_TIME_INDEFINITE = 245;
+ public static final int RELATIVE_TIME_NOW = 246;
+ public static final int RELATIVE_TIME_MOBILE_INACTIVE = 247;
+ public static final int RELATIVE_TIME_RESERVED = 248;
+
+ public boolean validityPeriodRelativeSet;
+ public int validityPeriodRelative;
+ public boolean deferredDeliveryTimeRelativeSet;
+ public int deferredDeliveryTimeRelative;
/**
- * Reply Option
- * 1-bit values which indicate whether SMS acknowledgment is requested or not.
- * (See 3GPP2 C.S0015-B, v2, 4.5.11)
+ * The Reply Option subparameter contains 1-bit values which
+ * indicate whether SMS acknowledgment is requested or not. (See
+ * 3GPP2 C.S0015-B, v2, 4.5.11)
*/
public boolean userAckReq;
public boolean deliveryAckReq;
@@ -225,14 +306,28 @@ public final class BearerData{
public boolean reportReq;
/**
- * The number of Messages element (8-bit value) is a decimal number in the 0 to 99 range
- * representing the number of messages stored at the Voice Mail System. This element is
- * used by the Voice Mail Notification service.
- * (See 3GPP2 C.S0015-B, v2, 4.5.12)
+ * The Number of Messages subparameter (8-bit value) is a decimal
+ * number in the 0 to 99 range representing the number of messages
+ * stored at the Voice Mail System. This element is used by the
+ * Voice Mail Notification service. (See 3GPP2 C.S0015-B, v2,
+ * 4.5.12)
*/
public int numberOfMessages;
/**
+ * The Message Deposit Index subparameter is assigned by the
+ * message center as a unique index to the contents of the User
+ * Data subparameter in each message sent to a particular mobile
+ * station. The mobile station, when replying to a previously
+ * received short message which included a Message Deposit Index
+ * subparameter, may include the Message Deposit Index of the
+ * received message to indicate to the message center that the
+ * original contents of the message are to be included in the
+ * reply. (See 3GPP2 C.S0015-B, v2, 4.5.18)
+ */
+ public int depositIndex;
+
+ /**
* 4-bit or 8-bit value that indicates the number to be dialed in reply to a
* received SMS message.
* (See 3GPP2 C.S0015-B, v2, 4.5.15)
@@ -248,25 +343,36 @@ public final class BearerData{
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.append("BearerData:\n");
- builder.append(" messageType: " + messageType + "\n");
- builder.append(" messageId: " + (int)messageId + "\n");
- builder.append(" priority: " + (priorityIndicatorSet ? priority : "not set") + "\n");
- builder.append(" privacy: " + (privacyIndicatorSet ? privacy : "not set") + "\n");
- builder.append(" alert: " + (alertIndicatorSet ? alert : "not set") + "\n");
- builder.append(" displayMode: " + (displayModeSet ? displayMode : "not set") + "\n");
- builder.append(" language: " + (languageIndicatorSet ? language : "not set") + "\n");
- builder.append(" errorClass: " + (messageStatusSet ? errorClass : "not set") + "\n");
- builder.append(" msgStatus: " + (messageStatusSet ? messageStatus : "not set") + "\n");
- builder.append(" hasUserDataHeader: " + hasUserDataHeader + "\n");
- builder.append(" timeStamp: " + timeStamp + "\n");
- builder.append(" userAckReq: " + userAckReq + "\n");
- builder.append(" deliveryAckReq: " + deliveryAckReq + "\n");
- builder.append(" readAckReq: " + readAckReq + "\n");
- builder.append(" reportReq: " + reportReq + "\n");
- builder.append(" numberOfMessages: " + numberOfMessages + "\n");
- builder.append(" callbackNumber: " + callbackNumber + "\n");
- builder.append(" userData: " + userData + "\n");
+ builder.append("BearerData ");
+ builder.append("{ messageType=" + messageType);
+ builder.append(", messageId=" + (int)messageId);
+ builder.append(", priority=" + (priorityIndicatorSet ? priority : "unset"));
+ builder.append(", privacy=" + (privacyIndicatorSet ? privacy : "unset"));
+ builder.append(", alert=" + (alertIndicatorSet ? alert : "unset"));
+ builder.append(", displayMode=" + (displayModeSet ? displayMode : "unset"));
+ builder.append(", language=" + (languageIndicatorSet ? language : "unset"));
+ builder.append(", errorClass=" + (messageStatusSet ? errorClass : "unset"));
+ builder.append(", msgStatus=" + (messageStatusSet ? messageStatus : "unset"));
+ builder.append(", msgCenterTimeStamp=" +
+ ((msgCenterTimeStamp != null) ? msgCenterTimeStamp : "unset"));
+ builder.append(", validityPeriodAbsolute=" +
+ ((validityPeriodAbsolute != null) ? validityPeriodAbsolute : "unset"));
+ builder.append(", validityPeriodRelative=" +
+ ((validityPeriodRelativeSet) ? validityPeriodRelative : "unset"));
+ builder.append(", deferredDeliveryTimeAbsolute=" +
+ ((deferredDeliveryTimeAbsolute != null) ? deferredDeliveryTimeAbsolute : "unset"));
+ builder.append(", deferredDeliveryTimeRelative=" +
+ ((deferredDeliveryTimeRelativeSet) ? deferredDeliveryTimeRelative : "unset"));
+ builder.append(", userAckReq=" + userAckReq);
+ builder.append(", deliveryAckReq=" + deliveryAckReq);
+ builder.append(", readAckReq=" + readAckReq);
+ builder.append(", reportReq=" + reportReq);
+ builder.append(", numberOfMessages=" + numberOfMessages);
+ builder.append(", callbackNumber=" + callbackNumber);
+ builder.append(", depositIndex=" + depositIndex);
+ builder.append(", hasUserDataHeader=" + hasUserDataHeader);
+ builder.append(", userData=" + userData);
+ builder.append(" }");
return builder.toString();
}
@@ -281,25 +387,60 @@ public final class BearerData{
outStream.skip(3);
}
- private static byte[] encode7bitAscii(String msg)
+ private static int countAsciiSeptets(CharSequence msg, boolean force) {
+ int msgLen = msg.length();
+ if (force) return msgLen;
+ for (int i = 0; i < msgLen; i++) {
+ if (UserData.charToAscii.get(msg.charAt(i), -1) == -1) {
+ return -1;
+ }
+ }
+ return msgLen;
+ }
+
+ /**
+ * Calculate the message text encoding length, fragmentation, and other details.
+ *
+ * @param force ignore (but still count) illegal characters if true
+ * @return septet count, or -1 on failure
+ */
+ public static TextEncodingDetails calcTextEncodingDetails(CharSequence msg,
+ boolean force7BitEncoding) {
+ TextEncodingDetails ted;
+ int septets = countAsciiSeptets(msg, force7BitEncoding);
+ if (septets != -1 && septets <= SmsMessage.MAX_USER_DATA_SEPTETS) {
+ ted = new TextEncodingDetails();
+ ted.msgCount = 1;
+ ted.codeUnitCount = septets;
+ ted.codeUnitsRemaining = SmsMessage.MAX_USER_DATA_SEPTETS - septets;
+ ted.codeUnitSize = SmsMessage.ENCODING_7BIT;
+ } else {
+ ted = com.android.internal.telephony.gsm.SmsMessage.calculateLength(
+ msg, force7BitEncoding);
+ }
+ return ted;
+ }
+
+ private static byte[] encode7bitAscii(String msg, boolean force)
throws CodingException
{
try {
BitwiseOutputStream outStream = new BitwiseOutputStream(msg.length());
- byte[] expandedData = msg.getBytes("US-ASCII");
- for (int i = 0; i < expandedData.length; i++) {
- int charCode = expandedData[i];
- // Test ourselves for ASCII membership, since Java seems not to care.
- if ((charCode < UserData.PRINTABLE_ASCII_MIN_INDEX) ||
- (charCode > UserData.PRINTABLE_ASCII_MAX_INDEX)) {
- throw new CodingException("illegal ASCII code (" + charCode + ")");
+ int msgLen = msg.length();
+ for (int i = 0; i < msgLen; i++) {
+ int charCode = UserData.charToAscii.get(msg.charAt(i), -1);
+ if (charCode == -1) {
+ if (force) {
+ outStream.write(7, UserData.UNENCODABLE_7_BIT_CHAR);
+ } else {
+ throw new CodingException("cannot ASCII encode (" + msg.charAt(i) + ")");
+ }
+ } else {
+ outStream.write(7, charCode);
}
- outStream.write(7, expandedData[i]);
}
return outStream.toByteArray();
- } catch (java.io.UnsupportedEncodingException ex) {
- throw new CodingException("7bit ASCII encode failed: " + ex);
- } catch (BitwiseOutputStream.AccessException ex) {
+ } catch (BitwiseOutputStream.AccessException ex) {
throw new CodingException("7bit ASCII encode failed: " + ex);
}
}
@@ -308,24 +449,31 @@ public final class BearerData{
throws CodingException
{
try {
- return msg.getBytes("utf-16be"); // XXX(do not submit) -- make sure decode matches
+ return msg.getBytes("utf-16be");
} catch (java.io.UnsupportedEncodingException ex) {
throw new CodingException("UTF-16 encode failed: " + ex);
}
}
- private static byte[] encode7bitGsm(String msg)
+ private static int calcUdhSeptetPadding(int userDataHeaderLen) {
+ int udhBits = userDataHeaderLen * 8;
+ int udhSeptets = (udhBits + 6) / 7;
+ int paddingBits = (udhSeptets * 7) - udhBits;
+ return paddingBits;
+ }
+
+ private static byte[] encode7bitGsm(String msg, int paddingBits)
throws CodingException
{
try {
- /**
- * TODO(cleanup): find some way to do this without the copy.
+ /*
+ * TODO(cleanup): It would be nice if GsmAlphabet provided
+ * an option to produce just the data without prepending
+ * the length.
*/
- byte []fullData = GsmAlphabet.stringToGsm7BitPacked(msg);
+ byte []fullData = GsmAlphabet.stringToGsm7BitPacked(msg, 0, -1, paddingBits, true);
byte []data = new byte[fullData.length - 1];
- for (int i = 0; i < data.length; i++) {
- data[i] = fullData[i + 1];
- }
+ System.arraycopy(fullData, 1, data, 0, fullData.length - 1);
return data;
} catch (com.android.internal.telephony.EncodeException ex) {
throw new CodingException("7bit GSM encode failed: " + ex);
@@ -335,51 +483,85 @@ public final class BearerData{
private static void encodeUserDataPayload(UserData uData)
throws CodingException
{
+ // TODO(cleanup): UDH can only occur in EMS mode, meaning
+ // encapsulation of GSM encoding, and so the logic here should
+ // be refactored to more cleanly reflect this constraint.
+
+ byte[] headerData = null;
+ if (uData.userDataHeader != null) headerData = SmsHeader.toByteArray(uData.userDataHeader);
+ int headerDataLen = (headerData == null) ? 0 : headerData.length + 1; // + length octet
+
+ byte[] payloadData;
+ int codeUnitCount;
if (uData.msgEncodingSet) {
if (uData.msgEncoding == UserData.ENCODING_OCTET) {
if (uData.payload == null) {
Log.e(LOG_TAG, "user data with octet encoding but null payload");
- // TODO(code_review): reasonable for fail case? or maybe bail on encoding?
- uData.payload = new byte[0];
+ payloadData = new byte[0];
+ codeUnitCount = 0;
+ } else {
+ payloadData = uData.payload;
+ codeUnitCount = uData.payload.length;
}
} else {
if (uData.payloadStr == null) {
Log.e(LOG_TAG, "non-octet user data with null payloadStr");
- // TODO(code_review): reasonable for fail case? or maybe bail on encoding?
uData.payloadStr = "";
}
if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) {
- uData.payload = encode7bitGsm(uData.payloadStr);
+ int paddingBits = calcUdhSeptetPadding(headerDataLen);
+ payloadData = encode7bitGsm(uData.payloadStr, paddingBits);
+ codeUnitCount = ((payloadData.length + headerDataLen) * 8) / 7;
} else if (uData.msgEncoding == UserData.ENCODING_7BIT_ASCII) {
- uData.payload = encode7bitAscii(uData.payloadStr);
+ payloadData = encode7bitAscii(uData.payloadStr, true);
+ codeUnitCount = uData.payloadStr.length();
} else if (uData.msgEncoding == UserData.ENCODING_UNICODE_16) {
- uData.payload = encodeUtf16(uData.payloadStr);
+ payloadData = encodeUtf16(uData.payloadStr);
+ codeUnitCount = uData.payloadStr.length();
} else {
throw new CodingException("unsupported user data encoding (" +
uData.msgEncoding + ")");
}
- uData.numFields = uData.payloadStr.length();
}
} else {
if (uData.payloadStr == null) {
Log.e(LOG_TAG, "user data with null payloadStr");
- // TODO(code_review): reasonable for fail case? or maybe bail on encoding?
uData.payloadStr = "";
}
try {
- uData.payload = encode7bitAscii(uData.payloadStr);
- uData.msgEncoding = UserData.ENCODING_7BIT_ASCII;
+ if (headerData == null) {
+ payloadData = encode7bitAscii(uData.payloadStr, false);
+ codeUnitCount = uData.payloadStr.length();
+ uData.msgEncoding = UserData.ENCODING_7BIT_ASCII;
+ } else {
+ // If there is a header, we are in EMS mode, in
+ // which case we use GSM encodings.
+ int paddingBits = calcUdhSeptetPadding(headerDataLen);
+ payloadData = encode7bitGsm(uData.payloadStr, paddingBits);
+ codeUnitCount = ((payloadData.length + headerDataLen) * 8) / 7;
+ uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
+ }
} catch (CodingException ex) {
- uData.payload = encodeUtf16(uData.payloadStr);
+ payloadData = encodeUtf16(uData.payloadStr);
+ codeUnitCount = uData.payloadStr.length();
uData.msgEncoding = UserData.ENCODING_UNICODE_16;
}
uData.msgEncodingSet = true;
- uData.numFields = uData.payloadStr.length();
}
- if (uData.payload.length > SmsMessage.MAX_USER_DATA_BYTES) {
- throw new CodingException("encoded user data too large (" + uData.payload.length +
+
+ int totalLength = payloadData.length + headerDataLen;
+ if (totalLength > SmsMessage.MAX_USER_DATA_BYTES) {
+ throw new CodingException("encoded user data too large (" + totalLength +
" > " + SmsMessage.MAX_USER_DATA_BYTES + " bytes)");
}
+
+ uData.numFields = codeUnitCount;
+ uData.payload = new byte[totalLength];
+ if (headerData != null) {
+ uData.payload[0] = (byte)headerData.length;
+ System.arraycopy(headerData, 0, uData.payload, 1, headerData.length);
+ }
+ System.arraycopy(payloadData, 0, uData.payload, headerDataLen, payloadData.length);
}
private static void encodeUserData(BearerData bData, BitwiseOutputStream outStream)
@@ -394,11 +576,6 @@ public final class BearerData{
*
*/
int dataBits = (bData.userData.payload.length * 8) - bData.userData.paddingBits;
- byte[] headerData = null;
- if (bData.hasUserDataHeader) {
- headerData = bData.userData.userDataHeader.toByteArray();
- dataBits += headerData.length * 8;
- }
int paramBits = dataBits + 13;
if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
(bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) {
@@ -413,7 +590,6 @@ public final class BearerData{
outStream.write(8, bData.userData.msgType);
}
outStream.write(8, bData.userData.numFields);
- if (headerData != null) outStream.writeByteArray(headerData.length * 8, headerData);
outStream.writeByteArray(dataBits, bData.userData.payload);
if (paddingBits > 0) outStream.write(paddingBits, 0);
}
@@ -502,11 +678,11 @@ public final class BearerData{
outStream.write(8, bData.numberOfMessages);
}
- private static void encodeMsgCenterTimeStamp(BearerData bData, BitwiseOutputStream outStream)
+ private static void encodeValidityPeriodRel(BearerData bData, BitwiseOutputStream outStream)
throws BitwiseOutputStream.AccessException
{
- outStream.write(8, 6);
- outStream.writeByteArray(6 * 8, bData.timeStamp);
+ outStream.write(8, 1);
+ outStream.write(8, bData.validityPeriodRelative);
}
private static void encodePrivacyIndicator(BearerData bData, BitwiseOutputStream outStream)
@@ -557,6 +733,8 @@ public final class BearerData{
* @return data byta array of raw encoded SMS bearer data.
*/
public static byte[] encode(BearerData bData) {
+ bData.hasUserDataHeader = ((bData.userData != null) &&
+ (bData.userData.userDataHeader != null));
try {
BitwiseOutputStream outStream = new BitwiseOutputStream(200);
outStream.write(8, SUBPARAM_MESSAGE_IDENTIFIER);
@@ -577,9 +755,9 @@ public final class BearerData{
outStream.write(8, SUBPARAM_NUMBER_OF_MESSAGES);
encodeMsgCount(bData, outStream);
}
- if (bData.timeStamp != null) {
- outStream.write(8, SUBPARAM_MESSAGE_CENTER_TIME_STAMP);
- encodeMsgCenterTimeStamp(bData, outStream);
+ if (bData.validityPeriodRelativeSet) {
+ outStream.write(8, SUBPARAM_VALIDITY_PERIOD_RELATIVE);
+ encodeValidityPeriodRel(bData, outStream);
}
if (bData.privacyIndicatorSet) {
outStream.write(8, SUBPARAM_PRIVACY_INDICATOR);
@@ -630,7 +808,7 @@ public final class BearerData{
private static void decodeUserData(BearerData bData, BitwiseInputStream inStream)
throws BitwiseInputStream.AccessException
{
- byte paramBytes = inStream.read(8);
+ int paramBytes = inStream.read(8);
bData.userData = new UserData();
bData.userData.msgEncoding = inStream.read(5);
bData.userData.msgEncodingSet = true;
@@ -698,7 +876,7 @@ public final class BearerData{
inStream.skip(offset);
byte[] expandedData = new byte[numFields];
for (int i = 0; i < numFields; i++) {
- expandedData[i] = inStream.read(7);
+ expandedData[i] = (byte)inStream.read(7);
}
return new String(expandedData, 0, numFields, "US-ASCII");
} catch (java.io.UnsupportedEncodingException ex) {
@@ -711,7 +889,12 @@ public final class BearerData{
private static String decode7bitGsm(byte[] data, int offset, int numFields)
throws CodingException
{
- String result = GsmAlphabet.gsm7BitPackedToString(data, offset, numFields);
+ int paddingBits = calcUdhSeptetPadding(offset);
+ numFields -= (((offset * 8) + paddingBits) / 7);
+ // TODO: It seems wrong that only Gsm7 bit encodings would
+ // take into account the header in numFields calculations.
+ // This should be verified.
+ String result = GsmAlphabet.gsm7BitPackedToString(data, offset, numFields, paddingBits);
if (result == null) {
throw new CodingException("7bit GSM decoding failed");
}
@@ -723,11 +906,11 @@ public final class BearerData{
{
int offset = 0;
if (hasUserDataHeader) {
- int udhLen = userData.payload[0];
- offset += udhLen;
+ int udhLen = userData.payload[0] & 0x00FF;
+ offset += udhLen + 1;
byte[] headerData = new byte[udhLen];
System.arraycopy(userData.payload, 1, headerData, 0, udhLen);
- userData.userDataHeader = SmsHeader.parse(headerData);
+ userData.userDataHeader = SmsHeader.fromByteArray(headerData);
}
switch (userData.msgEncoding) {
case UserData.ENCODING_OCTET:
@@ -750,10 +933,126 @@ public final class BearerData{
}
}
+ /**
+ * IS-91 Voice Mail message decoding
+ * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1)
+ * (For character encodings, see TIA/EIA/IS-91, Annex B)
+ *
+ * Protocol Summary: The user data payload may contain 3-14
+ * characters. The first two characters are parsed as a number
+ * and indicate the number of voicemails. The third character is
+ * either a SPACE or '!' to indicate normal or urgent priority,
+ * respectively. Any following characters are treated as normal
+ * text user data payload.
+ *
+ * Note that the characters encoding is 6-bit packed.
+ */
+ private static void decodeIs91VoicemailStatus(BearerData bData)
+ throws BitwiseInputStream.AccessException, CodingException
+ {
+ BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
+ int dataLen = inStream.available() / 6; // 6-bit packed character encoding.
+ int numFields = bData.userData.numFields;
+ if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) {
+ throw new CodingException("IS-91 voicemail status decoding failed");
+ }
+ try {
+ StringBuffer strbuf = new StringBuffer(dataLen);
+ while (inStream.available() >= 6) {
+ strbuf.append(UserData.IA5_MAP[inStream.read(6)]);
+ }
+ String data = strbuf.toString();
+ bData.numberOfMessages = Integer.parseInt(data.substring(0, 2));
+ char prioCode = data.charAt(2);
+ if (prioCode == ' ') {
+ bData.priority = PRIORITY_NORMAL;
+ } else if (prioCode == '!') {
+ bData.priority = PRIORITY_URGENT;
+ } else {
+ throw new CodingException("IS-91 voicemail status decoding failed: " +
+ "illegal priority setting (" + prioCode + ")");
+ }
+ bData.priorityIndicatorSet = true;
+ bData.userData.payloadStr = data.substring(3, numFields - 3);
+ } catch (java.lang.NumberFormatException ex) {
+ throw new CodingException("IS-91 voicemail status decoding failed: " + ex);
+ } catch (java.lang.IndexOutOfBoundsException ex) {
+ throw new CodingException("IS-91 voicemail status decoding failed: " + ex);
+ }
+ }
+
+ /**
+ * IS-91 Short Message decoding
+ * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1)
+ * (For character encodings, see TIA/EIA/IS-91, Annex B)
+ *
+ * Protocol Summary: The user data payload may contain 1-14
+ * characters, which are treated as normal text user data payload.
+ * Note that the characters encoding is 6-bit packed.
+ */
+ private static void decodeIs91ShortMessage(BearerData bData)
+ throws BitwiseInputStream.AccessException, CodingException
+ {
+ BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
+ int dataLen = inStream.available() / 6; // 6-bit packed character encoding.
+ int numFields = bData.userData.numFields;
+ if ((dataLen > 14) || (dataLen < numFields)) {
+ throw new CodingException("IS-91 voicemail status decoding failed");
+ }
+ StringBuffer strbuf = new StringBuffer(dataLen);
+ for (int i = 0; i < numFields; i++) {
+ strbuf.append(UserData.IA5_MAP[inStream.read(6)]);
+ }
+ bData.userData.payloadStr = strbuf.toString();
+ }
+
+ /**
+ * IS-91 CLI message (callback number) decoding
+ * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1)
+ *
+ * Protocol Summary: The data payload may contain 1-32 digits,
+ * encoded using standard 4-bit DTMF, which are treated as a
+ * callback number.
+ */
+ private static void decodeIs91Cli(BearerData bData) throws CodingException {
+ BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
+ int dataLen = inStream.available() / 4; // 4-bit packed DTMF digit encoding.
+ int numFields = bData.userData.numFields;
+ if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) {
+ throw new CodingException("IS-91 voicemail status decoding failed");
+ }
+ CdmaSmsAddress addr = new CdmaSmsAddress();
+ addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF;
+ addr.origBytes = bData.userData.payload;
+ addr.numberOfDigits = (byte)numFields;
+ decodeSmsAddress(addr);
+ bData.callbackNumber = addr;
+ }
+
+ private static void decodeIs91(BearerData bData)
+ throws BitwiseInputStream.AccessException, CodingException
+ {
+ switch (bData.userData.msgType) {
+ case UserData.IS91_MSG_TYPE_VOICEMAIL_STATUS:
+ decodeIs91VoicemailStatus(bData);
+ break;
+ case UserData.IS91_MSG_TYPE_CLI:
+ decodeIs91Cli(bData);
+ break;
+ case UserData.IS91_MSG_TYPE_SHORT_MESSAGE_FULL:
+ case UserData.IS91_MSG_TYPE_SHORT_MESSAGE:
+ decodeIs91ShortMessage(bData);
+ break;
+ default:
+ throw new CodingException("unsupported IS-91 message type (" +
+ bData.userData.msgType + ")");
+ }
+ }
+
private static void decodeReplyOption(BearerData bData, BitwiseInputStream inStream)
throws BitwiseInputStream.AccessException, CodingException
{
- byte paramBytes = inStream.read(8);
+ int paramBytes = inStream.read(8);
if (paramBytes != 1) {
throw new CodingException("REPLY_OPTION subparam size incorrect");
}
@@ -773,6 +1072,15 @@ public final class BearerData{
bData.numberOfMessages = inStream.read(8);
}
+ private static void decodeDepositIndex(BearerData bData, BitwiseInputStream inStream)
+ throws BitwiseInputStream.AccessException, CodingException
+ {
+ if (inStream.read(8) != 2) {
+ throw new CodingException("MESSAGE_DEPOSIT_INDEX subparam size incorrect");
+ }
+ bData.depositIndex = (inStream.read(8) << 8) | inStream.read(8);
+ }
+
private static String decodeDtmfSmsAddress(byte[] rawData, int numFields)
throws CodingException
{
@@ -807,7 +1115,7 @@ public final class BearerData{
private static void decodeCallbackNumber(BearerData bData, BitwiseInputStream inStream)
throws BitwiseInputStream.AccessException, CodingException
{
- byte paramBytes = inStream.read(8);
+ int paramBytes = inStream.read(8);
CdmaSmsAddress addr = new CdmaSmsAddress();
addr.digitMode = inStream.read(1);
byte fieldBits = 4;
@@ -845,14 +1153,51 @@ public final class BearerData{
bData.messageStatusSet = true;
}
- private static void decodeMsgCenterTimeStamp(BearerData bData,
- BitwiseInputStream inStream)
+ private static void decodeMsgCenterTimeStamp(BearerData bData, BitwiseInputStream inStream)
throws BitwiseInputStream.AccessException, CodingException
{
if (inStream.read(8) != 6) {
throw new CodingException("MESSAGE_CENTER_TIME_STAMP subparam size incorrect");
}
- bData.timeStamp = inStream.readByteArray(6 * 8);
+ bData.msgCenterTimeStamp = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
+ }
+
+ private static void decodeValidityAbs(BearerData bData, BitwiseInputStream inStream)
+ throws BitwiseInputStream.AccessException, CodingException
+ {
+ if (inStream.read(8) != 6) {
+ throw new CodingException("VALIDITY_PERIOD_ABSOLUTE subparam size incorrect");
+ }
+ bData.validityPeriodAbsolute = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
+ }
+
+ private static void decodeDeferredDeliveryAbs(BearerData bData, BitwiseInputStream inStream)
+ throws BitwiseInputStream.AccessException, CodingException
+ {
+ if (inStream.read(8) != 6) {
+ throw new CodingException("DEFERRED_DELIVERY_TIME_ABSOLUTE subparam size incorrect");
+ }
+ bData.deferredDeliveryTimeAbsolute = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
+ }
+
+ private static void decodeValidityRel(BearerData bData, BitwiseInputStream inStream)
+ throws BitwiseInputStream.AccessException, CodingException
+ {
+ if (inStream.read(8) != 1) {
+ throw new CodingException("VALIDITY_PERIOD_RELATIVE subparam size incorrect");
+ }
+ bData.deferredDeliveryTimeRelative = inStream.read(8);
+ bData.deferredDeliveryTimeRelativeSet = true;
+ }
+
+ private static void decodeDeferredDeliveryRel(BearerData bData, BitwiseInputStream inStream)
+ throws BitwiseInputStream.AccessException, CodingException
+ {
+ if (inStream.read(8) != 1) {
+ throw new CodingException("DEFERRED_DELIVERY_TIME_RELATIVE subparam size incorrect");
+ }
+ bData.validityPeriodRelative = inStream.read(8);
+ bData.validityPeriodRelativeSet = true;
}
private static void decodePrivacyIndicator(BearerData bData, BitwiseInputStream inStream)
@@ -909,6 +1254,16 @@ public final class BearerData{
bData.alertIndicatorSet = true;
}
+ private static void decodeUserResponseCode(BearerData bData, BitwiseInputStream inStream)
+ throws BitwiseInputStream.AccessException, CodingException
+ {
+ if (inStream.read(8) != 1) {
+ throw new CodingException("USER_REPONSE_CODE subparam size incorrect");
+ }
+ bData.userResponseCode = inStream.read(8);
+ bData.userResponseCodeSet = true;
+ }
+
/**
* Create BearerData object from serialized representation.
* (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
@@ -937,6 +1292,9 @@ public final class BearerData{
case SUBPARAM_USER_DATA:
decodeUserData(bData, inStream);
break;
+ case SUBPARAM_USER_REPONSE_CODE:
+ decodeUserResponseCode(bData, inStream);
+ break;
case SUBPARAM_REPLY_OPTION:
decodeReplyOption(bData, inStream);
break;
@@ -952,6 +1310,18 @@ public final class BearerData{
case SUBPARAM_MESSAGE_CENTER_TIME_STAMP:
decodeMsgCenterTimeStamp(bData, inStream);
break;
+ case SUBPARAM_VALIDITY_PERIOD_ABSOLUTE:
+ decodeValidityAbs(bData, inStream);
+ break;
+ case SUBPARAM_VALIDITY_PERIOD_RELATIVE:
+ decodeValidityRel(bData, inStream);
+ break;
+ case SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE:
+ decodeDeferredDeliveryAbs(bData, inStream);
+ break;
+ case SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE:
+ decodeDeferredDeliveryRel(bData, inStream);
+ break;
case SUBPARAM_PRIVACY_INDICATOR:
decodePrivacyIndicator(bData, inStream);
break;
@@ -967,6 +1337,9 @@ public final class BearerData{
case SUBPARAM_ALERT_ON_MESSAGE_DELIVERY:
decodeMsgDeliveryAlert(bData, inStream);
break;
+ case SUBPARAM_MESSAGE_DEPOSIT_INDEX:
+ decodeDepositIndex(bData, inStream);
+ break;
default:
throw new CodingException("unsupported bearer data subparameter ("
+ subparamId + ")");
@@ -976,7 +1349,18 @@ public final class BearerData{
throw new CodingException("missing MESSAGE_IDENTIFIER subparam");
}
if (bData.userData != null) {
- decodeUserDataPayload(bData.userData, bData.hasUserDataHeader);
+ if (bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) {
+ if ((foundSubparamMask ^
+ (1 << SUBPARAM_MESSAGE_IDENTIFIER) ^
+ (1 << SUBPARAM_USER_DATA))
+ != 0) {
+ Log.e(LOG_TAG, "IS-91 must occur without extra subparams (" +
+ foundSubparamMask + ")");
+ }
+ decodeIs91(bData);
+ } else {
+ decodeUserDataPayload(bData.userData, bData.hasUserDataHeader);
+ }
}
return bData;
} catch (BitwiseInputStream.AccessException ex) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
index 440debb..4d79966 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
@@ -20,23 +20,31 @@ import com.android.internal.telephony.SmsAddress;
import com.android.internal.util.HexDump;
public class CdmaSmsAddress extends SmsAddress {
+
/**
- * digit mode indicators
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
+ * Digit Mode Indicator is a 1-bit value that indicates whether
+ * the address digits are 4-bit DTMF codes or 8-bit codes. (See
+ * 3GPP2 C.S0015-B, v2, 3.4.3.3)
*/
static public final int DIGIT_MODE_4BIT_DTMF = 0x00;
static public final int DIGIT_MODE_8BIT_CHAR = 0x01;
+ public int digitMode;
+
/**
- * number mode indicators
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
+ * Number Mode Indicator is 1-bit value that indicates whether the
+ * address type is a data network address or not. (See 3GPP2
+ * C.S0015-B, v2, 3.4.3.3)
*/
static public final int NUMBER_MODE_NOT_DATA_NETWORK = 0x00;
static public final int NUMBER_MODE_DATA_NETWORK = 0x01;
+ public int numberMode;
+
/**
- * number types for data networks
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
+ * Number Types for data networks.
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
+ * NOTE: value is stored in the parent class ton field.
*/
static public final int TON_UNKNOWN = 0x00;
static public final int TON_INTERNATIONAL_OR_IP = 0x01;
@@ -48,14 +56,21 @@ public class CdmaSmsAddress extends SmsAddress {
static public final int TON_RESERVED = 0x07;
/**
- * maximum lengths for fields as defined in ril_cdma_sms.h
+ * Maximum lengths for fields as defined in ril_cdma_sms.h.
*/
static public final int SMS_ADDRESS_MAX = 36;
static public final int SMS_SUBADDRESS_MAX = 36;
/**
- * Supported numbering plan identification
- * (See C.S005-D, v1.0, table 2.7.1.3.2.4-3)
+ * This field shall be set to the number of address digits
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
+ */
+ public int numberOfDigits;
+
+ /**
+ * Numbering Plan identification is a 0 or 4-bit value that
+ * indicates which numbering plan identification is set. (See
+ * 3GPP2, C.S0015-B, v2, 3.4.3.3 and C.S005-D, table2.7.1.3.2.4-3)
*/
static public final int NUMBERING_PLAN_UNKNOWN = 0x0;
static public final int NUMBERING_PLAN_ISDN_TELEPHONY = 0x1;
@@ -63,50 +78,29 @@ public class CdmaSmsAddress extends SmsAddress {
//static protected final int NUMBERING_PLAN_TELEX = 0x4;
//static protected final int NUMBERING_PLAN_PRIVATE = 0x9;
- /**
- * 1-bit value that indicates whether the address digits are 4-bit DTMF codes
- * or 8-bit codes.
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
- */
- public byte digitMode;
-
- /**
- * 1-bit value that indicates whether the address type is a data network address or not.
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
- */
- public byte numberMode;
-
- // use parent class member ton instead public byte numberType;
+ public int numberPlan;
/**
- * 0 or 4-bit value that indicates which numbering plan identification is set.
- * (See 3GPP2, C.S0015-B, v2, 3.4.3.3 and C.S005-D, table2.7.1.3.2.4-3)
+ * NOTE: the parsed string address and the raw byte array values
+ * are stored in the parent class address and origBytes fields,
+ * respectively.
*/
- public byte numberPlan;
-
- /**
- * This field shall be set to the number of address digits
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
- */
- public byte numberOfDigits;
-
- // use parent class member orig_bytes instead of public byte[] digits;
- // Constructor
public CdmaSmsAddress(){
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.append("CdmaSmsAddress:\n");
- builder.append(" digitMode: " + digitMode + "\n");
- builder.append(" numberMode: " + numberMode + "\n");
- builder.append(" numberPlan: " + numberPlan + "\n");
- builder.append(" numberOfDigits: " + numberOfDigits + "\n");
- builder.append(" ton: " + ton + "\n");
- builder.append(" address: " + address + "\n");
- builder.append(" origBytes: " + HexDump.toHexString(origBytes) + "\n");
+ builder.append("CdmaSmsAddress ");
+ builder.append("{ digitMode=" + digitMode);
+ builder.append(", numberMode=" + numberMode);
+ builder.append(", numberPlan=" + numberPlan);
+ builder.append(", numberOfDigits=" + numberOfDigits);
+ builder.append(", ton=" + ton);
+ builder.append(", address=" + address);
+ builder.append(", origBytes=" + HexDump.toHexString(origBytes));
+ builder.append(" }");
return builder.toString();
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
index 02e94ad..34cbbfa 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony.cdma.sms;
+import android.util.SparseIntArray;
+
import com.android.internal.telephony.SmsHeader;
import com.android.internal.util.HexDump;
@@ -38,8 +40,26 @@ public class UserData {
public static final int ENCODING_GSM_DCS = 0x0A;
/**
+ * IS-91 message types.
+ * (See TIA/EIS/IS-91-A-ENGL 1999, table 3.7.1.1-3)
+ */
+ public static final int IS91_MSG_TYPE_VOICEMAIL_STATUS = 0x82;
+ public static final int IS91_MSG_TYPE_SHORT_MESSAGE_FULL = 0x83;
+ public static final int IS91_MSG_TYPE_CLI = 0x84;
+ public static final int IS91_MSG_TYPE_SHORT_MESSAGE = 0x85;
+
+ /**
* IA5 data encoding character mappings.
* (See CCITT Rec. T.50 Tables 1 and 3)
+ *
+ * Note this mapping is the the same as for printable ASCII
+ * characters, with a 0x20 offset, meaning that the ASCII SPACE
+ * character occurs with code 0x20.
+ *
+ * Note this mapping is also equivalent to that used by the IS-91
+ * protocol, except for the latter using only 6 bits, and hence
+ * mapping only entries up to the '_' character.
+ *
*/
public static final char[] IA5_MAP = {
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
@@ -50,10 +70,27 @@ public class UserData {
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~'};
/**
+ * Character to use when forced to encode otherwise unencodable
+ * characters, meaning those not in the respective ASCII or GSM
+ * 7-bit encoding tables. Current choice is SPACE, which is 0x20
+ * in both the GSM-7bit and ASCII-7bit encodings.
+ */
+ static final byte UNENCODABLE_7_BIT_CHAR = 0x20;
+
+ /**
* Only elements between these indices in the ASCII table are printable.
*/
public static final int PRINTABLE_ASCII_MIN_INDEX = 0x20;
- public static final int PRINTABLE_ASCII_MAX_INDEX = 0x7F;
+ public static final int ASCII_LF_INDEX = 0x0A;
+ public static final int ASCII_CR_INDEX = 0x0D;
+ public static final SparseIntArray charToAscii = new SparseIntArray();
+ static {
+ for (int i = 0; i < IA5_MAP.length; i++) {
+ charToAscii.put(IA5_MAP[i], PRINTABLE_ASCII_MIN_INDEX + i);
+ }
+ charToAscii.put('\r', ASCII_LF_INDEX);
+ charToAscii.put('\n', ASCII_CR_INDEX);
+ }
/**
* Mapping for IA5 values less than 32 are flow control signals
@@ -73,7 +110,6 @@ public class UserData {
public int msgEncoding;
public boolean msgEncodingSet = false;
- // XXX needed when encoding is IS91 or DCS (not supported yet):
public int msgType;
/**
@@ -93,14 +129,15 @@ public class UserData {
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.append("UserData:\n");
- builder.append(" msgEncoding: " + (msgEncodingSet ? msgEncoding : "not set") + "\n");
- builder.append(" msgType: " + msgType + "\n");
- builder.append(" paddingBits: " + paddingBits + "\n");
- builder.append(" numFields: " + (int)numFields + "\n");
- builder.append(" userDataHeader: " + userDataHeader + "\n");
- builder.append(" payload: '" + HexDump.toHexString(payload) + "'");
- builder.append(", payloadStr: '" + payloadStr + "'");
+ builder.append("UserData ");
+ builder.append("{ msgEncoding=" + (msgEncodingSet ? msgEncoding : "unset"));
+ builder.append(", msgType=" + msgType);
+ builder.append(", paddingBits=" + paddingBits);
+ builder.append(", numFields=" + (int)numFields);
+ builder.append(", userDataHeader=" + userDataHeader);
+ builder.append(", payload='" + HexDump.toHexString(payload) + "'");
+ builder.append(", payloadStr='" + payloadStr + "'");
+ builder.append(" }");
return builder.toString();
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/package.html b/telephony/java/com/android/internal/telephony/cdma/sms/package.html
index 48e1034..b2bc736 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/package.html
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/package.html
@@ -1,6 +1,6 @@
<HTML>
<BODY>
-Provides CDMA-specific features for text/data/PDU SMS messages
+Provides CDMA-specific features for text/data/PDU SMS messages
@hide
</BODY>
</HTML>
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index a2d3c5e..d1e4b4f 100755
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -34,6 +34,7 @@ import android.provider.Telephony;
import android.telephony.CellLocation;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.text.TextUtils;
import android.util.Log;
@@ -67,6 +68,7 @@ import com.android.internal.telephony.PhoneNotifier;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.PhoneSubInfo;
import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.gsm.stk.StkService;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.IccVmNotSupportedException;
@@ -203,9 +205,9 @@ public class GSMPhone extends PhoneBase {
}
}
- //Change the system setting
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.CURRENT_ACTIVE_PHONE, RILConstants.GSM_PHONE);
+ //Change the system property
+ SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
+ new Integer(RILConstants.GSM_PHONE).toString());
}
public void dispose() {
@@ -285,9 +287,8 @@ public class GSMPhone extends PhoneBase {
return mDataConnection.getActiveApnString();
}
- public int
- getSignalStrengthASU() {
- return mSST.rssi == 99 ? -1 : mSST.rssi;
+ public SignalStrength getSignalStrength() {
+ return mSST.mSignalStrength;
}
public boolean
@@ -447,11 +448,6 @@ public class GSMPhone extends PhoneBase {
}
public void
- notifyMessageWaitingIndicator() {
- mNotifier.notifyMessageWaitingChanged(this);
- }
-
- public void
notifyCallForwardingIndicator() {
mNotifier.notifyCallForwardingChanged(this);
}
@@ -825,6 +821,11 @@ public class GSMPhone extends PhoneBase {
}
public void
+ sendBurstDtmf(String dtmfString) {
+ Log.e(LOG_TAG, "[GSMPhone] sendBurstDtmf() is a CDMA method");
+ }
+
+ public void
setRadioPower(boolean power) {
mSST.setRadioPower(power);
}
@@ -832,21 +833,21 @@ public class GSMPhone extends PhoneBase {
private void storeVoiceMailNumber(String number) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor editor = sp.edit();
- editor.putString(VM_NUMBER, number);
+ editor.putString(VM_NUMBER, number);
editor.commit();
setVmSimImsi(getSubscriberId());
}
public String getVoiceMailNumber() {
// Read from the SIM. If its null, try reading from the shared preference area.
- String number = mSIMRecords.getVoiceMailNumber();
+ String number = mSIMRecords.getVoiceMailNumber();
if (TextUtils.isEmpty(number)) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
number = sp.getString(VM_NUMBER, null);
- }
+ }
return number;
}
-
+
private String getVmSimImsi() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
return sp.getString(VM_SIM_IMSI, null);
@@ -858,7 +859,7 @@ public class GSMPhone extends PhoneBase {
editor.putString(VM_SIM_IMSI, imsi);
editor.commit();
}
-
+
public String getVoiceMailAlphaTag() {
String ret;
@@ -922,13 +923,13 @@ public class GSMPhone extends PhoneBase {
public void setVoiceMailNumber(String alphaTag,
String voiceMailNumber,
Message onComplete) {
-
- Message resp;
+
+ Message resp;
mVmNumber = voiceMailNumber;
resp = h.obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
mSIMRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
}
-
+
private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) {
switch (commandInterfaceCFReason) {
case CF_REASON_UNCONDITIONAL:
@@ -1307,11 +1308,11 @@ public class GSMPhone extends PhoneBase {
case EVENT_SIM_RECORDS_LOADED:
updateCurrentCarrierInProvider();
-
+
// Check if this is a different SIM than the previous one. If so unset the
// voice mail number.
String imsi = getVmSimImsi();
- if (imsi != null && !getSubscriberId().equals(imsi)) {
+ if (imsi != null && !getSubscriberId().equals(imsi)) {
storeVoiceMailNumber(null);
setVmSimImsi(null);
}
@@ -1393,7 +1394,7 @@ public class GSMPhone extends PhoneBase {
onComplete.sendToTarget();
}
break;
-
+
case EVENT_SET_VM_NUMBER_DONE:
ar = (AsyncResult)msg.obj;
if (IccVmNotSupportedException.class.isInstance(ar.exception)) {
@@ -1407,7 +1408,7 @@ public class GSMPhone extends PhoneBase {
}
break;
-
+
case EVENT_GET_CALL_FORWARD_DONE:
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
@@ -1450,7 +1451,7 @@ public class GSMPhone extends PhoneBase {
/**
* Sets the "current" field in the telephony provider according to the SIM's operator
- *
+ *
* @return true for success; false otherwise.
*/
boolean updateCurrentCarrierInProvider() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
index 2b2f077..d93ca1d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
@@ -83,7 +83,7 @@ public class GsmConnection extends Connection {
static final int EVENT_PAUSE_DONE = 2;
static final int EVENT_NEXT_POST_DIAL = 3;
static final int EVENT_WAKE_LOCK_TIMEOUT = 4;
-
+
//***** Constants
static final int PAUSE_DELAY_FIRST_MILLIS = 100;
static final int PAUSE_DELAY_MILLIS = 3 * 1000;
@@ -117,7 +117,7 @@ public class GsmConnection extends Connection {
GsmConnection (Context context, DriverCall dc, GsmCallTracker ct, int index) {
createWakeLock(context);
acquireWakeLock();
-
+
owner = ct;
h = new MyHandler(owner.getLooper());
@@ -138,7 +138,7 @@ public class GsmConnection extends Connection {
GsmConnection (Context context, String dialString, GsmCallTracker ct, GsmCall parent) {
createWakeLock(context);
acquireWakeLock();
-
+
owner = ct;
h = new MyHandler(owner.getLooper());
@@ -375,7 +375,7 @@ public class GsmConnection extends Connection {
return DisconnectCause.ICC_ERROR;
} else if (causeCode == CallFailCause.ERROR_UNSPECIFIED) {
if (phone.mSST.rs.isCsRestricted()) {
- return DisconnectCause.CS_RESTRICTED;
+ return DisconnectCause.CS_RESTRICTED;
} else if (phone.mSST.rs.isCsEmergencyRestricted()) {
return DisconnectCause.CS_RESTRICTED_EMERGENCY;
} else if (phone.mSST.rs.isCsNormalRestricted()) {
@@ -575,7 +575,7 @@ public class GsmConnection extends Connection {
return postDialString.substring(nextPostDialChar);
}
-
+
@Override
protected void finalize()
{
@@ -609,7 +609,7 @@ public class GsmConnection extends Connection {
c = 0;
} else {
boolean isValid;
-
+
setPostDialState(PostDialState.STARTED);
c = postDialString.charAt(nextPostDialChar++);
@@ -680,31 +680,31 @@ public class GsmConnection extends Connection {
}
/**
- * Set post dial state and acquire wake lock while switching to "started"
- * state, the wake lock will be released if state switches out of "started"
- * state or after WAKE_LOCK_TIMEOUT_MILLIS.
+ * Set post dial state and acquire wake lock while switching to "started"
+ * state, the wake lock will be released if state switches out of "started"
+ * state or after WAKE_LOCK_TIMEOUT_MILLIS.
* @param s new PostDialState
*/
private void setPostDialState(PostDialState s) {
- if (postDialState != PostDialState.STARTED
+ if (postDialState != PostDialState.STARTED
&& s == PostDialState.STARTED) {
acquireWakeLock();
Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS);
- } else if (postDialState == PostDialState.STARTED
+ } else if (postDialState == PostDialState.STARTED
&& s != PostDialState.STARTED) {
h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
releaseWakeLock();
}
postDialState = s;
}
-
+
private void
createWakeLock(Context context) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
}
-
+
private void
acquireWakeLock() {
log("acquireWakeLock");
@@ -720,7 +720,7 @@ public class GsmConnection extends Connection {
}
}
}
-
+
private void log(String msg) {
Log.d(LOG_TAG, "[GSMConn] " + msg);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 9e6ebc4..c33d4b6 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -28,10 +28,9 @@ import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.NetworkInfo;
-import android.net.wifi.WifiManager;
import android.net.Uri;
+import android.net.wifi.WifiManager;
import android.os.AsyncResult;
-import android.os.Handler;
import android.os.INetStatService;
import android.os.Message;
import android.os.RemoteException;
@@ -42,7 +41,6 @@ import android.preference.PreferenceManager;
import android.provider.Checkin;
import android.provider.Settings;
import android.provider.Telephony;
-import android.provider.Settings.SettingNotFoundException;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
@@ -50,12 +48,12 @@ import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
+import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.DataConnection.FailCause;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.TelephonyEventLog;
+import com.android.internal.telephony.DataConnection.FailCause;
import java.io.IOException;
import java.util.ArrayList;
@@ -67,6 +65,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
private static final String LOG_TAG = "GSM";
private static final boolean DBG = true;
+ private GSMPhone mGsmPhone;
/**
* Handles changes to the APN db.
*/
@@ -87,6 +86,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// Indicates baseband will not auto-attach
private boolean noAutoAttach = false;
long nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ private boolean mReregisterOnReconnectFailure = false;
private ContentResolver mResolver;
private boolean mPingTestActive = false;
@@ -150,7 +150,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
private static final int POLL_PDP_MILLIS = 5 * 1000;
- //WINK:TODO: Teleca, is this really gsm specific, what about CDMA?
private static final String INTENT_RECONNECT_ALARM = "com.android.internal.telephony.gprs-reconnect";
private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason";
@@ -177,9 +176,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
if (state == State.FAILED) {
- cleanUpConnection(false, reason);
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 0; // tearDown is false
+ msg.obj = (String) reason;
+ sendMessage(msg);
}
- trySetupData(reason);
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
} else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
final android.net.NetworkInfo networkInfo = (NetworkInfo)
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
@@ -204,6 +206,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
GsmDataConnectionTracker(GSMPhone p) {
super(p);
+ mGsmPhone = p;
p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
@@ -250,17 +253,17 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
//Unregister for all events
phone.mCM.unregisterForAvailable(this);
phone.mCM.unregisterForOffOrNotAvailable(this);
- ((GSMPhone) phone).mSIMRecords.unregisterForRecordsLoaded(this);
+ mGsmPhone.mSIMRecords.unregisterForRecordsLoaded(this);
phone.mCM.unregisterForDataStateChanged(this);
- ((GSMPhone) phone).mCT.unregisterForVoiceCallEnded(this);
- ((GSMPhone) phone).mCT.unregisterForVoiceCallStarted(this);
- ((GSMPhone) phone).mSST.unregisterForGprsAttached(this);
- ((GSMPhone) phone).mSST.unregisterForGprsDetached(this);
- ((GSMPhone) phone).mSST.unregisterForRoamingOn(this);
- ((GSMPhone) phone).mSST.unregisterForRoamingOff(this);
- ((GSMPhone) phone).mSST.unregisterForPsRestrictedEnabled(this);
- ((GSMPhone) phone).mSST.unregisterForPsRestrictedDisabled(this);
-
+ mGsmPhone.mCT.unregisterForVoiceCallEnded(this);
+ mGsmPhone.mCT.unregisterForVoiceCallStarted(this);
+ mGsmPhone.mSST.unregisterForGprsAttached(this);
+ mGsmPhone.mSST.unregisterForGprsDetached(this);
+ mGsmPhone.mSST.unregisterForRoamingOn(this);
+ mGsmPhone.mSST.unregisterForRoamingOff(this);
+ mGsmPhone.mSST.unregisterForPsRestrictedEnabled(this);
+ mGsmPhone.mSST.unregisterForPsRestrictedDisabled(this);
+
phone.getContext().unregisterReceiver(this.mIntentReceiver);
phone.getContext().getContentResolver().unregisterContentObserver(this.apnObserver);
@@ -362,7 +365,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
* The APN of the specified type is no longer needed. Ensure that if
* use of the default APN has not been explicitly disabled, we are connected
* to the default APN.
- * @param type the APN type. The only valid values are currently
+ * @param type the APN type. The only valid values are currently
* {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}.
* @return
*/
@@ -374,10 +377,14 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
removeMessages(EVENT_RESTORE_DEFAULT_APN);
setEnabled(type, false);
if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
+ mRequestedApnType = Phone.APN_TYPE_DEFAULT;
if (dataEnabled[APN_DEFAULT_ID]) {
return Phone.APN_ALREADY_ACTIVE;
} else {
- cleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 1; // tearDown is true;
+ msg.obj = Phone.REASON_DATA_DISABLED;
+ sendMessage(msg);
return Phone.APN_REQUEST_STARTED;
}
} else {
@@ -407,10 +414,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
public boolean isDataConnectionAsDesired() {
boolean roaming = phone.getServiceState().getRoaming();
- if (((GSMPhone) phone).mSIMRecords.getRecordsLoaded() &&
- ((GSMPhone) phone).mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE &&
+ if (mGsmPhone.mSIMRecords.getRecordsLoaded() &&
+ mGsmPhone.mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE &&
(!roaming || getDataOnRoamingEnabled()) &&
- !mIsWifiConnected &&
+ !mIsWifiConnected &&
!mIsPsRestricted ) {
return (state == State.CONNECTED);
}
@@ -477,7 +484,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
setEnabled(Phone.APN_TYPE_DEFAULT, true);
// trySetupData() will be a no-op if we are currently
// connected to the MMS APN
- return trySetupData(Phone.REASON_DATA_ENABLED);
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
+ return true;
} else if (!enable) {
setEnabled(Phone.APN_TYPE_DEFAULT, false);
// Don't tear down if there is an active APN and it handles MMS or SUPL.
@@ -486,21 +494,16 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
(isApnTypeActive(Phone.APN_TYPE_SUPL) && isEnabled(Phone.APN_TYPE_SUPL))) {
return false;
}
- cleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 1; // tearDown is true
+ msg.obj = Phone.REASON_DATA_DISABLED;
+ sendMessage(msg);
return true;
} else {
// isEnabled && enable
return true;
}
}
-
- /**
- * Simply tear down data connections due to radio off
- * and don't setup again.
- */
- public void cleanConnectionBeforeRadioOff() {
- cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
- }
/**
* Report the current state of data connectivity (enabled or disabled) for
@@ -565,7 +568,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason));
Log.d(LOG_TAG, "[DSAC DEB] " + "trySetupData with mIsPsRestricted=" + mIsPsRestricted);
-
+
if (phone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
@@ -576,22 +579,23 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return true;
}
- int gprsState = ((GSMPhone) phone).mSST.getCurrentGprsState();
+ int gprsState = mGsmPhone.mSST.getCurrentGprsState();
boolean roaming = phone.getServiceState().getRoaming();
+ boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState();
if ((state == State.IDLE || state == State.SCANNING)
&& (gprsState == ServiceState.STATE_IN_SERVICE || noAutoAttach)
- && ((GSMPhone) phone).mSIMRecords.getRecordsLoaded()
- && ( ((GSMPhone) phone).mSST.isConcurrentVoiceAndData() ||
- phone.getState() == Phone.State.IDLE )
+ && mGsmPhone.mSIMRecords.getRecordsLoaded()
+ && phone.getState() == Phone.State.IDLE
&& isDataAllowed()
- && !mIsPsRestricted ) {
+ && !mIsPsRestricted
+ && desiredPowerState ) {
if (state == State.IDLE) {
waitingApns = buildWaitingApns();
if (waitingApns.isEmpty()) {
if (DBG) log("No APN found");
- notifyNoData(PdpConnection.FailCause.BAD_APN);
+ notifyNoData(PdpConnection.FailCause.MISSING_UKNOWN_APN);
return false;
} else {
log ("Create from allApns : " + apnListToString(allApns));
@@ -607,13 +611,14 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
log("trySetupData: Not ready for data: " +
" dataState=" + state +
" gprsState=" + gprsState +
- " sim=" + ((GSMPhone) phone).mSIMRecords.getRecordsLoaded() +
- " UMTS=" + ((GSMPhone) phone).mSST.isConcurrentVoiceAndData() +
+ " sim=" + mGsmPhone.mSIMRecords.getRecordsLoaded() +
+ " UMTS=" + mGsmPhone.mSST.isConcurrentVoiceAndData() +
" phoneState=" + phone.getState() +
" dataEnabled=" + getAnyDataEnabled() +
" roaming=" + roaming +
" dataOnRoamingEnable=" + getDataOnRoamingEnabled() +
- " ps restricted=" + mIsPsRestricted);
+ " ps restricted=" + mIsPsRestricted +
+ " desiredPowerState=" + desiredPowerState);
return false;
}
}
@@ -638,6 +643,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
mReconnectIntent = null;
}
+ setState(State.DISCONNECTING);
+
for (DataConnection conn : pdpList) {
PdpConnection pdp = (PdpConnection) conn;
if (tearDown) {
@@ -649,25 +656,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
stopNetStatPoll();
- /*
- * If we've been asked to tear down the connection,
- * set the state to DISCONNECTING. However, there's
- * a race that can occur if for some reason we were
- * already in the IDLE state. In that case, the call
- * to pdp.disconnect() above will immediately post
- * a message to the handler thread that the disconnect
- * is done, and if the handler runs before the code
- * below does, the handler will have set the state to
- * IDLE before the code below runs. If we didn't check
- * for that, future calls to trySetupData would fail,
- * and we would never get out of the DISCONNECTING state.
- */
if (!tearDown) {
setState(State.IDLE);
phone.notifyDataConnection(reason);
mActiveApn = null;
- } else if (state != State.IDLE) {
- setState(State.DISCONNECTING);
}
}
@@ -779,7 +771,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
private boolean
- pdpStatesHasCID (ArrayList<PDPContextState> states, int cid) {
+ pdpStatesHasCID (ArrayList<DataCallState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
if (states.get(i).cid == cid) return true;
}
@@ -788,9 +780,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
private boolean
- pdpStatesHasActiveCID (ArrayList<PDPContextState> states, int cid) {
+ pdpStatesHasActiveCID (ArrayList<DataCallState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
- if (states.get(i).cid == cid) return (states.get(i).active != 0);
+ if ((states.get(i).cid == cid) && (states.get(i).active != 0)) {
+ return true;
+ }
}
return false;
@@ -805,7 +799,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
isConnected = (state != State.IDLE && state != State.FAILED);
// The "current" may no longer be valid. MMS depends on this to send properly.
- ((GSMPhone) phone).updateCurrentCarrierInProvider();
+ mGsmPhone.updateCurrentCarrierInProvider();
// TODO: It'd be nice to only do this if the changed entrie(s)
// match the current operator.
@@ -813,6 +807,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (state != State.DISCONNECTING) {
cleanUpConnection(isConnected, Phone.REASON_APN_CHANGED);
if (!isConnected) {
+ // reset reconnect timer
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ mReregisterOnReconnectFailure = false;
trySetupData(Phone.REASON_APN_CHANGED);
}
}
@@ -825,9 +822,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
* previous state
*/
protected void onPdpStateChanged (AsyncResult ar, boolean explicitPoll) {
- ArrayList<PDPContextState> pdpStates;
+ ArrayList<DataCallState> pdpStates;
- pdpStates = (ArrayList<PDPContextState>)(ar.result);
+ pdpStates = (ArrayList<DataCallState>)(ar.result);
if (ar.exception != null) {
// This is probably "radio not available" or something
@@ -893,6 +890,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
startNetStatPoll();
// reset reconnect timer
nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ mReregisterOnReconnectFailure = false;
}
private void setupDnsProperties() {
@@ -963,7 +961,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
} else {
mPdpResetCount = 0;
EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_REREGISTER_NETWORK, sentSinceLastRecv);
- ((GSMPhone) phone).mSST.reRegisterNetwork(null);
+ mGsmPhone.mSST.reRegisterNetwork(null);
}
// TODO: Add increasingly drastic recovery steps, eg,
// reset the radio, reset the device.
@@ -1056,7 +1054,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
int watchdogTrigger = Settings.Gservices.getInt(mResolver,
- Settings.Gservices.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
+ Settings.Gservices.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
NUMBER_SENT_PACKETS_OF_HANG);
if (sentSinceLastRecv >= watchdogTrigger) {
@@ -1079,7 +1077,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// Slow down the poll interval to let things happen
netStatPollPeriod = Settings.Gservices.getInt(mResolver,
- Settings.Gservices.PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS,
+ Settings.Gservices.PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS,
POLL_NETSTAT_SLOW_MILLIS);
} else {
if (DBG) log("Sent " + String.valueOf(sentSinceLastRecv) +
@@ -1112,7 +1110,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
};
-
+
private void runPingTest () {
int status = -1;
try {
@@ -1161,22 +1159,36 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
/**
* Return true if data connection need to be setup after disconnected due to
* reason.
- *
+ *
* @param reason the reason why data is disconnected
- * @return true if try setup data connection is need for this reason
+ * @return true if try setup data connection is need for this reason
*/
private boolean retryAfterDisconnected(String reason) {
boolean retry = true;
-
+
if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
- Phone.REASON_DATA_DISABLED.equals(reason) ) {
+ Phone.REASON_DATA_DISABLED.equals(reason) ) {
retry = false;
}
return retry;
- }
+ }
private void reconnectAfterFail(FailCause lastFailCauseCode, String reason) {
if (state == State.FAILED) {
+ if (nextReconnectDelay > RECONNECT_DELAY_MAX_MILLIS) {
+ if (mReregisterOnReconnectFailure) {
+ // We have already tried to re-register to the network.
+ // This might be a problem with the data network.
+ nextReconnectDelay = RECONNECT_DELAY_MAX_MILLIS;
+ } else {
+ // Try to Re-register to the network.
+ Log.d(LOG_TAG, "PDP activate failed, Reregistering to the network");
+ mReregisterOnReconnectFailure = true;
+ mGsmPhone.mSST.reRegisterNetwork(null);
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ return;
+ }
+ }
Log.d(LOG_TAG, "PDP activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
@@ -1192,9 +1204,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// double it for next time
nextReconnectDelay *= 2;
- if (nextReconnectDelay > RECONNECT_DELAY_MAX_MILLIS) {
- nextReconnectDelay = RECONNECT_DELAY_MAX_MILLIS;
- }
if (!shouldPostNotification(lastFailCauseCode)) {
Log.d(LOG_TAG,"NOT Posting GPRS Unavailable notification "
@@ -1214,7 +1223,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (state == State.FAILED) {
cleanUpConnection(false, null);
}
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED));
}
protected void onEnableNewApn() {
@@ -1223,17 +1232,16 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
}
- protected void onTrySetupData() {
- trySetupData(null);
+ protected void onTrySetupData(String reason) {
+ trySetupData(reason);
}
protected void onRestoreDefaultApn() {
if (DBG) Log.d(LOG_TAG, "Restore default APN");
setEnabled(Phone.APN_TYPE_MMS, false);
-
+ mRequestedApnType = Phone.APN_TYPE_DEFAULT;
if (!isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
cleanUpConnection(true, Phone.REASON_RESTORE_DEFAULT_APN);
- mRequestedApnType = Phone.APN_TYPE_DEFAULT;
}
}
@@ -1269,6 +1277,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// Make sure our reconnect delay starts at the initial value
// next time the radio comes on
nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ mReregisterOnReconnectFailure = false;
if (phone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
@@ -1326,19 +1335,13 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
cause = (PdpConnection.FailCause) (ar.result);
if(DBG) log("PDP setup failed " + cause);
// Log this failure to the Event Logs.
- if (cause == PdpConnection.FailCause.BAD_APN ||
- cause == PdpConnection.FailCause.BAD_PAP_SECRET ||
- cause == PdpConnection.FailCause.BARRED ||
- cause == PdpConnection.FailCause.RADIO_ERROR_RETRY ||
- cause == PdpConnection.FailCause.SUSPENED_TEMPORARY ||
- cause == PdpConnection.FailCause.UNKNOWN ||
- cause == PdpConnection.FailCause.USER_AUTHENTICATION) {
+ if (cause.isEventLoggable()) {
int cid = -1;
GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
if (loc != null) cid = loc.getCid();
EventLog.List val = new EventLog.List(
- cause.ordinal(), cid,
+ cause.ordinal(), cid,
TelephonyManager.getDefault().getNetworkType());
EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_RADIO_PDP_SETUP_FAIL, val);
}
@@ -1346,20 +1349,20 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// No try for permanent failure
if (cause.isPermanentFail()) {
notifyNoData(cause);
+ return;
}
- if (tryNextApn(cause)) {
- waitingApns.remove(0);
- if (waitingApns.isEmpty()) {
- // No more to try, start delayed retry
- startDelayedRetry(cause, reason);
- } else {
- // we still have more apns to try
- setState(State.SCANNING);
- trySetupData(reason);
- }
- } else {
+ waitingApns.remove(0);
+ if (waitingApns.isEmpty()) {
+ // No more to try, start delayed retry
startDelayedRetry(cause, reason);
+ } else {
+ // we still have more apns to try
+ setState(State.SCANNING);
+ // Wait a bit before trying the next APN, so that
+ // we're not tying up the RIL command channel
+ sendMessageDelayed(obtainMessage(EVENT_TRY_SETUP_DATA, reason),
+ RECONNECT_DELAY_INITIAL_MILLIS);
}
}
}
@@ -1387,7 +1390,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
protected void onVoiceCallStarted() {
- if (state == State.CONNECTED && !((GSMPhone) phone).mSST.isConcurrentVoiceAndData()) {
+ if (state == State.CONNECTED && ! mGsmPhone.mSST.isConcurrentVoiceAndData()) {
stopNetStatPoll();
phone.notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
}
@@ -1395,7 +1398,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
protected void onVoiceCallEnded() {
if (state == State.CONNECTED) {
- if (!((GSMPhone) phone).mSST.isConcurrentVoiceAndData()) {
+ if (!mGsmPhone.mSST.isConcurrentVoiceAndData()) {
startNetStatPoll();
phone.notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
} else {
@@ -1403,17 +1406,16 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
resetPollStats();
}
} else {
+ // reset reconnect timer
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ mReregisterOnReconnectFailure = false;
// in case data setup was attempted when we were on a voice call
trySetupData(Phone.REASON_VOICE_CALL_ENDED);
}
}
- private boolean tryNextApn(FailCause cause) {
- return (cause != FailCause.RADIO_NOT_AVAILABLE)
- && (cause != FailCause.RADIO_OFF)
- && (cause != FailCause.RADIO_ERROR_RETRY)
- && (cause != FailCause.NO_SIGNAL)
- && (cause != FailCause.SIM_LOCKED);
+ protected void onCleanUpConnection(boolean tearDown, String reason) {
+ cleanUpConnection(tearDown, reason);
}
private int getRestoreDefaultApnDelay() {
@@ -1436,7 +1438,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
*/
private void createAllApnList() {
allApns = new ArrayList<ApnSetting>();
- String operator = ((GSMPhone) phone).mSIMRecords.getSIMOperatorNumeric();
+ String operator = mGsmPhone.mSIMRecords.getSIMOperatorNumeric();
if (operator != null) {
String selection = "numeric = '" + operator + "'";
@@ -1462,7 +1464,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (allApns.isEmpty()) {
if (DBG) log("No APN found for carrier: " + operator);
preferredApn = null;
- notifyNoData(PdpConnection.FailCause.BAD_APN);
+ notifyNoData(PdpConnection.FailCause.MISSING_UKNOWN_APN);
} else {
preferredApn = getPreferredApn();
Log.d(LOG_TAG, "Get PreferredAPN");
@@ -1478,7 +1480,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
DataConnection pdp;
for (int i = 0; i < PDP_CONNECTION_POOL_SIZE; i++) {
- pdp = new PdpConnection((GSMPhone) phone);
+ pdp = new PdpConnection(mGsmPhone);
pdpList.add(pdp);
}
}
@@ -1497,7 +1499,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
*/
private ArrayList<ApnSetting> buildWaitingApns() {
ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
- String operator = ((GSMPhone )phone).mSIMRecords.getSIMOperatorNumeric();
+ String operator = mGsmPhone.mSIMRecords.getSIMOperatorNumeric();
if (mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
if (canSetPreferApn && preferredApn != null) {
@@ -1568,7 +1570,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
ContentResolver resolver = phone.getContext().getContentResolver();
resolver.delete(PREFERAPN_URI, null, null);
- if (pos >= 0) {
+ if (pos >= 0) {
ContentValues values = new ContentValues();
values.put(APN_ID, pos);
resolver.insert(PREFERAPN_URI, values);
@@ -1581,7 +1583,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
Cursor cursor = phone.getContext().getContentResolver().query(
- PREFERAPN_URI, new String[] { "_id", "name", "apn" },
+ PREFERAPN_URI, new String[] { "_id", "name", "apn" },
null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
if (cursor != null) {
@@ -1665,9 +1667,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
* PDP context and notify us with PDP_CONTEXT_CHANGED.
* But we should stop the network polling and prevent reset PDP.
*/
- Log.d(LOG_TAG, "[DSAC DEB] " + "EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
+ Log.d(LOG_TAG, "[DSAC DEB] " + "EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
stopNetStatPoll();
- mIsPsRestricted = true;
+ mIsPsRestricted = true;
break;
case EVENT_PS_RESTRICT_DISABLED:
@@ -1683,6 +1685,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (state == State.FAILED) {
cleanUpConnection(false, Phone.REASON_PS_RESTRICT_ENABLED);
nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ mReregisterOnReconnectFailure = false;
}
trySetupData(Phone.REASON_PS_RESTRICT_ENABLED);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 4db8fc6..18e6375 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -621,7 +621,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
if (isInterrogate()) {
phone.mCM.queryFacilityLock(facility, password,
serviceClass, obtainMessage(EVENT_QUERY_COMPLETE, this));
- } else if (isActivate() || isDeactivate()) {
+ } else if (isActivate() || isDeactivate()) {
phone.mCM.setFacilityLock(facility, isActivate(), password,
serviceClass, obtainMessage(EVENT_SET_COMPLETE, this));
} else {
@@ -1186,9 +1186,9 @@ public final class GsmMmiCode extends Handler implements MmiCode {
sb.append(createQueryCallWaitingResultMessage(ints[1]));
} else if (isServiceCodeCallBarring(sc)) {
// ints[0] for Call Barring is a bit vector of services
- sb.append(createQueryCallBarringResultMessage(ints[0]));
+ sb.append(createQueryCallBarringResultMessage(ints[0]));
} else if (ints[0] == 1) {
- // for all other services, treat it as a boolean
+ // for all other services, treat it as a boolean
sb.append(context.getText(com.android.internal.R.string.serviceEnabled));
} else {
sb.append(context.getText(com.android.internal.R.string.mmiError));
@@ -1224,9 +1224,9 @@ public final class GsmMmiCode extends Handler implements MmiCode {
{
StringBuilder sb = new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor));
- for (int classMask = 1
+ for (int classMask = 1
; classMask <= SERVICE_CLASS_MAX
- ; classMask <<= 1
+ ; classMask <<= 1
) {
if ((classMask & serviceClass) != 0) {
sb.append("\n");
@@ -1235,7 +1235,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
}
return sb;
}
-
+
/***
* TODO: It would be nice to have a method here that can take in a dialstring and
* figure out if there is an MMI code embedded within it. This code would replace
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 3e73caf..2770ddc 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -22,12 +22,14 @@ import android.app.PendingIntent.CanceledException;
import android.content.Intent;
import android.os.AsyncResult;
import android.os.Message;
+import android.provider.Telephony.Sms.Intents;
import android.telephony.ServiceState;
import android.util.Config;
import android.util.Log;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.gsm.SmsMessage;
+import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.SMSDispatcher;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
@@ -39,8 +41,11 @@ import java.util.HashMap;
final class GsmSMSDispatcher extends SMSDispatcher {
private static final String TAG = "GSM";
+ private GSMPhone mGsmPhone;
+
GsmSMSDispatcher(GSMPhone phone) {
super(phone);
+ mGsmPhone = phone;
}
/**
@@ -73,134 +78,61 @@ final class GsmSMSDispatcher extends SMSDispatcher {
}
}
}
-
- if (mCm != null) {
- mCm.acknowledgeLastIncomingSMS(true, null);
- }
+ acknowledgeLastIncomingSms(true, Intents.RESULT_SMS_HANDLED, null);
}
- /**
- * Dispatches an incoming SMS messages.
- *
- * @param sms the incoming message from the phone
- */
- protected void dispatchMessage(SmsMessageBase smsb) {
+ /** {@inheritDoc} */
+ protected int dispatchMessage(SmsMessageBase smsb) {
// If sms is null, means there was a parsing error.
- // TODO: Should NAK this.
if (smsb == null) {
- return;
+ return Intents.RESULT_SMS_GENERIC_ERROR;
}
SmsMessage sms = (SmsMessage) smsb;
boolean handled = false;
// Special case the message waiting indicator messages
if (sms.isMWISetMessage()) {
- ((GSMPhone) mPhone).updateMessageWaitingIndicator(true);
-
- if (sms.isMwiDontStore()) {
- handled = true;
- }
-
+ mGsmPhone.updateMessageWaitingIndicator(true);
+ handled |= sms.isMwiDontStore();
if (Config.LOGD) {
- Log.d(TAG,
- "Received voice mail indicator set SMS shouldStore="
- + !handled);
+ Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled);
}
} else if (sms.isMWIClearMessage()) {
- ((GSMPhone) mPhone).updateMessageWaitingIndicator(false);
-
- if (sms.isMwiDontStore()) {
- handled = true;
- }
-
+ mGsmPhone.updateMessageWaitingIndicator(false);
+ handled |= sms.isMwiDontStore();
if (Config.LOGD) {
- Log.d(TAG,
- "Received voice mail indicator clear SMS shouldStore="
- + !handled);
+ Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled);
}
}
if (handled) {
- return;
+ return Intents.RESULT_SMS_HANDLED;
}
- // Parse the headers to see if this is partial, or port addressed
- int referenceNumber = -1;
- int count = 0;
- int sequence = 0;
- int destPort = -1;
-
- SmsHeader header = sms.getUserDataHeader();
- if (header != null) {
- for (SmsHeader.Element element : header.getElements()) {
- try {
- switch (element.getID()) {
- case SmsHeader.CONCATENATED_8_BIT_REFERENCE: {
- byte[] data = element.getData();
-
- referenceNumber = data[0] & 0xff;
- count = data[1] & 0xff;
- sequence = data[2] & 0xff;
-
- // Per TS 23.040, 9.2.3.24.1: If the count is zero, sequence
- // is zero, or sequence > count, ignore the entire element
- if (count == 0 || sequence == 0 || sequence > count) {
- referenceNumber = -1;
- }
- break;
- }
-
- case SmsHeader.CONCATENATED_16_BIT_REFERENCE: {
- byte[] data = element.getData();
-
- referenceNumber = (data[0] & 0xff) * 256 + (data[1] & 0xff);
- count = data[2] & 0xff;
- sequence = data[3] & 0xff;
-
- // Per TS 23.040, 9.2.3.24.8: If the count is zero, sequence
- // is zero, or sequence > count, ignore the entire element
- if (count == 0 || sequence == 0 || sequence > count) {
- referenceNumber = -1;
- }
- break;
- }
-
- case SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT: {
- byte[] data = element.getData();
-
- destPort = (data[0] & 0xff) << 8;
- destPort |= (data[1] & 0xff);
-
- break;
- }
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- Log.e(TAG, "Bad element in header", e);
- return; // TODO: NACK the message or something, don't just discard.
- }
- }
- }
-
- if (referenceNumber == -1) {
- // notify everyone of the message if it isn't partial
+ SmsHeader smsHeader = sms.getUserDataHeader();
+ // See if message is partial or port addressed.
+ if ((smsHeader == null) || (smsHeader.concatRef == null)) {
+ // Message is not partial (not part of concatenated sequence).
byte[][] pdus = new byte[1][];
pdus[0] = sms.getPdu();
- if (destPort != -1) {
- if (destPort == SmsHeader.PORT_WAP_PUSH) {
- mWapPush.dispatchWapPdu(sms.getUserData());
+ if (smsHeader != null && smsHeader.portAddrs != null) {
+ if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) {
+ return mWapPush.dispatchWapPdu(sms.getUserData());
+ } else {
+ // The message was sent to a port, so concoct a URI for it.
+ dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort);
}
- // The message was sent to a port, so concoct a URI for it
- dispatchPortAddressedPdus(pdus, destPort);
} else {
- // It's a normal message, dispatch it
+ // Normal short and non-port-addressed message, dispatch it.
dispatchPdus(pdus);
}
+ return Activity.RESULT_OK;
} else {
- // Process the message part
- processMessagePart(sms, referenceNumber, sequence, count, destPort);
+ // Process the message part.
+ return processMessagePart(sms, smsHeader.concatRef, smsHeader.portAddrs);
}
}
@@ -208,28 +140,36 @@ final class GsmSMSDispatcher extends SMSDispatcher {
protected void sendMultipartText(String destinationAddress, String scAddress,
ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
ArrayList<PendingIntent> deliveryIntents) {
- int ref = ++sConcatenatedRef & 0xff;
-
- for (int i = 0, count = parts.size(); i < count; i++) {
- // build SmsHeader
- byte[] data = new byte[3];
- data[0] = (byte) ref; // reference #, unique per message
- data[1] = (byte) count; // total part count
- data[2] = (byte) (i + 1); // 1-based sequence
- SmsHeader header = new SmsHeader();
- header.add(new SmsHeader.Element(SmsHeader.CONCATENATED_8_BIT_REFERENCE, data));
- PendingIntent sentIntent = null;
- PendingIntent deliveryIntent = null;
+ int refNumber = getNextConcatenatedRef() & 0x00FF;
+
+ for (int i = 0, msgCount = parts.size(); i < msgCount; i++) {
+ SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
+ concatRef.refNumber = refNumber;
+ concatRef.seqNumber = i + 1; // 1-based sequence
+ concatRef.msgCount = msgCount;
+ // TODO: We currently set this to true since our messaging app will never
+ // send more than 255 parts (it converts the message to MMS well before that).
+ // However, we should support 3rd party messaging apps that might need 16-bit
+ // references
+ // Note: It's not sufficient to just flip this bit to true; it will have
+ // ripple effects (several calculations assume 8-bit ref).
+ concatRef.isEightBits = true;
+ SmsHeader smsHeader = new SmsHeader();
+ smsHeader.concatRef = concatRef;
+
+ PendingIntent sentIntent = null;
if (sentIntents != null && sentIntents.size() > i) {
sentIntent = sentIntents.get(i);
}
+
+ PendingIntent deliveryIntent = null;
if (deliveryIntents != null && deliveryIntents.size() > i) {
deliveryIntent = deliveryIntents.get(i);
}
SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
- parts.get(i), deliveryIntent != null, header.toByteArray());
+ parts.get(i), deliveryIntent != null, SmsHeader.toByteArray(smsHeader));
sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
}
@@ -239,7 +179,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
* Send a multi-part text based SMS which already passed SMS control check.
*
* It is the working function for sendMultipartText().
- *
+ *
* @param destinationAddress the address to send the message to
* @param scAddress is the service center address or null to use
* the current default SMSC
@@ -259,18 +199,16 @@ final class GsmSMSDispatcher extends SMSDispatcher {
* to the recipient. The raw pdu of the status report is in the
* extended data ("pdu").
*/
- private void sendMultipartTextWithPermit(String destinationAddress,
+ private void sendMultipartTextWithPermit(String destinationAddress,
String scAddress, ArrayList<String> parts,
- ArrayList<PendingIntent> sentIntents,
+ ArrayList<PendingIntent> sentIntents,
ArrayList<PendingIntent> deliveryIntents) {
-
- PendingIntent sentIntent = null;
- PendingIntent deliveryIntent = null;
-
+
// check if in service
int ss = mPhone.getServiceState().getState();
if (ss != ServiceState.STATE_IN_SERVICE) {
for (int i = 0, count = parts.size(); i < count; i++) {
+ PendingIntent sentIntent = null;
if (sentIntents != null && sentIntents.size() > i) {
sentIntent = sentIntents.get(i);
}
@@ -280,26 +218,29 @@ final class GsmSMSDispatcher extends SMSDispatcher {
return;
}
- int ref = ++sConcatenatedRef & 0xff;
-
- for (int i = 0, count = parts.size(); i < count; i++) {
- // build SmsHeader
- byte[] data = new byte[3];
- data[0] = (byte) ref; // reference #, unique per message
- data[1] = (byte) count; // total part count
- data[2] = (byte) (i + 1); // 1-based sequence
- SmsHeader header = new SmsHeader();
- header.add(new SmsHeader.Element(SmsHeader.CONCATENATED_8_BIT_REFERENCE, data));
-
+ int refNumber = getNextConcatenatedRef() & 0x00FF;
+
+ for (int i = 0, msgCount = parts.size(); i < msgCount; i++) {
+ SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
+ concatRef.refNumber = refNumber;
+ concatRef.seqNumber = i + 1; // 1-based sequence
+ concatRef.msgCount = msgCount;
+ concatRef.isEightBits = false;
+ SmsHeader smsHeader = new SmsHeader();
+ smsHeader.concatRef = concatRef;
+
+ PendingIntent sentIntent = null;
if (sentIntents != null && sentIntents.size() > i) {
sentIntent = sentIntents.get(i);
}
+
+ PendingIntent deliveryIntent = null;
if (deliveryIntents != null && deliveryIntents.size() > i) {
deliveryIntent = deliveryIntents.get(i);
}
SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
- parts.get(i), deliveryIntent != null, header.toByteArray());
+ parts.get(i), deliveryIntent != null, SmsHeader.toByteArray(smsHeader));
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("smsc", pdus.encodedScAddress);
@@ -307,7 +248,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
SmsTracker tracker = SmsTrackerFactory(map, sentIntent, deliveryIntent);
sendSms(tracker);
- }
+ }
}
/** {@inheritDoc} */
@@ -324,33 +265,33 @@ final class GsmSMSDispatcher extends SMSDispatcher {
/**
* Send the multi-part SMS based on multipart Sms tracker
- *
+ *
* @param tracker holds the multipart Sms tracker ready to be sent
*/
protected void sendMultipartSms (SmsTracker tracker) {
ArrayList<String> parts;
ArrayList<PendingIntent> sentIntents;
ArrayList<PendingIntent> deliveryIntents;
-
+
HashMap map = tracker.mData;
-
+
String destinationAddress = (String) map.get("destination");
String scAddress = (String) map.get("scaddress");
-
+
parts = (ArrayList<String>) map.get("parts");
sentIntents = (ArrayList<PendingIntent>) map.get("sentIntents");
deliveryIntents = (ArrayList<PendingIntent>) map.get("deliveryIntents");
-
- sendMultipartTextWithPermit(destinationAddress,
+
+ sendMultipartTextWithPermit(destinationAddress,
scAddress, parts, sentIntents, deliveryIntents);
}
/** {@inheritDoc} */
- protected void acknowledgeLastIncomingSms(boolean success, Message response){
+ protected void acknowledgeLastIncomingSms(boolean success, int result, Message response){
// FIXME unit test leaves cm == null. this should change
if (mCm != null) {
- mCm.acknowledgeLastIncomingSMS(success, response);
+ mCm.acknowledgeLastIncomingGsmSms(success, resultToCause(result), response);
}
}
@@ -375,5 +316,17 @@ final class GsmSMSDispatcher extends SMSDispatcher {
response.recycle();
}
+ private int resultToCause(int rc) {
+ switch (rc) {
+ case Activity.RESULT_OK:
+ case Intents.RESULT_SMS_HANDLED:
+ // Cause code is ignored on success.
+ return 0;
+ case Intents.RESULT_SMS_OUT_OF_MEMORY:
+ return CommandsInterface.GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED;
+ case Intents.RESULT_SMS_GENERIC_ERROR:
+ default:
+ return CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR;
+ }
+ }
}
-
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 9ab1002..b3b4345 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -16,7 +16,13 @@
package com.android.internal.telephony.gsm;
-import com.android.internal.telephony.Phone;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ALPHA;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISROAMING;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_NUMERIC;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -38,6 +44,7 @@ import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.provider.Telephony.Intents;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
import android.util.Config;
@@ -49,21 +56,11 @@ import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
import com.android.internal.telephony.TelephonyIntents;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISROAMING;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_NUMERIC;
-
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
@@ -73,6 +70,7 @@ import java.util.TimeZone;
* {@hide}
*/
final class GsmServiceStateTracker extends ServiceStateTracker {
+
//***** Instance Variables
GSMPhone phone;
GsmCellLocation cellLoc;
@@ -80,9 +78,6 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
int mPreferredNetworkType;
RestrictedState rs;
- int rssi = 99; // signal strength 0-31, 99=unknown
- // That's "received signal strength indication" fyi
-
private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
@@ -121,7 +116,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
private boolean mStartedGprsRegCheck = false;
// Already sent the event-log for no gprs register
private boolean mReportedGprsNoReg = false;
-
+
/**
* The Notification object given to the NotificationManager.
*/
@@ -151,9 +146,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
static final int CS_DISABLED = 1004; // Access Control enables all voice/sms service
static final int CS_NORMAL_ENABLED = 1005; // Access Control blocks normal voice/sms service
static final int CS_EMERGENCY_ENABLED = 1006; // Access Control blocks emergency call service
-
+
// notification id
- static final int PS_NOTIFICATION = 888; //id to update and cancel PS restricted
+ static final int PS_NOTIFICATION = 888; //id to update and cancel PS restricted
static final int CS_NOTIFICATION = 999; //id to update and cancel CS restricted
private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
@@ -177,6 +172,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
cellLoc = new GsmCellLocation();
newCellLoc = new GsmCellLocation();
rs = new RestrictedState();
+ mSignalStrength = new SignalStrength();
PowerManager powerManager =
(PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
@@ -201,7 +197,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
cr.registerContentObserver(
Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
mAutoTimeObserver);
- setRssiDefaultValues();
+ setSignalStrengthDefaultValues();
mNeedToRegForSimLoaded = true;
}
@@ -280,7 +276,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
* @param obj placed in Message.obj
*/
/*protected*/ void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
- Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedEnabled ");
+ Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedEnabled ");
Registrant r = new Registrant(h, what, obj);
psRestrictEnabledRegistrants.add(r);
@@ -300,7 +296,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
* @param obj placed in Message.obj
*/
/*protected*/ void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
- Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedDisabled ");
+ Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedDisabled ");
Registrant r = new Registrant(h, what, obj);
psRestrictDisabledRegistrants.add(r);
@@ -308,7 +304,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
r.notifyRegistrant();
}
}
-
+
/*protected*/ void unregisterForPsRestrictedDisabled(Handler h) {
psRestrictDisabledRegistrants.remove(h);
}
@@ -506,13 +502,13 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
mStartedGprsRegCheck = false;
break;
-
+
case EVENT_RESTRICTED_STATE_CHANGED:
// This is a notification from
// CommandsInterface.setOnRestrictedStateChanged
Log.d(LOG_TAG, "[DSAC DEB] " + "EVENT_RESTRICTED_STATE_CHANGED");
-
+
ar = (AsyncResult) msg.obj;
onRestrictedStateChanged(ar);
@@ -541,12 +537,15 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
(dcTracker.getAnyDataEnabled() ? 1 : 0) );
EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_DATA_STATE_RADIO_OFF, val);
}
- dcTracker.cleanConnectionBeforeRadioOff();
-
+ Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 1; // tearDown is true
+ msg.obj = GSMPhone.REASON_RADIO_TURNED_OFF;
+ dcTracker.sendMessage(msg);
+
// poll data state up to 15 times, with a 100ms delay
// totaling 1.5 sec. Normal data disable action will finish in 100ms.
for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) {
- if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED
+ if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED
&& dcTracker.getState() != DataConnectionTracker.State.DISCONNECTING) {
Log.d(LOG_TAG, "Data shutdown complete.");
break;
@@ -557,7 +556,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
cm.setRadioPower(false, null);
} // Otherwise, we're in the desired state
}
-
+
protected void updateSpnDisplay() {
int rule = phone.mSIMRecords.getDisplayRule(ss.getOperatorNumeric());
String spn = phone.mSIMRecords.getServiceProviderName();
@@ -699,9 +698,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
- private void
- setRssiDefaultValues() {
- rssi = 99;
+ private void setSignalStrengthDefaultValues() {
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, true);
}
/**
@@ -722,7 +720,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
case RADIO_UNAVAILABLE:
newSS.setStateOutOfService();
newCellLoc.setStateInvalid();
- setRssiDefaultValues();
+ setSignalStrengthDefaultValues();
mGotCountryCode = false;
pollStateDone();
@@ -731,7 +729,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
case RADIO_OFF:
newSS.setStateOff();
newCellLoc.setStateInvalid();
- setRssiDefaultValues();
+ setSignalStrengthDefaultValues();
mGotCountryCode = false;
pollStateDone();
@@ -745,10 +743,10 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
Log.d(LOG_TAG, "Radio Technology Change ongoing, setting SS to off");
newSS.setStateOff();
newCellLoc.setStateInvalid();
- setRssiDefaultValues();
+ setSignalStrengthDefaultValues();
mGotCountryCode = false;
- pollStateDone();
+ //NOTE: pollStateDone() is not needed in this case
break;
default:
@@ -1044,17 +1042,18 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
/**
- * send signal-strength-changed notification if rssi changed
+ * send signal-strength-changed notification if changed
* Called both for solicited and unsolicited signal stength updates
*/
private void
onSignalStrengthResult(AsyncResult ar) {
- int oldRSSI = rssi;
+ SignalStrength oldSignalStrength = mSignalStrength;
+ int rssi = 99;
if (ar.exception != null) {
- // 99 = unknown
+ // -1 = unknown
// most likely radio is resetting/disconnected
- rssi = 99;
+ setSignalStrengthDefaultValues();
} else {
int[] ints = (int[])ar.result;
@@ -1067,13 +1066,16 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
}
- if (rssi != oldRSSI) {
+ mSignalStrength = new SignalStrength(rssi, -1, -1, -1,
+ -1, -1, -1, true);
+
+ if (!mSignalStrength.equals(oldSignalStrength)) {
try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after
// POLL_PERIOD_MILLIS) during Radio Technology Change)
phone.notifySignalStrength();
} catch (NullPointerException ex) {
- Log.d(LOG_TAG, "onSignalStrengthResult() Phone already destroyed: " + ex
- + "Signal Stranth not notified");
+ log("onSignalStrengthResult() Phone already destroyed: " + ex
+ + "SignalStrength not notified");
}
}
}
@@ -1089,27 +1091,27 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
{
Log.d(LOG_TAG, "[DSAC DEB] " + "onRestrictedStateChanged");
RestrictedState newRs = new RestrictedState();
-
+
Log.d(LOG_TAG, "[DSAC DEB] " + "current rs at enter "+ rs);
-
+
if (ar.exception == null) {
int[] ints = (int[])ar.result;
int state = ints[0];
-
+
newRs.setCsEmergencyRestricted(
((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
//ignore the normal call and data restricted state before SIM READY
- if (phone.getIccCard().getState() == IccCard.State.READY) {
+ if (phone.getIccCard().getState() == IccCard.State.READY) {
newRs.setCsNormalRestricted(
((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
newRs.setPsRestricted(
(state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0);
}
-
- Log.d(LOG_TAG, "[DSAC DEB] " + "new rs "+ newRs);
-
+
+ Log.d(LOG_TAG, "[DSAC DEB] " + "new rs "+ newRs);
+
if (!rs.isPsRestricted() && newRs.isPsRestricted()) {
psRestrictEnabledRegistrants.notifyRegistrants();
setNotification(PS_ENABLED);
@@ -1117,9 +1119,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
psRestrictDisabledRegistrants.notifyRegistrants();
setNotification(PS_DISABLED);
}
-
+
/**
- * There are two kind of cs restriction, normal and emergency. So
+ * There are two kind of cs restriction, normal and emergency. So
* there are 4 x 4 combinations in current and new restricted states
* and we only need to notify when state is changed.
*/
@@ -1129,32 +1131,32 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
setNotification(CS_DISABLED);
} else if (!newRs.isCsNormalRestricted()) {
// remove normal restriction
- setNotification(CS_EMERGENCY_ENABLED);
+ setNotification(CS_EMERGENCY_ENABLED);
} else if (!newRs.isCsEmergencyRestricted()) {
// remove emergency restriction
- setNotification(CS_NORMAL_ENABLED);
+ setNotification(CS_NORMAL_ENABLED);
}
} else if (rs.isCsEmergencyRestricted() && !rs.isCsNormalRestricted()) {
if (!newRs.isCsRestricted()) {
// remove all restriction
- setNotification(CS_DISABLED);
+ setNotification(CS_DISABLED);
} else if (newRs.isCsRestricted()) {
// enable all restriction
setNotification(CS_ENABLED);
} else if (newRs.isCsNormalRestricted()) {
// remove emergency restriction and enable normal restriction
- setNotification(CS_NORMAL_ENABLED);
+ setNotification(CS_NORMAL_ENABLED);
}
} else if (!rs.isCsEmergencyRestricted() && rs.isCsNormalRestricted()) {
if (!newRs.isCsRestricted()) {
// remove all restriction
- setNotification(CS_DISABLED);
+ setNotification(CS_DISABLED);
} else if (newRs.isCsRestricted()) {
// enable all restriction
setNotification(CS_ENABLED);
} else if (newRs.isCsEmergencyRestricted()) {
// remove normal restriction and enable emergency restriction
- setNotification(CS_EMERGENCY_ENABLED);
+ setNotification(CS_EMERGENCY_ENABLED);
}
} else {
if (newRs.isCsRestricted()) {
@@ -1162,10 +1164,10 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
setNotification(CS_ENABLED);
} else if (newRs.isCsEmergencyRestricted()) {
// enable emergency restriction
- setNotification(CS_EMERGENCY_ENABLED);
+ setNotification(CS_EMERGENCY_ENABLED);
} else if (newRs.isCsNormalRestricted()) {
// enable normal restriction
- setNotification(CS_NORMAL_ENABLED);
+ setNotification(CS_NORMAL_ENABLED);
}
}
@@ -1527,7 +1529,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
/**
* Post a notification to NotificationManager for restricted state
- *
+ *
* @param notifyType is one state of PS/CS_*_ENABLE/DISABLE
*/
private void setNotification(int notifyType) {
@@ -1546,7 +1548,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
CharSequence details = "";
CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle);
int notificationId = CS_NOTIFICATION;
-
+
switch (notifyType) {
case PS_ENABLED:
notificationId = PS_NOTIFICATION;
@@ -1557,24 +1559,24 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
break;
case CS_ENABLED:
details = context.getText(com.android.internal.R.string.RestrictedOnAll);;
- break;
+ break;
case CS_NORMAL_ENABLED:
details = context.getText(com.android.internal.R.string.RestrictedOnNormal);;
- break;
+ break;
case CS_EMERGENCY_ENABLED:
details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);;
- break;
+ break;
case CS_DISABLED:
// do nothing and cancel the notification later
- break;
+ break;
}
-
+
Log.d(LOG_TAG, "[DSAC DEB] " + "put notification " + title + " / " +details);
mNotification.tickerText = title;
- mNotification.setLatestEventInfo(context, title, details,
+ mNotification.setLatestEventInfo(context, title, details,
mNotification.contentIntent);
-
- NotificationManager notificationManager = (NotificationManager)
+
+ NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
@@ -1585,4 +1587,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
notificationManager.notify(notificationId, mNotification);
}
}
+
+ private void log(String s) {
+ Log.d(LOG_TAG, "[GsmServiceStateTracker] " + s);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/MccTable.java b/telephony/java/com/android/internal/telephony/gsm/MccTable.java
index 6198979..e18da56 100644
--- a/telephony/java/com/android/internal/telephony/gsm/MccTable.java
+++ b/telephony/java/com/android/internal/telephony/gsm/MccTable.java
@@ -182,7 +182,7 @@ public final class MccTable
table.add(new MccEntry(222,"it",2,"Europe/Rome","it")); //Italy
table.add(new MccEntry(225,"va",2,"Europe/Rome","it")); //Vatican City State
table.add(new MccEntry(226,"ro",2)); //Romania
- table.add(new MccEntry(228,"ch",2,"Europe/Zurich","en")); //Switzerland (Confederation of)
+ table.add(new MccEntry(228,"ch",2,"Europe/Zurich","de")); //Switzerland (Confederation of)
table.add(new MccEntry(230,"cz",2,"Europe/Prague","cs")); //Czech Republic
table.add(new MccEntry(231,"sk",2)); //Slovak Republic
table.add(new MccEntry(232,"at",2,"Europe/Vienna","de")); //Austria
diff --git a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
index 88acb1b..55e5adc 100644
--- a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
@@ -35,32 +35,32 @@ public class PdpConnection extends DataConnection {
private static final String LOG_TAG = "GSM";
private static final boolean DBG = true;
- private static final boolean FAKE_FAIL = false;
/** Fail cause of last PDP activate, from RIL_LastPDPActivateFailCause */
- private static final int PDP_FAIL_RIL_BARRED = 8;
- private static final int PDP_FAIL_RIL_BAD_APN = 27;
- private static final int PDP_FAIL_RIL_USER_AUTHENTICATION = 29;
- private static final int PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED = 32;
- private static final int PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED = 33;
- private static final int PDP_FAIL_RIL_ERROR_UNSPECIFIED = 0xffff;
+ private static final int PDP_FAIL_OPERATOR_BARRED = 0x08;
+ private static final int PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A;
+ private static final int PDP_FAIL_MISSING_UKNOWN_APN = 0x1B;
+ private static final int PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C;
+ private static final int PDP_FAIL_USER_AUTHENTICATION = 0x1D;
+ private static final int PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E;
+ private static final int PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
+ private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20;
+ private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21;
+ private static final int PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22;
+ private static final int PDP_FAIL_NSAPI_IN_USE = 0x23;
+ private static final int PDP_FAIL_PROTOCOL_ERRORS = 0x6F;
+ private static final int PDP_FAIL_ERROR_UNSPECIFIED = 0xffff;
+
+ private static final int PDP_FAIL_REGISTRATION_FAIL = -1;
+ private static final int PDP_FAIL_GPRS_REGISTRATION_FAIL = -2;
//***** Instance Variables
private String pdp_name;
private ApnSetting apn;
- // dataLink is only used to support pppd link
- private DataLink dataLink;
-
//***** Constructor
PdpConnection(GSMPhone phone) {
super(phone);
- this.dataLink = null;
-
- if (SystemProperties.get("ro.radio.use-ppp","no").equals("yes")) {
- dataLink = new PppLink((GsmDataConnectionTracker) phone.mDataConnection, phone);
- dataLink.setOnLinkChange(this, EVENT_LINK_STATE_CHANGED, null);
- }
}
/**
@@ -83,28 +83,20 @@ public class PdpConnection extends DataConnection {
lastFailCause = FailCause.NONE;
receivedDisconnectReq = false;
- if (FAKE_FAIL) {
- // for debug before baseband implement error in setup PDP
- if (apn.apn.equalsIgnoreCase("badapn")){
- notifyFail(FailCause.BAD_APN, onConnectCompleted);
- return;
- }
- }
-
phone.mCM.setupDataCall(Integer.toString(RILConstants.GSM_PHONE), null, apn.apn, apn.user,
apn.password, obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
}
+ private void tearDownData(Message msg) {
+ if (phone.mCM.getRadioState().isOn()) {
+ phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
+ }
+ }
+
protected void disconnect(Message msg) {
onDisconnect = msg;
if (state == State.ACTIVE) {
- if (dataLink != null) {
- dataLink.disconnect();
- }
-
- if (phone.mCM.getRadioState().isOn()) {
- phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
- }
+ tearDownData(msg);
} else if (state == State.ACTIVATING) {
receivedDisconnectReq = true;
} else {
@@ -186,21 +178,51 @@ public class PdpConnection extends DataConnection {
FailCause cause;
switch (rilCause) {
- case PDP_FAIL_RIL_BARRED:
- cause = FailCause.BARRED;
+ case PDP_FAIL_OPERATOR_BARRED:
+ cause = FailCause.OPERATOR_BARRED;
+ break;
+ case PDP_FAIL_INSUFFICIENT_RESOURCES:
+ cause = FailCause.INSUFFICIENT_RESOURCES;
break;
- case PDP_FAIL_RIL_BAD_APN:
- cause = FailCause.BAD_APN;
+ case PDP_FAIL_MISSING_UKNOWN_APN:
+ cause = FailCause.MISSING_UKNOWN_APN;
break;
- case PDP_FAIL_RIL_USER_AUTHENTICATION:
+ case PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE:
+ cause = FailCause.UNKNOWN_PDP_ADDRESS;
+ break;
+ case PDP_FAIL_USER_AUTHENTICATION:
cause = FailCause.USER_AUTHENTICATION;
break;
- case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED:
+ case PDP_FAIL_ACTIVATION_REJECT_GGSN:
+ cause = FailCause.ACTIVATION_REJECT_GGSN;
+ break;
+ case PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED:
+ cause = FailCause.ACTIVATION_REJECT_UNSPECIFIED;
+ break;
+ case PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER:
+ cause = FailCause.SERVICE_OPTION_OUT_OF_ORDER;
+ break;
+ case PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED:
cause = FailCause.SERVICE_OPTION_NOT_SUPPORTED;
break;
- case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED:
+ case PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED:
cause = FailCause.SERVICE_OPTION_NOT_SUBSCRIBED;
break;
+ case PDP_FAIL_NSAPI_IN_USE:
+ cause = FailCause.NSAPI_IN_USE;
+ break;
+ case PDP_FAIL_PROTOCOL_ERRORS:
+ cause = FailCause.PROTOCOL_ERRORS;
+ break;
+ case PDP_FAIL_ERROR_UNSPECIFIED:
+ cause = FailCause.UNKNOWN;
+ break;
+ case PDP_FAIL_REGISTRATION_FAIL:
+ cause = FailCause.REGISTRATION_FAIL;
+ break;
+ case PDP_FAIL_GPRS_REGISTRATION_FAIL:
+ cause = FailCause.GPRS_REGISTRATION_FAIL;
+ break;
default:
cause = FailCause.UNKNOWN;
}
@@ -243,7 +265,7 @@ public class PdpConnection extends DataConnection {
// Don't bother reporting success if there's already a
// pending disconnect request, since DataConnectionTracker
// has already updated its state.
- disconnect(onDisconnect);
+ tearDownData(onDisconnect);
} else {
String[] response = ((String[]) ar.result);
cid = Integer.parseInt(response[0]);
@@ -278,11 +300,7 @@ public class PdpConnection extends DataConnection {
}
}
- if (dataLink != null) {
- dataLink.connect();
- } else {
- onLinkStateChanged(DataLink.LinkState.LINK_UP);
- }
+ onLinkStateChanged(DataLink.LinkState.LINK_UP);
if (DBG) log("PDP setup on cid = " + cid);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/PppLink.java b/telephony/java/com/android/internal/telephony/gsm/PppLink.java
deleted file mode 100644
index 9627696..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/PppLink.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2006 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.gsm;
-
-import android.database.Cursor;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.os.SystemService;
-import android.util.Log;
-
-import com.android.internal.telephony.DataLink;
-import com.android.internal.telephony.DataConnectionTracker.State;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.util.ArrayUtils;
-
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-
-/**
- * Represents a PPP link.
- *
- * Ideally this would be managed by the RIL implementation, but
- * we currently have implementations where this is not the case.
- *
- * {@hide}
- */
-final class PppLink extends DataLink {
- private static final String LOG_TAG = "GSM";
-
- static final String PATH_PPP_OPERSTATE = "/sys/class/net/ppp0/operstate";
- static final String SERVICE_PPPD_GPRS = "pppd_gprs";
- static final String PROPERTY_PPPD_EXIT_CODE = "net.gprs.ppp-exit";
- static final int POLL_SYSFS_MILLIS = 5 * 1000;
- static final int EVENT_POLL_DATA_CONNECTION = 2;
- static final int EVENT_PPP_OPERSTATE_CHANGED = 8;
- static final int EVENT_PPP_PIDFILE_CHANGED = 9;
-
- static final byte[] UP_ASCII_STRING = new byte[] {
- 'u' & 0xff,
- 'p' & 0xff,
- };
- static final byte[] DOWN_ASCII_STRING = new byte[] {
- 'd' & 0xff,
- 'o' & 0xff,
- 'w' & 0xff,
- 'n' & 0xff,
- };
- static final byte[] UNKNOWN_ASCII_STRING = new byte[] {
- 'u' & 0xff,
- 'n' & 0xff,
- 'k' & 0xff,
- 'n' & 0xff,
- 'o' & 0xff,
- 'w' & 0xff,
- 'n' & 0xff,
- };
- private final byte[] mCheckPPPBuffer = new byte[32];
-
- private PhoneBase phone;
-
- int lastPppdExitCode = EXIT_OK;
-
-
- PppLink(GsmDataConnectionTracker dc, GSMPhone p) {
- super(dc);
- this.phone = p;
- }
-
- public void connect() {
- // Clear any previous exit code
- SystemProperties.set(PROPERTY_PPPD_EXIT_CODE, "");
- SystemService.start(SERVICE_PPPD_GPRS);
- removeMessages(EVENT_POLL_DATA_CONNECTION);
- Message poll = obtainMessage();
- poll.what = EVENT_POLL_DATA_CONNECTION;
- sendMessageDelayed(poll, POLL_SYSFS_MILLIS);
- }
-
- public void disconnect() {
- SystemService.stop(SERVICE_PPPD_GPRS);
- }
-
- public int getLastLinkExitCode() {
- return lastPppdExitCode;
- }
-
- public void setPasswordInfo(Cursor cursor) {
- StringBuilder builder = new StringBuilder();
- FileOutputStream output = null;
-
- try {
- output = new FileOutputStream("/etc/ppp/pap-secrets");
- if (cursor.moveToFirst()) {
- do {
- builder.append(cursor.getString(cursor.getColumnIndex("user")));
- builder.append(" ");
- builder.append(cursor.getString(cursor.getColumnIndex("server")));
- builder.append(" ");
- builder.append(cursor.getString(cursor.getColumnIndex("password")));
- builder.append("\n");
- } while (cursor.moveToNext());
- }
-
- output.write(builder.toString().getBytes());
- } catch (java.io.IOException e) {
- Log.e(LOG_TAG, "Could not create '/etc/ppp/pap-secrets'", e);
- } finally {
- try {
- if (output != null) output.close();
- } catch (java.io.IOException e) {
- Log.e(LOG_TAG, "Error closing '/etc/ppp/pap-secrets'", e);
- }
- }
- }
-
- public void handleMessage (Message msg) {
-
- switch (msg.what) {
-
- case EVENT_POLL_DATA_CONNECTION:
- checkPPP();
-
- // keep polling in case interface goes down
- if (dataConnection.getState() != State.IDLE) {
- Message poll = obtainMessage();
- poll.what = EVENT_POLL_DATA_CONNECTION;
- sendMessageDelayed(poll, POLL_SYSFS_MILLIS);
- }
- break;
- }
- }
-
- private void checkPPP() {
- boolean connecting = (dataConnection.getState() == State.CONNECTING);
-
- try {
- RandomAccessFile file = new RandomAccessFile(PATH_PPP_OPERSTATE, "r");
- file.read(mCheckPPPBuffer);
- file.close();
-
- // Unfortunately, we're currently seeing operstate
- // "unknown" where one might otherwise expect "up"
- if (ArrayUtils.equals(mCheckPPPBuffer, UP_ASCII_STRING, UP_ASCII_STRING.length)
- || ArrayUtils.equals(mCheckPPPBuffer, UNKNOWN_ASCII_STRING,
- UNKNOWN_ASCII_STRING.length)
- && dataConnection.getState() == State.CONNECTING) {
-
- Log.i(LOG_TAG,
- "found ppp interface. Notifying GPRS connected");
-
- if (mLinkChangeRegistrant != null) {
- mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP);
- }
-
- connecting = false;
- } else if (dataConnection.getState() == State.CONNECTED
- && ArrayUtils.equals(mCheckPPPBuffer, DOWN_ASCII_STRING,
- DOWN_ASCII_STRING.length)) {
-
- Log.i(LOG_TAG,
- "ppp interface went down. Reconnecting...");
-
- if (mLinkChangeRegistrant != null) {
- mLinkChangeRegistrant.notifyResult(LinkState.LINK_DOWN);
- }
- }
- } catch (IOException ex) {
- if (! (ex instanceof FileNotFoundException)) {
- Log.i(LOG_TAG, "Poll ppp0 ex " + ex.toString());
- }
-
- if (dataConnection.getState() == State.CONNECTED &&
- mLinkChangeRegistrant != null) {
- mLinkChangeRegistrant.notifyResult(LinkState.LINK_DOWN);
- }
- }
-
- // CONNECTING means pppd has started but negotiation is not complete
- // If we're still CONNECTING here, check to see if pppd has
- // already exited
- if (connecting) {
- String exitCode;
-
- exitCode = SystemProperties.get(PROPERTY_PPPD_EXIT_CODE, "");
-
- if (!exitCode.equals("")) {
- // pppd has exited. Let's figure out why
- lastPppdExitCode = Integer.parseInt(exitCode);
-
- Log.d(LOG_TAG,"pppd exited with " + exitCode);
-
- if (mLinkChangeRegistrant != null) {
- mLinkChangeRegistrant.notifyResult(LinkState.LINK_EXITED);
- }
- }
- }
-
- }
-
- protected void log(String s) {
- Log.d(LOG_TAG, "[PppLink] " + s);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/RestrictedState.java b/telephony/java/com/android/internal/telephony/gsm/RestrictedState.java
index d17f134..3f7d5d7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/RestrictedState.java
+++ b/telephony/java/com/android/internal/telephony/gsm/RestrictedState.java
@@ -19,7 +19,7 @@ package com.android.internal.telephony.gsm;
import android.telephony.ServiceState;
public class RestrictedState {
-
+
/**
* Set true to block packet data access due to restriction
*/
@@ -32,7 +32,7 @@ public class RestrictedState {
* Set true to block emergency call due to restriction
*/
private boolean mCsEmergencyRestricted;
-
+
public RestrictedState() {
setPsRestricted(false);
setCsNormalRestricted(false);
@@ -80,11 +80,11 @@ public class RestrictedState {
public boolean isPsRestricted() {
return mPsRestricted;
}
-
+
public boolean isCsRestricted() {
return mCsNormalRestricted && mCsEmergencyRestricted;
}
-
+
@Override
public boolean equals (Object o) {
RestrictedState s;
@@ -107,7 +107,7 @@ public class RestrictedState {
@Override
public String toString() {
String csString = "none";
-
+
if (mCsEmergencyRestricted && mCsNormalRestricted) {
csString = "all";
} else if (mCsEmergencyRestricted && !mCsNormalRestricted) {
@@ -115,7 +115,7 @@ public class RestrictedState {
} else if (!mCsEmergencyRestricted && mCsNormalRestricted) {
csString = "normal call";
}
-
+
return "Restricted State CS: " + csString + " PS:" + mPsRestricted;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index f9015d9..e25de81 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -67,7 +67,7 @@ public final class SIMRecords extends IccRecords {
SpnOverride mSpnOverride;
-
+
//***** Cached SIM State; cleared on channel close
String imsi;
@@ -92,7 +92,6 @@ public final class SIMRecords extends IccRecords {
byte[] mEfCfis = null;
- String spn;
int spnDisplayCondition;
// Numeric network codes listed in TS 51.011 EF[SPDI]
ArrayList<String> spdiNetworks = null;
@@ -204,7 +203,7 @@ public final class SIMRecords extends IccRecords {
// -1 means no EF_SPN found; treat accordingly.
spnDisplayCondition = -1;
efMWIS = null;
- efCPHS_MWI = null;
+ efCPHS_MWI = null;
spdiNetworks = null;
pnnHomeName = null;
@@ -483,7 +482,7 @@ public final class SIMRecords extends IccRecords {
return imsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
}
-
+
/**
* If the timezone is not already set, set it based on the MCC of the SIM.
* @param mcc Mobile Country Code of the SIM
@@ -492,7 +491,7 @@ public final class SIMRecords extends IccRecords {
String timezone = SystemProperties.get(TIMEZONE_PROPERTY);
if (timezone == null || timezone.length() == 0) {
String zoneId = MccTable.defaultTimeZoneForMcc(mcc);
-
+
if (zoneId != null && zoneId.length() > 0) {
// Set time zone based on MCC
AlarmManager alarm =
@@ -1011,7 +1010,7 @@ public final class SIMRecords extends IccRecords {
IccUtils.bytesToHexString(data));
mEfCfis = data;
-
+
// Refer TS 51.011 Section 10.3.46 for the content description
callForwardingEnabled = ((data[1] & 0x01) != 0);
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
new file mode 100644
index 0000000..45f50bc
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.telephony.gsm;
+
+/**
+ * SmsBroadcastConfigInfo defines one configuration of Cell Broadcast
+ * Message (CBM) to be received by the ME
+ *
+ * fromServiceId - toServiceId defines a range of CBM message identifiers
+ * whose value is 0x0000 - 0xFFFF as defined in TS 23.041 9.4.1.2.2 for GMS
+ * and 9.4.4.2.2 for UMTS. All other values can be treated as empty
+ * CBM message ID.
+ *
+ * fromCodeScheme - toCodeScheme defines a range of CBM data coding schemes
+ * whose value is 0x00 - 0xFF as defined in TS 23.041 9.4.1.2.3 for GMS
+ * and 9.4.4.2.3 for UMTS.
+ * All other values can be treated as empty CBM data coding scheme.
+ *
+ * selected false means message types specified in <fromServiceId, toServiceId>
+ * and <fromCodeScheme, toCodeScheme>are not accepted, while true means accepted.
+ *
+ */
+public class SmsBroadcastConfigInfo {
+ private int fromServiceId;
+ private int toServiceId;
+ private int fromCodeScheme;
+ private int toCodeScheme;
+ private boolean selected;
+
+ /**
+ * Initialize the object from rssi and cid.
+ */
+ public SmsBroadcastConfigInfo(int fromId, int toId, int fromScheme,
+ int toScheme, boolean selected) {
+ setFromServiceId(fromId);
+ setToServiceId(toId);
+ setFromCodeScheme(fromScheme);
+ setToCodeScheme(toScheme);
+ this.setSelected(selected);
+ }
+
+ /**
+ * @param fromServiceId the fromServiceId to set
+ */
+ public void setFromServiceId(int fromServiceId) {
+ this.fromServiceId = fromServiceId;
+ }
+
+ /**
+ * @return the fromServiceId
+ */
+ public int getFromServiceId() {
+ return fromServiceId;
+ }
+
+ /**
+ * @param toServiceId the toServiceId to set
+ */
+ public void setToServiceId(int toServiceId) {
+ this.toServiceId = toServiceId;
+ }
+
+ /**
+ * @return the toServiceId
+ */
+ public int getToServiceId() {
+ return toServiceId;
+ }
+
+ /**
+ * @param fromCodeScheme the fromCodeScheme to set
+ */
+ public void setFromCodeScheme(int fromCodeScheme) {
+ this.fromCodeScheme = fromCodeScheme;
+ }
+
+ /**
+ * @return the fromCodeScheme
+ */
+ public int getFromCodeScheme() {
+ return fromCodeScheme;
+ }
+
+ /**
+ * @param toCodeScheme the toCodeScheme to set
+ */
+ public void setToCodeScheme(int toCodeScheme) {
+ this.toCodeScheme = toCodeScheme;
+ }
+
+ /**
+ * @return the toCodeScheme
+ */
+ public int getToCodeScheme() {
+ return toCodeScheme;
+ }
+
+ /**
+ * @param selected the selected to set
+ */
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ /**
+ * @return the selected
+ */
+ public boolean isSelected() {
+ return selected;
+ }
+
+ @Override
+ public String toString() {
+ return "SmsBroadcastConfigInfo: Id [" +
+ getFromServiceId() + "," + getToServiceId() + "] Code [" +
+ getFromCodeScheme() + "," + getToCodeScheme() + "] " +
+ (isSelected() ? "ENABLED" : "DISABLED");
+ }
+} \ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 867b719..f1207e4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -26,6 +26,7 @@ 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;
@@ -250,6 +251,12 @@ public class SmsMessage extends SmsMessageBase{
// TP-Data-Coding-Scheme
// Default encoding, uncompressed
+ // To test writing messages to the SIM card, change this value 0x00
+ // to 0x12, which means "bits 1 and 0 contain message class, and the
+ // class is 2". Note that this takes effect for the sender. In other
+ // words, messages sent by the phone with this change will end up on
+ // 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);
// (no TP-Validity-Period)
@@ -330,9 +337,20 @@ public class SmsMessage extends SmsMessageBase{
public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, short destinationPort, byte[] data,
boolean statusReportRequested) {
- if (data.length > (MAX_USER_DATA_BYTES - 7 /* UDH size */)) {
+
+ SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs();
+ portAddrs.destPort = destinationPort;
+ portAddrs.origPort = 0;
+ portAddrs.areEightBits = false;
+
+ SmsHeader smsHeader = new SmsHeader();
+ smsHeader.portAddrs = portAddrs;
+
+ byte[] smsHeaderData = SmsHeader.toByteArray(smsHeader);
+
+ if ((data.length + smsHeaderData.length + 1) > MAX_USER_DATA_BYTES) {
Log.e(LOG_TAG, "SMS data message may only contain "
- + (MAX_USER_DATA_BYTES - 7) + " bytes");
+ + (MAX_USER_DATA_BYTES - smsHeaderData.length - 1) + " bytes");
return null;
}
@@ -348,21 +366,12 @@ public class SmsMessage extends SmsMessageBase{
// (no TP-Validity-Period)
- // User data size
- bo.write(data.length + 7);
-
- // User data header size
- bo.write(0x06); // header is 6 octets
+ // Total size
+ bo.write(data.length + smsHeaderData.length + 1);
- // User data header, indicating the destination port
- bo.write(SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT); // port
- // addressing
- // header
- bo.write(0x04); // each port is 2 octets
- bo.write((destinationPort >> 8) & 0xFF); // MSB of destination port
- bo.write(destinationPort & 0xFF); // LSB of destination port
- bo.write(0x00); // MSB of originating port
- bo.write(0x00); // LSB of originating port
+ // User data header
+ bo.write(smsHeaderData.length);
+ bo.write(smsHeaderData, 0, smsHeaderData.length);
// User data
bo.write(data, 0, data.length);
@@ -556,13 +565,14 @@ public class SmsMessage extends SmsMessageBase{
int offset = cur;
int userDataLength = pdu[offset++] & 0xff;
int headerSeptets = 0;
+ int userDataHeaderLength = 0;
if (hasUserDataHeader) {
- int userDataHeaderLength = pdu[offset++] & 0xff;
+ userDataHeaderLength = pdu[offset++] & 0xff;
byte[] udh = new byte[userDataHeaderLength];
System.arraycopy(pdu, offset, udh, 0, userDataHeaderLength);
- userDataHeader = SmsHeader.parse(udh);
+ userDataHeader = SmsHeader.fromByteArray(udh);
offset += userDataHeaderLength;
int headerBits = (userDataHeaderLength + 1) * 8;
@@ -571,19 +581,34 @@ public class SmsMessage extends SmsMessageBase{
mUserDataSeptetPadding = (headerSeptets * 7) - headerBits;
}
- /*
- * Here we just create the user data length to be the remainder of
- * the pdu minus the user data hearder. This is because the count
- * could mean the number of uncompressed sepets if the userdata is
- * encoded in 7-bit.
- */
- userData = new byte[pdu.length - offset];
+ int bufferLen;
+ if (dataInSeptets) {
+ /*
+ * 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.
+ */
+ bufferLen = pdu.length - offset;
+ } else {
+ /*
+ * userDataLength is the count of octets, so just subtract the
+ * user data header.
+ */
+ bufferLen = userDataLength - (hasUserDataHeader ? (userDataHeaderLength + 1) : 0);
+ if (bufferLen < 0) {
+ bufferLen = 0;
+ }
+ }
+
+ userData = new byte[bufferLen];
System.arraycopy(pdu, offset, userData, 0, userData.length);
cur = offset;
if (dataInSeptets) {
// Return the number of septets
- return userDataLength - headerSeptets;
+ int count = userDataLength - headerSeptets;
+ // If count < 0, return 0 (means UDL was probably incorrect)
+ return count < 0 ? 0 : count;
} else {
// Return the number of octets
return userData.length;
@@ -613,8 +638,6 @@ public class SmsMessage extends SmsMessageBase{
/**
* Returns an object representing the user data headers
*
- * @return an object representing the user data headers
- *
* {@hide}
*/
SmsHeader getUserDataHeader() {
@@ -717,6 +740,44 @@ public class SmsMessage extends SmsMessageBase{
}
}
+ /**
+ * Calculate the number of septets needed to encode the message.
+ *
+ * @param msgBody the message to encode
+ * @param use7bitOnly ignore (but still count) illegal characters if true
+ * @return TextEncodingDetails
+ */
+ public static TextEncodingDetails calculateLength(CharSequence msgBody,
+ boolean use7bitOnly) {
+ TextEncodingDetails ted = new TextEncodingDetails();
+ try {
+ int septets = GsmAlphabet.countGsmSeptets(msgBody, !use7bitOnly);
+ ted.codeUnitCount = septets;
+ if (septets > MAX_USER_DATA_SEPTETS) {
+ ted.msgCount = (septets / MAX_USER_DATA_SEPTETS_WITH_HEADER) + 1;
+ ted.codeUnitsRemaining = MAX_USER_DATA_SEPTETS_WITH_HEADER
+ - (septets % MAX_USER_DATA_SEPTETS_WITH_HEADER);
+ } else {
+ ted.msgCount = 1;
+ ted.codeUnitsRemaining = MAX_USER_DATA_SEPTETS - septets;
+ }
+ ted.codeUnitSize = ENCODING_7BIT;
+ } catch (EncodeException ex) {
+ int octets = msgBody.length() * 2;
+ ted.codeUnitCount = msgBody.length();
+ if (octets > MAX_USER_DATA_BYTES) {
+ ted.msgCount = (octets / MAX_USER_DATA_BYTES_WITH_HEADER) + 1;
+ ted.codeUnitsRemaining = (MAX_USER_DATA_BYTES_WITH_HEADER
+ - (octets % MAX_USER_DATA_BYTES_WITH_HEADER))/2;
+ } else {
+ ted.msgCount = 1;
+ ted.codeUnitsRemaining = (MAX_USER_DATA_BYTES - octets)/2;
+ }
+ ted.codeUnitSize = ENCODING_16BIT;
+ }
+ return ted;
+ }
+
/** {@inheritDoc} */
public int getProtocolIdentifier() {
return protocolIdentifier;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java b/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
index 11ad52d..e68655e 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
@@ -34,7 +34,7 @@ public class SuppServiceNotification {
public int type;
/** TS 27.007 7.17 "number" (MT only) */
public String number;
-
+
static public final int MO_CODE_UNCONDITIONAL_CF_ACTIVE = 0;
static public final int MO_CODE_SOME_CF_ACTIVE = 1;
static public final int MO_CODE_CALL_FORWARDED = 2;
@@ -44,7 +44,7 @@ public class SuppServiceNotification {
static public final int MO_CODE_INCOMING_CALLS_BARRED = 6;
static public final int MO_CODE_CLIR_SUPPRESSION_REJECTED = 7;
static public final int MO_CODE_CALL_DEFLECTED = 8;
-
+
static public final int MT_CODE_FORWARDED_CALL = 0;
static public final int MT_CODE_CUG_CALL = 1;
static public final int MT_CODE_CALL_ON_HOLD = 2;
diff --git a/telephony/java/com/android/internal/telephony/gsm/package.html b/telephony/java/com/android/internal/telephony/gsm/package.html
index 4b1cf99..fed8399 100755
--- a/telephony/java/com/android/internal/telephony/gsm/package.html
+++ b/telephony/java/com/android/internal/telephony/gsm/package.html
@@ -1,6 +1,6 @@
<HTML>
<BODY>
-Provides classes to control or read data from GSM phones.
+Provides classes to control or read data from GSM phones.
@hide
</BODY>
</HTML>
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java b/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
index c002729..58f1f97 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
@@ -24,15 +24,15 @@ package com.android.internal.telephony.gsm.stk;
public interface AppInterface {
/*
- * Intent's actions which are broadcasted by the Telephony once a new STK
+ * Intent's actions which are broadcasted by the Telephony once a new STK
* proactive command, session end arrive.
*/
- public static final String STK_CMD_ACTION =
+ public static final String STK_CMD_ACTION =
"android.intent.action.stk.command";
- public static final String STK_SESSION_END_ACTION =
+ public static final String STK_SESSION_END_ACTION =
"android.intent.action.stk.session_end";
-
- /*
+
+ /*
* Callback function from app to telephony to pass a result code and user's
* input back to the SIM.
*/
@@ -44,20 +44,20 @@ public interface AppInterface {
* implementation should support those.
*/
public static enum CommandType {
- DISPLAY_TEXT(0x21),
- GET_INKEY(0x22),
- GET_INPUT(0x23),
- LAUNCH_BROWSER(0x15),
- PLAY_TONE(0x20),
- REFRESH(0x01),
- SELECT_ITEM(0x24),
- SEND_SS(0x11),
- SEND_USSD(0x12),
- SEND_SMS(0x13),
- SEND_DTMF(0x14),
- SET_UP_EVENT_LIST(0x05),
- SET_UP_IDLE_MODE_TEXT(0x28),
- SET_UP_MENU(0x25),
+ DISPLAY_TEXT(0x21),
+ GET_INKEY(0x22),
+ GET_INPUT(0x23),
+ LAUNCH_BROWSER(0x15),
+ PLAY_TONE(0x20),
+ REFRESH(0x01),
+ SELECT_ITEM(0x24),
+ SEND_SS(0x11),
+ SEND_USSD(0x12),
+ SEND_SMS(0x13),
+ SEND_DTMF(0x14),
+ SET_UP_EVENT_LIST(0x05),
+ SET_UP_IDLE_MODE_TEXT(0x28),
+ SET_UP_MENU(0x25),
SET_UP_CALL(0x10);
private int mValue;
@@ -72,7 +72,7 @@ public interface AppInterface {
/**
* Create a CommandType object.
- *
+ *
* @param value Integer value to be converted to a CommandType object.
* @return CommandType object whose "Type of Command" value is {@code
* value}. If no CommandType object has that value, null is
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
index 168361a..e81ff98 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
@@ -36,17 +36,17 @@ class CommandDetails extends ValueObject implements Parcelable {
public ComprehensionTlvTag getTag() {
return ComprehensionTlvTag.COMMAND_DETAILS;
}
-
+
CommandDetails() {
}
public boolean compareTo(CommandDetails other) {
return (this.compRequired == other.compRequired &&
this.commandNumber == other.commandNumber &&
- this.commandQualifier == other.commandQualifier &&
+ this.commandQualifier == other.commandQualifier &&
this.typeOfCommand == other.typeOfCommand);
}
-
+
public CommandDetails(Parcel in) {
compRequired = true;
commandNumber = in.readInt();
@@ -60,7 +60,7 @@ class CommandDetails extends ValueObject implements Parcelable {
dest.writeInt(commandQualifier);
}
- public static final Parcelable.Creator<CommandDetails> CREATOR =
+ public static final Parcelable.Creator<CommandDetails> CREATOR =
new Parcelable.Creator<CommandDetails>() {
public CommandDetails createFromParcel(Parcel in) {
return new CommandDetails(in);
@@ -85,7 +85,7 @@ class DeviceIdentities extends ValueObject {
}
}
-// Container class to hold icon identifier value.
+// Container class to hold icon identifier value.
class IconId extends ValueObject {
int recordNumber;
boolean selfExplanatory;
@@ -95,7 +95,7 @@ class IconId extends ValueObject {
}
}
-// Container class to hold item icon identifier list value.
+// Container class to hold item icon identifier list value.
class ItemsIconId extends ValueObject {
int [] recordNumbers;
boolean selfExplanatory;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
index a27c582..3da652f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
@@ -158,7 +158,7 @@ class GetInputParams extends CommandParams {
this.input = input;
}
- boolean setIcon(Bitmap icon) {
+ boolean setIcon(Bitmap icon) {
if (icon != null && input != null) {
input.icon = icon;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
index 06b36a4..bfde616 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
@@ -635,7 +635,7 @@ class CommandParamsFactory extends Handler {
/**
* Processes SET_UP_EVENT_LIST proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved.
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
index 4f746ac..ffde6a3 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
@@ -33,7 +33,7 @@ class ComprehensionTlv {
private int mLength;
private int mValueIndex;
private byte[] mRawValue;
-
+
/**
* Constructor. Private on purpose. Use
* {@link #decodeMany(byte[], int) decodeMany} or
@@ -165,9 +165,9 @@ class ComprehensionTlv {
} else {
throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
}
-
+
return new ComprehensionTlv(tag, cr, length, data, curIndex);
-
+
} catch (IndexOutOfBoundsException e) {
throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java b/telephony/java/com/android/internal/telephony/gsm/stk/Input.java
index 1f0d971..19f724b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/Input.java
@@ -21,13 +21,13 @@ import android.os.Parcel;
import android.os.Parcelable;
/**
- * Container class for STK GET INPUT, GET IN KEY commands parameters.
+ * Container class for STK GET INPUT, GET IN KEY commands parameters.
*
*/
public class Input implements Parcelable {
public String text;
public String defaultText;
- public Bitmap icon;
+ public Bitmap icon;
public int minLen;
public int maxLen;
public boolean ucs2;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java b/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
index 40a6b37..331f69d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
@@ -24,7 +24,7 @@ import java.util.ArrayList;
import java.util.List;
/**
- * Container class for STK menu (SET UP MENU, SELECT ITEM) parameters.
+ * Container class for STK menu (SET UP MENU, SELECT ITEM) parameters.
*
*/
public class Menu implements Parcelable {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java b/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
index 810afd2..afd1bba 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2006-2007 Google Inc.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -56,7 +56,7 @@ class GetInkeyInputResponseData extends ResponseData {
private boolean mIsYesNo;
private boolean mYesNoResponse;
public String mInData;
-
+
// GetInKey Yes/No response characters constants.
protected static final byte GET_INKEY_YES = 0x01;
protected static final byte GET_INKEY_NO = 0x00;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
index 62a778e..5425a43 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
@@ -20,9 +20,9 @@ import android.os.Parcel;
import android.os.Parcelable;
/**
- * Class used to pass STK messages from telephony to application. Application
+ * Class used to pass STK messages from telephony to application. Application
* should call getXXX() to get commands's specific values.
- *
+ *
*/
public class StkCmdMessage implements Parcelable {
// members
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
index f6e5685..bd6bc8f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
@@ -30,7 +30,7 @@ public abstract class StkLog {
Log.d("STK", className.substring(className.lastIndexOf('.') + 1) + ": "
+ msg);
}
-
+
public static void d(String caller, String msg) {
if (!DEBUG) {
return;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
index 3de14f0..9268037 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
@@ -25,8 +25,6 @@ import android.os.Message;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.EncodeException;
-import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.gsm.SimCard;
import com.android.internal.telephony.gsm.SIMFileHandler;
import com.android.internal.telephony.gsm.SIMRecords;
@@ -34,8 +32,6 @@ import com.android.internal.telephony.gsm.SIMRecords;
import android.util.Config;
import java.io.ByteArrayOutputStream;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
/**
* Enumeration for representing the tag value of COMPREHENSION-TLV objects. If
@@ -119,7 +115,7 @@ public class StkService extends Handler implements AppInterface {
// Class members
private static SIMRecords mSimRecords;
-
+
// Service members.
private static StkService sInstance;
private CommandsInterface mCmdIf;
@@ -174,6 +170,9 @@ public class StkService extends Handler implements AppInterface {
// Register for SIM ready event.
mSimRecords.registerForRecordsLoaded(this, MSG_ID_SIM_LOADED, null);
+
+ mCmdIf.reportStkServiceIsRunning(null);
+ StkLog.d(this, "StkService: is running");
}
public void dispose() {
@@ -184,9 +183,6 @@ public class StkService extends Handler implements AppInterface {
mCmdIf.unSetOnStkCallSetUp(this);
this.removeCallbacksAndMessages(null);
-
- //removing instance
- sInstance = null;
}
protected void finalize() {
@@ -450,7 +446,7 @@ public class StkService extends Handler implements AppInterface {
}
/**
- * Used for instantiating the Service from the GsmPhone constructor.
+ * Used for instantiating/updating the Service from the GsmPhone constructor.
*
* @param ci CommandsInterface object
* @param sr SIMRecords object
@@ -560,15 +556,15 @@ public class StkService extends Handler implements AppInterface {
}
private void handleCmdResponse(StkResponseMessage resMsg) {
- // Make sure the response details match the last valid command. An invalid
+ // Make sure the response details match the last valid command. An invalid
// response is a one that doesn't have a corresponding proactive command
- // and sending it can "confuse" the baseband/ril.
- // One reason for out of order responses can be UI glitches. For example,
- // if the application launch an activity, and that activity is stored
+ // and sending it can "confuse" the baseband/ril.
+ // One reason for out of order responses can be UI glitches. For example,
+ // if the application launch an activity, and that activity is stored
// by the framework inside the history stack. That activity will be
- // available for relaunch using the latest application dialog
- // (long press on the home button). Relaunching that activity can send
- // the same command's result again to the StkService and can cause it to
+ // available for relaunch using the latest application dialog
+ // (long press on the home button). Relaunching that activity can send
+ // the same command's result again to the StkService and can cause it to
// get out of sync with the SIM.
if (!validateResponse(resMsg)) {
return;
@@ -621,7 +617,7 @@ public class StkService extends Handler implements AppInterface {
mCmdIf.handleCallSetupRequestFromSim(resMsg.usersConfirm, null);
// No need to send terminal response for SET UP CALL. The user's
// confirmation result is send back using a dedicated ril message
- // invoked by the CommandInterface call above.
+ // invoked by the CommandInterface call above.
mCurrntCmd = null;
return;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java b/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
index bbc925e..90cc6c1 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
@@ -20,7 +20,7 @@ import android.os.Parcel;
import android.os.Parcelable;
/**
- * Container class for PlayTone commands parameters.
+ * Container class for PlayTone commands parameters.
*
*/
public class ToneSettings implements Parcelable {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java b/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
index 8c8f977..09a860e 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2006-2007 Google Inc.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -28,7 +28,7 @@ abstract class ValueParser {
/**
* Search for a Command Details object from a list.
- *
+ *
* @param ctlvs List of ComprehensionTlv objects used for search
* @return An CtlvCommandDetails object found from the objects. If no
* Command Details object is found, ResultException is thrown.
@@ -53,7 +53,7 @@ abstract class ValueParser {
/**
* Search for a Device Identities object from a list.
- *
+ *
* @param ctlvs List of ComprehensionTlv objects used for search
* @return An CtlvDeviceIdentities object found from the objects. If no
* Command Details object is found, ResultException is thrown.
@@ -77,7 +77,7 @@ abstract class ValueParser {
/**
* Retrieves Duration information from the Duration COMPREHENSION-TLV
* object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return A Duration object
* @throws ResultException
@@ -100,7 +100,7 @@ abstract class ValueParser {
/**
* Retrieves Item information from the COMPREHENSION-TLV object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return An Item
* @throws ResultException
@@ -130,7 +130,7 @@ abstract class ValueParser {
/**
* Retrieves Item id information from the COMPREHENSION-TLV object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return An Item id
* @throws ResultException
@@ -152,7 +152,7 @@ abstract class ValueParser {
/**
* Retrieves icon id from an Icon Identifier COMPREHENSION-TLV object
- *
+ *
* @param ctlv An Icon Identifier COMPREHENSION-TLV object
* @return IconId instance
* @throws ResultException
@@ -175,7 +175,7 @@ abstract class ValueParser {
/**
* Retrieves item icons id from an Icon Identifier List COMPREHENSION-TLV
* object
- *
+ *
* @param ctlv An Item Icon List Identifier COMPREHENSION-TLV object
* @return ItemsIconId instance
* @throws ResultException
@@ -206,7 +206,7 @@ abstract class ValueParser {
/**
* Retrieves text attribute information from the Text Attribute
* COMPREHENSION-TLV object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return A list of TextAttribute objects
* @throws ResultException
@@ -266,7 +266,7 @@ abstract class ValueParser {
/**
* Retrieves alpha identifier from an Alpha Identifier COMPREHENSION-TLV
* object.
- *
+ *
* @param ctlv An Alpha Identifier COMPREHENSION-TLV object
* @return String corresponding to the alpha identifier
* @throws ResultException
@@ -290,7 +290,7 @@ abstract class ValueParser {
/**
* Retrieves text from the Text COMPREHENSION-TLV object, and decodes it
* into a Java String.
- *
+ *
* @param ctlv A Text COMPREHENSION-TLV object
* @return A Java String object decoded from the Text object
* @throws ResultException
diff --git a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java b/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java
index 25d2026..b116c35 100644
--- a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java
+++ b/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java
@@ -75,7 +75,7 @@ class LineReader
* Returns NULL on EOF
*/
- String
+ String
getNextLine(boolean ctrlZ)
{
int i = 0;
@@ -131,7 +131,7 @@ class InterpreterEx extends Exception
String result;
}
-public class ModelInterpreter
+public class ModelInterpreter
implements Runnable, SimulatedRadioControl
{
static final int MAX_CALLS = 6;
@@ -153,14 +153,14 @@ public class ModelInterpreter
SimulatedGsmCallState simulatedCallState;
HandlerThread mHandlerThread;
-
+
int pausedResponseCount;
Object pausedResponseMonitor = new Object();
//***** Events
static final int PROGRESS_CALL_STATE = 1;
-
+
//***** Constructor
public
@@ -181,7 +181,7 @@ public class ModelInterpreter
ss.bind(sa);
init();
- }
+ }
private void
init()
@@ -190,7 +190,7 @@ public class ModelInterpreter
mHandlerThread = new HandlerThread("ModelInterpreter");
mHandlerThread.start();
Looper looper = mHandlerThread.getLooper();
- simulatedCallState = new SimulatedGsmCallState(looper);
+ simulatedCallState = new SimulatedGsmCallState(looper);
}
//***** Runnable Implementation
@@ -204,7 +204,7 @@ public class ModelInterpreter
try {
s = ss.accept();
} catch (java.io.IOException ex) {
- Log.w(LOG_TAG,
+ Log.w(LOG_TAG,
"IOException on socket.accept(); stopping", ex);
return;
}
@@ -213,15 +213,15 @@ public class ModelInterpreter
in = s.getInputStream();
out = s.getOutputStream();
} catch (java.io.IOException ex) {
- Log.w(LOG_TAG,
+ Log.w(LOG_TAG,
"IOException on accepted socket(); re-listening", ex);
continue;
}
Log.i(LOG_TAG, "New connection accepted");
}
-
-
+
+
lineReader = new LineReader (in);
println ("Welcome");
@@ -271,14 +271,14 @@ public class ModelInterpreter
//***** Instance Methods
-
+
/** Start the simulated phone ringing */
public void
triggerRing(String number)
{
synchronized (this) {
boolean success;
-
+
success = simulatedCallState.triggerRing(number);
if (success) {
@@ -307,10 +307,10 @@ public class ModelInterpreter
*/
public void
setAutoProgressConnectingCall(boolean b)
- {
+ {
simulatedCallState.setAutoProgressConnectingCall(b);
}
-
+
public void
setNextDialFailImmediately(boolean b)
{
@@ -321,7 +321,7 @@ public class ModelInterpreter
{
//FIXME implement
}
-
+
/** hangup ringing, dialing, or actuve calls */
public void
@@ -373,7 +373,7 @@ public class ModelInterpreter
public void triggerSsn(int a, int b) {}
public void triggerIncomingUssd(String statusCode, String message) {}
-
+
public void
triggerIncomingSMS(String message)
{
@@ -386,7 +386,7 @@ public class ModelInterpreter
// source address: +18005551212
pdu.append("918100551521F0");
-
+
// protocol ID and data coding scheme
pdu.append("0000");
@@ -421,7 +421,7 @@ public class ModelInterpreter
pausedResponseMonitor.notifyAll();
}
}
- }
+ }
//***** Private Instance Methods
@@ -429,11 +429,11 @@ public class ModelInterpreter
onAnswer() throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.onAnswer();
if (!success) {
- throw new InterpreterEx("ERROR");
+ throw new InterpreterEx("ERROR");
}
}
@@ -445,7 +445,7 @@ public class ModelInterpreter
success = simulatedCallState.onAnswer();
if (!success) {
- throw new InterpreterEx("ERROR");
+ throw new InterpreterEx("ERROR");
}
finalResponse = "NO CARRIER";
@@ -471,12 +471,12 @@ public class ModelInterpreter
throw new InterpreterEx("ERROR");
}
}
-
+
private void
releaseHeldOrUDUB() throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.releaseHeldOrUDUB();
if (!success) {
@@ -488,19 +488,19 @@ public class ModelInterpreter
releaseActiveAcceptHeldOrWaiting() throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.releaseActiveAcceptHeldOrWaiting();
if (!success) {
throw new InterpreterEx("ERROR");
}
- }
+ }
private void
switchActiveAndHeldOrWaiting() throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.switchActiveAndHeldOrWaiting();
if (!success) {
@@ -512,7 +512,7 @@ public class ModelInterpreter
separateCall(int index) throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.separateCall(index);
if (!success) {
@@ -524,7 +524,7 @@ public class ModelInterpreter
conference() throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.conference();
if (!success) {
@@ -536,7 +536,7 @@ public class ModelInterpreter
onDial(String command) throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.onDial(command.substring(1));
if (!success) {
@@ -566,7 +566,7 @@ public class ModelInterpreter
println("+CMGS: 1");
}
-
+
void
processLine (String line) throws InterpreterEx
{
@@ -645,8 +645,8 @@ public class ModelInterpreter
}
***/
}
-
- void
+
+ void
println (String s)
{
synchronized(this) {
@@ -663,7 +663,7 @@ public class ModelInterpreter
}
}
- void
+ void
print (String s)
{
synchronized(this) {
@@ -714,8 +714,8 @@ public class ModelInterpreter
{"+CIMI", "320720000000000\r"},
{"+CSCS=?", "+CSCS: (\"HEX\",\"UCS2\")\r"},
{"+CFUN?", "+CFUN: 1\r"},
- {"+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
- "+COPS: 0,0,\"Android\"\r"
+ {"+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
+ "+COPS: 0,0,\"Android\"\r"
+ "+COPS: 0,1,\"Android\"\r"
+ "+COPS: 0,2,\"310995\"\r"},
{"+CREG?", "+CREG: 2,5, \"0113\", \"6614\"\r"},
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
index 5c69017..22adc19 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -26,8 +26,9 @@ import android.util.Log;
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.gsm.CallFailCause;
-import com.android.internal.telephony.gsm.PDPContextState;
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.Phone;
@@ -59,7 +60,7 @@ public final class SimulatedCommands extends BaseCommands
private final static String SIM_PUK2_CODE = "87654321";
//***** Instance Variables
-
+
SimulatedGsmCallState simulatedCallState;
HandlerThread mHandlerThread;
SimLockState mSimLockedState;
@@ -79,7 +80,7 @@ public final class SimulatedCommands extends BaseCommands
ArrayList<Message> pausedResponses = new ArrayList<Message>();
int nextCallFailCause = CallFailCause.NORMAL_CLEARING;
-
+
//***** Constructor
public
@@ -88,9 +89,9 @@ public final class SimulatedCommands extends BaseCommands
mHandlerThread = new HandlerThread("SimulatedCommands");
mHandlerThread.start();
Looper looper = mHandlerThread.getLooper();
-
+
simulatedCallState = new SimulatedGsmCallState(looper);
-
+
setRadioState(RadioState.RADIO_OFF);
mSimLockedState = INITIAL_LOCK_STATE;
mSimLockEnabled = (mSimLockedState != SimLockState.NONE);
@@ -353,11 +354,11 @@ public final class SimulatedCommands extends BaseCommands
public void
setSuppServiceNotifications(boolean enable, Message result) {
resultSuccess(result, null);
-
+
if (enable && mSsnNotifyOn) {
Log.w(LOG_TAG, "Supp Service Notifications already enabled!");
}
-
+
mSsnNotifyOn = enable;
}
@@ -465,7 +466,7 @@ public final class SimulatedCommands extends BaseCommands
unimplemented(result);
}
- /**
+ /**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -479,13 +480,13 @@ public final class SimulatedCommands extends BaseCommands
resultSuccess(result, simulatedCallState.getDriverCalls());
} else {
//Log.i("GSM", "[SimCmds] getCurrentCalls: SIM not ready!");
- resultFail(result,
+ resultFail(result,
new CommandException(
CommandException.Error.RADIO_NOT_AVAILABLE));
}
}
- /**
+ /**
* @deprecated
*/
public void getPDPContextList(Message result) {
@@ -497,13 +498,13 @@ public final class SimulatedCommands extends BaseCommands
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
- * ar.result contains a List of PDPContextState
+ * ar.result contains a List of DataCallState
*/
public void getDataCallList(Message result) {
- resultSuccess(result, new ArrayList<PDPContextState>(0));
+ resultSuccess(result, new ArrayList<DataCallState>(0));
}
- /**
+ /**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -520,7 +521,7 @@ public final class SimulatedCommands extends BaseCommands
resultSuccess(result, null);
}
- /**
+ /**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -531,7 +532,7 @@ public final class SimulatedCommands extends BaseCommands
resultSuccess(result, "012345678901234");
}
- /**
+ /**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -542,7 +543,7 @@ public final class SimulatedCommands extends BaseCommands
resultSuccess(result, "012345678901234");
}
- /**
+ /**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -553,7 +554,7 @@ public final class SimulatedCommands extends BaseCommands
resultSuccess(result, "99");
}
- /**
+ /**
* Hang up one individual connection.
* returned message
* retMsg.obj = AsyncResult ar
@@ -566,7 +567,7 @@ public final class SimulatedCommands extends BaseCommands
*/
public void hangupConnection (int gsmIndex, Message result) {
boolean success;
-
+
success = simulatedCallState.onChld('1', (char)('0'+gsmIndex));
if (!success){
@@ -588,7 +589,7 @@ public final class SimulatedCommands extends BaseCommands
*/
public void hangupWaitingOrBackground (Message result) {
boolean success;
-
+
success = simulatedCallState.onChld('0', '\0');
if (!success){
@@ -600,7 +601,7 @@ public final class SimulatedCommands extends BaseCommands
/**
* 3GPP 22.030 6.5.5
- * "Releases all active calls (if any exist) and accepts
+ * "Releases all active calls (if any exist) and accepts
* the other (held or waiting) call."
*
* ar.exception carries exception on failure
@@ -609,7 +610,7 @@ public final class SimulatedCommands extends BaseCommands
*/
public void hangupForegroundResumeBackground (Message result) {
boolean success;
-
+
success = simulatedCallState.onChld('1', '\0');
if (!success){
@@ -621,7 +622,7 @@ public final class SimulatedCommands extends BaseCommands
/**
* 3GPP 22.030 6.5.5
- * "Places all active calls (if any exist) on hold and accepts
+ * "Places all active calls (if any exist) on hold and accepts
* the other (held or waiting) call."
*
* ar.exception carries exception on failure
@@ -630,7 +631,7 @@ public final class SimulatedCommands extends BaseCommands
*/
public void switchWaitingOrHoldingAndActive (Message result) {
boolean success;
-
+
success = simulatedCallState.onChld('2', '\0');
if (!success){
@@ -647,10 +648,10 @@ public final class SimulatedCommands extends BaseCommands
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result is null on success and failure
- */
+ */
public void conference (Message result) {
boolean success;
-
+
success = simulatedCallState.onChld('3', '\0');
if (!success){
@@ -682,7 +683,7 @@ public final class SimulatedCommands extends BaseCommands
/**
* 3GPP 22.030 6.5.5
- * "Places all active calls on hold except call X with which
+ * "Places all active calls on hold except call X with which
* communication shall be supported."
*/
public void separateConnection (int gsmIndex, Message result) {
@@ -703,10 +704,10 @@ public final class SimulatedCommands extends BaseCommands
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result is null on success and failure
- */
+ */
public void acceptCall (Message result) {
boolean success;
-
+
success = simulatedCallState.onAnswer();
if (!success){
@@ -716,15 +717,15 @@ 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.result is null on success and failure
- */
+ */
public void rejectCall (Message result) {
boolean success;
-
+
success = simulatedCallState.onChld('0', '\0');
if (!success){
@@ -734,7 +735,7 @@ public final class SimulatedCommands extends BaseCommands
}
}
- /**
+ /**
* cause code returned as Integer in Message.obj.response
* Returns integer cause code defined in TS 24.008
* Annex H or closest approximation.
@@ -765,11 +766,11 @@ public final class SimulatedCommands extends BaseCommands
public void getMute (Message result) {unimplemented(result);}
- /**
+ /**
* response.obj is an AsyncResult
* response.obj.result is an int[2]
- * response.obj.result[0] is received signal strength (0-31, 99)
- * response.obj.result[1] is bit error rate (0-7, 99)
+ * response.obj.result[0] is received signal strength (0-31, 99)
+ * response.obj.result[1] is bit error rate (0-7, 99)
* as defined in TS 27.007 8.5
*/
public void getSignalStrength (Message result) {
@@ -893,7 +894,7 @@ public final class SimulatedCommands extends BaseCommands
* response.obj.result[0] is long alpha or null if unregistered
* response.obj.result[1] is short alpha or null if unregistered
* response.obj.result[2] is numeric or null if unregistered
- */
+ */
public void getOperator(Message result) {
String[] ret = new String[3];
@@ -908,7 +909,7 @@ public final class SimulatedCommands extends BaseCommands
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result is null on success and failure
- */
+ */
public void sendDtmf(char c, Message result) {
resultSuccess(result, null);
}
@@ -932,10 +933,19 @@ public final class SimulatedCommands extends BaseCommands
}
/**
+ * ar.exception carries exception on failure
+ * ar.userObject contains the orignal value of result.obj
+ * ar.result is null on success and failure
+ */
+ public void sendBurstDtmf(String dtmfString, Message result) {
+ resultSuccess(result, null);
+ }
+
+ /**
* smscPDU is smsc address in PDU form GSM BCD format prefixed
* by a length byte (as expected by TS 27.005) or NULL for default SMSC
* pdu is SMS in PDU format as an ASCII hex string
- * less the SMSC address
+ * less the SMSC address
*/
public void sendSMS (String smscPDU, String pdu, Message result) {unimplemented(result);}
@@ -1009,6 +1019,14 @@ public final class SimulatedCommands extends BaseCommands
unimplemented(result);
}
+ public void reportSmsMemoryStatus(boolean available, Message result) {
+ unimplemented(result);
+ }
+
+ public void reportStkServiceIsRunning(Message result) {
+ resultSuccess(result, null);
+ }
+
private boolean isSimLocked() {
if (mSimLockedState != SimLockState.NONE) {
return true;
@@ -1032,16 +1050,16 @@ public final class SimulatedCommands extends BaseCommands
}
- public void acknowledgeLastIncomingSMS(boolean success, Message result) {
+ public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
unimplemented(result);
}
- public void acknowledgeLastIncomingCdmaSms(boolean success, Message result) {
+ public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
unimplemented(result);
}
- /**
- * parameters equivilient to 27.007 AT+CRSM command
+ /**
+ * parameters equivilient to 27.007 AT+CRSM command
* response.obj will be an AsyncResult
* response.obj.userObj will be a SimIoResult on success
*/
@@ -1052,7 +1070,7 @@ public final class SimulatedCommands extends BaseCommands
/**
* (AsyncResult)response.obj).result is an int[] with element [0] set to
- * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
+ * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
*
* @param response is callback message
*/
@@ -1063,46 +1081,46 @@ public final class SimulatedCommands extends BaseCommands
* response.obj will be a an int[2]
*
* response.obj[0] will be TS 27.007 +CLIR parameter 'n'
- * 0 presentation indicator is used according to the subscription of the CLIR service
- * 1 CLIR invocation
- * 2 CLIR suppression
+ * 0 presentation indicator is used according to the subscription of the CLIR service
+ * 1 CLIR invocation
+ * 2 CLIR suppression
*
* response.obj[1] will be TS 27.007 +CLIR parameter 'm'
- * 0 CLIR not provisioned
- * 1 CLIR provisioned in permanent mode
- * 2 unknown (e.g. no network, etc.)
- * 3 CLIR temporary mode presentation restricted
- * 4 CLIR temporary mode presentation allowed
+ * 0 CLIR not provisioned
+ * 1 CLIR provisioned in permanent mode
+ * 2 unknown (e.g. no network, etc.)
+ * 3 CLIR temporary mode presentation restricted
+ * 4 CLIR temporary mode presentation allowed
*/
public void getCLIR(Message result) {unimplemented(result);}
-
+
/**
* clirMode is one of the CLIR_* constants above
*
* response.obj is null
*/
-
+
public void setCLIR(int clirMode, Message result) {unimplemented(result);}
/**
* (AsyncResult)response.obj).result is an int[] with element [0] set to
- * 0 for disabled, 1 for enabled.
+ * 0 for disabled, 1 for enabled.
*
* @param serviceClass is a sum of SERVICE_CLASS_*
* @param response is callback message
*/
-
+
public void queryCallWaiting(int serviceClass, Message response) {
unimplemented(response);
}
-
+
/**
* @param enable is true to enable, false to disable
* @param serviceClass is a sum of SERVICE_CLASS_*
* @param response is callback message
*/
-
+
public void setCallWaiting(boolean enable, int serviceClass,
Message response) {
unimplemented(response);
@@ -1111,9 +1129,9 @@ public final class SimulatedCommands extends BaseCommands
/**
* @param action is one of CF_ACTION_*
* @param cfReason is one of CF_REASON_*
- * @param serviceClass is a sum of SERVICE_CLASSS_*
+ * @param serviceClass is a sum of SERVICE_CLASSS_*
*/
- public void setCallForward(int action, int cfReason, int serviceClass,
+ public void setCallForward(int action, int cfReason, int serviceClass,
String number, int timeSeconds, Message result) {unimplemented(result);}
/**
@@ -1121,14 +1139,14 @@ public final class SimulatedCommands extends BaseCommands
*
* ((AsyncResult)response.obj).result will be an array of
* CallForwardInfo's
- *
+ *
* An array of length 0 means "disabled for all codes"
*/
public void queryCallForwardStatus(int cfReason, int serviceClass,
String number, Message result) {unimplemented(result);}
public void setNetworkSelectionModeAutomatic(Message result) {unimplemented(result);}
-
+ public void exitEmergencyCallbackMode(Message result) {unimplemented(result);}
public void setNetworkSelectionModeManual(
String operatorNumeric, Message result) {unimplemented(result);}
@@ -1155,7 +1173,7 @@ public final class SimulatedCommands extends BaseCommands
public void getAvailableNetworks(Message result) {unimplemented(result);}
public void getBasebandVersion (Message result) {
- resultSuccess(result, "SimulatedCommands");
+ resultSuccess(result, "SimulatedCommands");
}
/**
@@ -1167,7 +1185,7 @@ public final class SimulatedCommands extends BaseCommands
public void triggerIncomingUssd(String statusCode, String message) {
if (mUSSDRegistrant != null) {
String[] result = {statusCode, message};
- mUSSDRegistrant.notifyResult(result);
+ mUSSDRegistrant.notifyResult(result);
}
}
@@ -1215,7 +1233,7 @@ public final class SimulatedCommands extends BaseCommands
//***** SimulatedRadioControl
-
+
/** Start the simulated phone ringing */
public void
triggerRing(String number) {
@@ -1249,9 +1267,9 @@ public final class SimulatedCommands extends BaseCommands
simulatedCallState.setNextDialFailImmediately(b);
}
- public void
+ public void
setNextCallFailCause(int gsmCause) {
- nextCallFailCause = gsmCause;
+ nextCallFailCause = gsmCause;
}
public void
@@ -1319,7 +1337,7 @@ public final class SimulatedCommands extends BaseCommands
private void unimplemented(Message result) {
if (result != null) {
- AsyncResult.forMessage(result).exception
+ AsyncResult.forMessage(result).exception
= new RuntimeException("Unimplemented");
if (pausedResponseCount > 0) {
@@ -1359,13 +1377,13 @@ public final class SimulatedCommands extends BaseCommands
unimplemented(response);
}
- public void
+ public void
getCDMASubscription(Message response) {
Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
unimplemented(response);
}
- public void
+ public void
setCdmaSubscription(int cdmaSubscriptionType, Message response) {
Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
unimplemented(response);
@@ -1403,7 +1421,7 @@ public final class SimulatedCommands extends BaseCommands
* @param serviceClass is a sum of SERVICE_CLASS_*
* @param response is callback message
*/
- public void setTTYModeEnabled(boolean enable, Message response) {
+ public void setTTYMode(int ttyMode, Message response) {
Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
unimplemented(response);
}
@@ -1411,12 +1429,12 @@ public final class SimulatedCommands extends BaseCommands
/**
* Query the TTY mode for the CDMA phone
* (AsyncResult)response.obj).result is an int[] with element [0] set to
- * 0 for disabled, 1 for enabled.
- *
+ * 0 for disabled, 1 for enabled.
+ *
* @param serviceClass is a sum of SERVICE_CLASS_*
* @param response is callback message
*/
- public void queryTTYModeEnabled(Message response) {
+ public void queryTTYMode(Message response) {
Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
unimplemented(response);
}
@@ -1436,19 +1454,36 @@ public final class SimulatedCommands extends BaseCommands
Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
}
- public void activateCdmaBroadcastSms(int activate, Message result) {
- // TODO Auto-generated method stub
+ public void setCdmaBroadcastActivation(boolean activate, Message response) {
+ unimplemented(response);
}
- public void getCdmaBroadcastConfig(Message result) {
- // TODO Auto-generated method stub
+ public void getCdmaBroadcastConfig(Message response) {
+ unimplemented(response);
}
- public void setCdmaBroadcastConfig(int[] configValuesArray, Message result) {
- // TODO Auto-generated method stub
+ public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
+ unimplemented(response);
}
+ public void forceDataDormancy(Message response) {
+ unimplemented(response);
+ }
+
+
+ public void setGsmBroadcastActivation(boolean activate, Message response) {
+ unimplemented(response);
+ }
+
+
+ public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
+ unimplemented(response);
+ }
+
+ public void getGsmBroadcastConfig(Message response) {
+ unimplemented(response);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java b/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
index 803735c..c6c301d 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
@@ -37,7 +37,7 @@ class CallInfo {
WAITING(5); // MT call only
State (int value) {this.value = value;}
-
+
private final int value;
public int value() {return value;};
};
@@ -73,7 +73,7 @@ class CallInfo {
String
toCLCCLine(int index) {
- return
+ return
"+CLCC: "
+ index + "," + (isMT ? "1" : "0") +","
+ state.value() + ",0," + (isMpty ? "1" : "0")
@@ -82,7 +82,7 @@ class CallInfo {
DriverCall
toDriverCall(int index) {
- DriverCall ret;
+ DriverCall ret;
ret = new DriverCall();
@@ -136,7 +136,7 @@ class SimulatedGsmCallState extends Handler {
private boolean autoProgressConnecting = true;
private boolean nextDialFailImmediately;
-
+
//***** Event Constants
@@ -169,8 +169,8 @@ class SimulatedGsmCallState extends Handler {
//***** Public Methods
- /**
- * Start the simulated phone ringing
+ /**
+ * Start the simulated phone ringing
* true if succeeded, false if failed
*/
public boolean
@@ -185,7 +185,7 @@ class SimulatedGsmCallState extends Handler {
if (call == null && empty < 0) {
empty = i;
- } else if (call != null
+ } else if (call != null
&& (call.state == CallInfo.State.INCOMING
|| call.state == CallInfo.State.WAITING)
) {
@@ -208,7 +208,7 @@ class SimulatedGsmCallState extends Handler {
if (isCallWaiting) {
calls[empty].state = CallInfo.State.WAITING;
}
-
+
}
return true;
}
@@ -225,11 +225,11 @@ class SimulatedGsmCallState extends Handler {
if (autoProgressConnecting) {
sendMessageDelayed(
- obtainMessage(EVENT_PROGRESS_CALL_STATE, call),
+ obtainMessage(EVENT_PROGRESS_CALL_STATE, call),
CONNECTING_PAUSE_MSEC);
}
break;
- } else if (call != null
+ } else if (call != null
&& call.state == CallInfo.State.ALERTING
) {
call.state = CallInfo.State.ACTIVE;
@@ -246,7 +246,7 @@ class SimulatedGsmCallState extends Handler {
for (int i = 0 ; i < calls.length ; i++) {
CallInfo call = calls[i];
- if (call != null && (call.state == CallInfo.State.DIALING
+ if (call != null && (call.state == CallInfo.State.DIALING
|| call.state == CallInfo.State.ALERTING)
) {
call.state = CallInfo.State.ACTIVE;
@@ -263,13 +263,13 @@ class SimulatedGsmCallState extends Handler {
setAutoProgressConnectingCall(boolean b) {
autoProgressConnecting = b;
}
-
+
public void
setNextDialFailImmediately(boolean b) {
nextDialFailImmediately = b;
}
- /**
+ /**
* hangup ringing, dialing, or active calls
* returns true if call was hung up, false if not
*/
@@ -283,7 +283,7 @@ class SimulatedGsmCallState extends Handler {
for (int i = 0 ; i < calls.length ; i++) {
CallInfo call = calls[i];
- if (call != null
+ if (call != null
&& (call.state == CallInfo.State.INCOMING
|| call.state == CallInfo.State.WAITING)
) {
@@ -295,7 +295,7 @@ class SimulatedGsmCallState extends Handler {
for (int i = 0 ; i < calls.length ; i++) {
CallInfo call = calls[i];
- if (call != null
+ if (call != null
&& (call.state == CallInfo.State.DIALING
|| call.state == CallInfo.State.ACTIVE
|| call.state == CallInfo.State.ALERTING)
@@ -308,7 +308,7 @@ class SimulatedGsmCallState extends Handler {
}
}
- /**
+ /**
* hangup holding calls
* returns true if call was hung up, false if not
*/
@@ -330,7 +330,7 @@ class SimulatedGsmCallState extends Handler {
}
}
- /**
+ /**
* hangup all
* returns true if call was hung up, false if not
*/
@@ -359,7 +359,7 @@ class SimulatedGsmCallState extends Handler {
for (int i = 0 ; i < calls.length ; i++) {
CallInfo call = calls[i];
- if (call != null
+ if (call != null
&& (call.state == CallInfo.State.INCOMING
|| call.state == CallInfo.State.WAITING)
) {
@@ -399,7 +399,7 @@ class SimulatedGsmCallState extends Handler {
return false;
}
}
-
+
switch (c0) {
case '0':
ret = releaseHeldOrUDUB();
@@ -442,7 +442,7 @@ class SimulatedGsmCallState extends Handler {
return ret;
}
-
+
public boolean
releaseHeldOrUDUB() {
boolean found = false;
@@ -493,8 +493,8 @@ class SimulatedGsmCallState extends Handler {
for (int i = 0 ; i < calls.length ; i++) {
CallInfo c = calls[i];
- if (c != null
- && (c.state == CallInfo.State.DIALING
+ if (c != null
+ && (c.state == CallInfo.State.DIALING
|| c.state == CallInfo.State.ALERTING)
) {
calls[i] = null;
@@ -531,7 +531,7 @@ class SimulatedGsmCallState extends Handler {
public boolean
switchActiveAndHeldOrWaiting() {
boolean hasHeld = false;
-
+
// first, are there held calls?
for (int i = 0 ; i < calls.length ; i++) {
CallInfo c = calls[i];
@@ -595,7 +595,7 @@ class SimulatedGsmCallState extends Handler {
}
return true;
- } catch (InvalidStateEx ex) {
+ } catch (InvalidStateEx ex) {
return false;
}
}
@@ -612,7 +612,7 @@ class SimulatedGsmCallState extends Handler {
if (c != null) {
countCalls++;
-
+
if (c.isConnecting()) {
return false;
}
@@ -624,7 +624,7 @@ class SimulatedGsmCallState extends Handler {
if (c != null) {
c.state = CallInfo.State.ACTIVE;
if (countCalls > 0) {
- c.isMpty = true;
+ c.isMpty = true;
}
}
}
@@ -659,12 +659,12 @@ class SimulatedGsmCallState extends Handler {
int freeSlot = -1;
Log.d("GSM", "SC> dial '" + address + "'");
-
+
if (nextDialFailImmediately) {
nextDialFailImmediately = false;
Log.d("GSM", "SC< dial fail (per request)");
- return false;
+ return false;
}
String phNum = PhoneNumberUtils.extractNetworkPortion(address);
@@ -696,15 +696,15 @@ class SimulatedGsmCallState extends Handler {
if (freeSlot < 0 && calls[i] == null) {
freeSlot = i;
}
-
+
if (calls[i] != null && !calls[i].isActiveOrHeld()) {
- // Can't make outgoing calls when there is a ringing or
+ // Can't make outgoing calls when there is a ringing or
// connecting outgoing call
Log.d("GSM", "SC< dial fail (invalid call state)");
return false;
} else if (calls[i] != null && calls[i].state == CallInfo.State.ACTIVE) {
// All active calls behome held
- calls[i].state = CallInfo.State.HOLDING;
+ calls[i].state = CallInfo.State.HOLDING;
}
}
@@ -717,7 +717,7 @@ class SimulatedGsmCallState extends Handler {
if (autoProgressConnecting) {
sendMessageDelayed(
- obtainMessage(EVENT_PROGRESS_CALL_STATE, calls[freeSlot]),
+ obtainMessage(EVENT_PROGRESS_CALL_STATE, calls[freeSlot]),
CONNECTING_PAUSE_MSEC);
}
@@ -776,7 +776,7 @@ class SimulatedGsmCallState extends Handler {
if (call != null) {
if (!hasMpty && call.isMpty) {
mptyIsHeld = call.state == CallInfo.State.HOLDING;
- } else if (call.isMpty && mptyIsHeld
+ } else if (call.isMpty && mptyIsHeld
&& call.state == CallInfo.State.ACTIVE
) {
Log.e("ModelInterpreter", "Invalid state");
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java b/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java
index 9e1a7c5..054d370 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java
@@ -45,7 +45,7 @@ public interface SimulatedRadioControl
/** see pauseResponses */
public void resumeResponses();
-
+
public void triggerSsn(int type, int code);
/** Generates an incoming USSD message. */