summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk4
-rw-r--r--core/java/android/net/MobileDataStateTracker.java58
-rw-r--r--core/java/android/provider/Checkin.java4
-rw-r--r--core/java/android/provider/Settings.java27
-rw-r--r--core/java/android/provider/Telephony.java8
-rw-r--r--core/java/android/webkit/gears/AndroidRadioDataProvider.java4
-rw-r--r--core/res/res/values/strings.xml6
-rw-r--r--j44
-rw-r--r--location/java/com/android/internal/location/CellState.java2
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java8
-rw-r--r--preloaded-classes9
-rw-r--r--services/java/com/android/server/status/StatusBarPolicy.java96
-rw-r--r--telephony/java/android/telephony/CellLocation.java14
-rw-r--r--telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java12
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java8
-rw-r--r--telephony/java/android/telephony/PhoneStateListener.java38
-rw-r--r--telephony/java/android/telephony/ServiceState.aidl16
-rw-r--r--telephony/java/android/telephony/ServiceState.java6
-rw-r--r--telephony/java/android/telephony/SmsManager.java440
-rw-r--r--telephony/java/android/telephony/SmsMessage.java607
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java138
-rw-r--r--telephony/java/android/telephony/cdma/CdmaCellLocation.java4
-rw-r--r--telephony/java/android/telephony/cdma/TtyIntent.java98
-rw-r--r--telephony/java/android/telephony/cdma/package.html5
-rw-r--r--telephony/java/android/telephony/gsm/GsmCellLocation.java4
-rw-r--r--telephony/java/android/telephony/gsm/SmsManager.java353
-rw-r--r--telephony/java/android/telephony/gsm/SmsMessage.java1542
-rw-r--r--telephony/java/com/android/internal/telephony/ATResponseParser.java4
-rw-r--r--telephony/java/com/android/internal/telephony/AdnRecord.aidl1
-rw-r--r--telephony/java/com/android/internal/telephony/AdnRecord.java29
-rw-r--r--telephony/java/com/android/internal/telephony/AdnRecordCache.java22
-rw-r--r--telephony/java/com/android/internal/telephony/AdnRecordLoader.java59
-rw-r--r--telephony/java/com/android/internal/telephony/BaseCommands.java327
-rw-r--r--telephony/java/com/android/internal/telephony/Call.java36
-rw-r--r--telephony/java/com/android/internal/telephony/CallTracker.java60
-rw-r--r--telephony/java/com/android/internal/telephony/CallerInfo.java48
-rw-r--r--telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java128
-rw-r--r--telephony/java/com/android/internal/telephony/CommandException.java (renamed from telephony/java/com/android/internal/telephony/gsm/CommandException.java)16
-rw-r--r--telephony/java/com/android/internal/telephony/CommandsInterface.java409
-rw-r--r--telephony/java/com/android/internal/telephony/Connection.java38
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java297
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionTracker.java334
-rw-r--r--telephony/java/com/android/internal/telephony/DataLink.java (renamed from telephony/java/com/android/internal/telephony/gsm/DataLink.java)9
-rw-r--r--telephony/java/com/android/internal/telephony/DataLinkInterface.java (renamed from telephony/java/com/android/internal/telephony/gsm/DataLinkInterface.java)18
-rw-r--r--telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java6
-rw-r--r--telephony/java/com/android/internal/telephony/DriverCall.java6
-rw-r--r--telephony/java/com/android/internal/telephony/EncodeException.java (renamed from telephony/java/com/android/internal/telephony/gsm/EncodeException.java)16
-rw-r--r--telephony/java/com/android/internal/telephony/GsmAlphabet.java (renamed from telephony/java/com/android/internal/telephony/gsm/GsmAlphabet.java)161
-rw-r--r--telephony/java/com/android/internal/telephony/ISms.aidl (renamed from telephony/java/com/android/internal/telephony/gsm/ISms.aidl)48
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl16
-rw-r--r--telephony/java/com/android/internal/telephony/IccCard.java7
-rw-r--r--telephony/java/com/android/internal/telephony/IccCardApplication.java50
-rw-r--r--telephony/java/com/android/internal/telephony/IccCardStatus.java22
-rw-r--r--telephony/java/com/android/internal/telephony/IccConstants.java6
-rw-r--r--telephony/java/com/android/internal/telephony/IccFileHandler.java446
-rw-r--r--telephony/java/com/android/internal/telephony/IccIoResult.java6
-rw-r--r--telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java230
-rw-r--r--telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java21
-rw-r--r--telephony/java/com/android/internal/telephony/IccProvider.java33
-rw-r--r--telephony/java/com/android/internal/telephony/IccRecords.java165
-rw-r--r--telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java147
-rw-r--r--telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java47
-rw-r--r--telephony/java/com/android/internal/telephony/IccUtils.java68
-rw-r--r--telephony/java/com/android/internal/telephony/MmiCode.java4
-rw-r--r--telephony/java/com/android/internal/telephony/Phone.java487
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java330
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneFactory.java106
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneProxy.java283
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java4
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneSubInfo.java13
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java11
-rw-r--r--telephony/java/com/android/internal/telephony/RIL.java930
-rw-r--r--telephony/java/com/android/internal/telephony/RILConstants.java66
-rw-r--r--telephony/java/com/android/internal/telephony/SMSDispatcher.java (renamed from telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java)386
-rw-r--r--telephony/java/com/android/internal/telephony/ServiceStateTracker.java38
-rw-r--r--telephony/java/com/android/internal/telephony/SmsAddress.java65
-rw-r--r--telephony/java/com/android/internal/telephony/SmsHeader.java (renamed from telephony/java/com/android/internal/telephony/gsm/SmsHeader.java)82
-rw-r--r--telephony/java/com/android/internal/telephony/SmsMessageBase.java388
-rw-r--r--telephony/java/com/android/internal/telephony/SmsRawData.aidl (renamed from telephony/java/com/android/internal/telephony/gsm/SmsRawData.aidl)2
-rw-r--r--telephony/java/com/android/internal/telephony/SmsRawData.java (renamed from telephony/java/com/android/internal/telephony/gsm/SmsRawData.java)6
-rw-r--r--telephony/java/com/android/internal/telephony/SmsResponse.java (renamed from telephony/java/com/android/internal/telephony/gsm/SmsResponse.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyIntents.java22
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyProperties.java17
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java785
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CallFailCause.java2
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaCall.java54
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java230
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java134
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java315
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java738
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java375
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java518
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/FeatureCode.java312
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimCard.java111
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java430
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java248
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimRecords.java390
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java153
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/SMSDispatcher.java833
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/SmsMessage.java905
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/TtyIntent.java46
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/package.html6
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java192
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java98
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java371
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java110
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/UserData.java63
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/package.html6
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/ApnSetting.java3
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GSMPhone.java449
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmCall.java40
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java143
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmConnection.java94
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java (renamed from telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java)850
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java183
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java259
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java139
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java148
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/MccTable.java468
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/NetworkInfo.aidl4
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/NetworkInfo.java36
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/PDPContextState.java3
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/PdpConnection.java390
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/PppLink.java50
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java421
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SIMRecords.java293
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SimCard.java44
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java240
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java172
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SimTlv.java31
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SimUtils.java329
-rwxr-xr-xtelephony/java/com/android/internal/telephony/gsm/SmsMessage.java1058
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java4
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java20
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java14
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/CommandListener.java10
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java10
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java32
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java5
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/Service.java246
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/StkAppInstaller.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/StkAppStateReceiver.java4
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedCommands.java134
-rw-r--r--telephony/jni/cdmasms/Android.mk28
-rw-r--r--telephony/jni/cdmasms/cdma_sms_jni.cpp1301
-rw-r--r--telephony/jni/cdmasms/cdma_sms_jni.h159
147 files changed, 15667 insertions, 9709 deletions
diff --git a/Android.mk b/Android.mk
index ad2d518dd004..ea10716c5405 100644
--- a/Android.mk
+++ b/Android.mk
@@ -106,8 +106,8 @@ LOCAL_SRC_FILES += \
telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
telephony/java/com/android/internal/telephony/ITelephony.aidl \
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
-telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl \
- telephony/java/com/android/internal/telephony/gsm/ISms.aidl \
+ telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl \
+ telephony/java/com/android/internal/telephony/ISms.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl
LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 42bbf6c53592..b81d5457719f 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -115,28 +115,28 @@ public class MobileDataStateTracker extends NetworkStateTracker {
mMobileDataState = state;
switch (state) {
- case DISCONNECTED:
- setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
- if (mInterfaceName != null) {
- NetworkUtils.resetConnections(mInterfaceName);
- }
- mInterfaceName = null;
- mDefaultGatewayAddr = 0;
- break;
- case CONNECTING:
- setDetailedState(DetailedState.CONNECTING, reason, apnName);
- break;
- case SUSPENDED:
- setDetailedState(DetailedState.SUSPENDED, reason, apnName);
- break;
- case CONNECTED:
- mInterfaceName = intent.getStringExtra(Phone.DATA_IFACE_NAME_KEY);
- if (mInterfaceName == null) {
- Log.d(TAG, "CONNECTED event did not supply interface name.");
- }
- setupDnsProperties();
- setDetailedState(DetailedState.CONNECTED, reason, apnName);
- break;
+ case DISCONNECTED:
+ setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
+ if (mInterfaceName != null) {
+ NetworkUtils.resetConnections(mInterfaceName);
+ }
+ mInterfaceName = null;
+ mDefaultGatewayAddr = 0;
+ break;
+ case CONNECTING:
+ setDetailedState(DetailedState.CONNECTING, reason, apnName);
+ break;
+ case SUSPENDED:
+ setDetailedState(DetailedState.SUSPENDED, reason, apnName);
+ break;
+ case CONNECTED:
+ mInterfaceName = intent.getStringExtra(Phone.DATA_IFACE_NAME_KEY);
+ if (mInterfaceName == null) {
+ Log.d(TAG, "CONNECTED event did not supply interface name.");
+ }
+ setupDnsProperties();
+ setDetailedState(DetailedState.CONNECTED, reason, apnName);
+ break;
}
}
} else if (intent.getAction().equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
@@ -227,26 +227,26 @@ public class MobileDataStateTracker extends NetworkStateTracker {
* for this network.
*/
public String getTcpBufferSizesPropName() {
- String networkTypeStr = "unknown";
+ String networkTypeStr = "unknown";
TelephonyManager tm = new TelephonyManager(mContext);
//TODO We have to edit the parameter for getNetworkType regarding CDMA
switch(tm.getNetworkType()) {
- case TelephonyManager.NETWORK_TYPE_GPRS:
+ case TelephonyManager.NETWORK_TYPE_GPRS:
networkTypeStr = "gprs";
break;
- case TelephonyManager.NETWORK_TYPE_EDGE:
+ case TelephonyManager.NETWORK_TYPE_EDGE:
networkTypeStr = "edge";
break;
- case TelephonyManager.NETWORK_TYPE_UMTS:
+ case TelephonyManager.NETWORK_TYPE_UMTS:
networkTypeStr = "umts";
break;
- case TelephonyManager.NETWORK_TYPE_CDMA:
+ case TelephonyManager.NETWORK_TYPE_CDMA:
networkTypeStr = "cdma";
break;
- case TelephonyManager.NETWORK_TYPE_EVDO_0:
+ case TelephonyManager.NETWORK_TYPE_EVDO_0:
networkTypeStr = "evdo";
break;
- case TelephonyManager.NETWORK_TYPE_EVDO_A:
+ case TelephonyManager.NETWORK_TYPE_EVDO_A:
networkTypeStr = "evdo";
break;
}
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
index d6e8899a3f38..36a1114031eb 100644
--- a/core/java/android/provider/Checkin.java
+++ b/core/java/android/provider/Checkin.java
@@ -127,10 +127,12 @@ public final class Checkin {
PHONE_GPRS_ATTEMPTED,
PHONE_GPRS_CONNECTED,
PHONE_RADIO_RESETS,
- PHONE_CDMA_REGISTERED,
TEST,
NETWORK_RX_MOBILE,
NETWORK_TX_MOBILE,
+ PHONE_CDMA_REGISTERED,
+ PHONE_CDMA_DATA_ATTEMPTED,
+ PHONE_CDMA_DATA_CONNECTED,
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ea5edfd1d836..cf7f6b481493 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -813,8 +813,8 @@ public final class Settings {
public static final String WAIT_FOR_DEBUGGER = "wait_for_debugger";
/**
- * represents current acitve phone class
- * 0 = GSM-Phone, 1 = CDMA-Phone
+ * represents current active phone class
+ * 1 = GSM-Phone, 0 = CDMA-Phone
*/
public static final String CURRENT_ACTIVE_PHONE = "current_active_phone";
@@ -1106,6 +1106,14 @@ public final class Settings {
"preferred_network_mode";
/**
+ * CDMA Cell Broadcast SMS
+ * 0 = CDMA Cell Broadcast SMS disabled
+ * 1 = CDMA Cell Broadcast SMS enabled
+ */
+ public static final String CDMA_CELL_BROADCAST_SMS =
+ "cdma_cell_broadcast_sms";
+
+ /**
* The cdma subscription 0 = Subscription from RUIM, when available
* 1 = Subscription from NV
*/
@@ -2072,9 +2080,10 @@ public final class Settings {
/**
* Returns the GTalk JID resource associated with this device.
*
- * @return String the JID resource of the device. It uses the device IMEI in the computation
- * of the JID resource. If IMEI is not ready (i.e. telephony module not ready), we'll return
- * an empty string.
+ * @return String the JID resource of the device. It uses the Device ID (IMEI for GSM and MEID
+ * for CDMA) in the computation.
+ * of the JID resource. If Device ID is not ready (i.e. telephony module not ready), we'll
+ * return an empty string.
* @hide
*/
// TODO: we shouldn't not have a permenant Jid resource, as that's an easy target for
@@ -2093,13 +2102,13 @@ public final class Settings {
throw new RuntimeException("this should never happen");
}
- String imei = TelephonyManager.getDefault().getDeviceId();
- if (TextUtils.isEmpty(imei)) {
+ String deviceId = TelephonyManager.getDefault().getDeviceId();
+ if (TextUtils.isEmpty(deviceId)) {
return "";
}
- byte[] hashedImei = digest.digest(imei.getBytes());
- String id = new String(Base64.encodeBase64(hashedImei), 0, 12);
+ byte[] hashedDeviceId = digest.digest(deviceId.getBytes());
+ String id = new String(Base64.encodeBase64(hashedDeviceId), 0, 12);
id = id.replaceAll("/", "_");
sJidResource = JID_RESOURCE_PREFIX + id;
return sJidResource;
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 776a2664b16a..1ffbde7e6244 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -28,16 +28,16 @@ import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.telephony.PhoneNumberUtils;
+import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
-import android.telephony.gsm.SmsMessage;
import android.text.TextUtils;
import android.text.util.Regex;
import android.util.Config;
import java.util.HashSet;
-import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.Set;
/**
* The Telephony provider contains data related to phone operation.
@@ -49,6 +49,10 @@ public final class Telephony {
private static final boolean DEBUG = false;
private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
+ // Constructor
+ public Telephony() {
+ }
+
/**
* Base columns for tables that contain text based SMSs.
*/
diff --git a/core/java/android/webkit/gears/AndroidRadioDataProvider.java b/core/java/android/webkit/gears/AndroidRadioDataProvider.java
index 8887b24ec53a..2d431a8d6162 100644
--- a/core/java/android/webkit/gears/AndroidRadioDataProvider.java
+++ b/core/java/android/webkit/gears/AndroidRadioDataProvider.java
@@ -46,8 +46,8 @@ public final class AndroidRadioDataProvider extends PhoneStateListener {
private static final int RADIO_TYPE_UNKNOWN = 0;
private static final int RADIO_TYPE_GSM = 1;
private static final int RADIO_TYPE_WCDMA = 2;
- private static final int RADIO_TYPE_CDMA = 3;
- private static final int RADIO_TYPE_EVDO = 4;
+ private static final int RADIO_TYPE_CDMA = 3;
+ private static final int RADIO_TYPE_EVDO = 4;
private static final int RADIO_TYPE_1xRTT = 5;
/** Simple container for radio data */
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index bec3bc870179..55052daf688e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -67,6 +67,12 @@
<string name="BaMmi">Call barring</string>
<string name="PwdMmi">Password change</string>
<string name="PinMmi">PIN change</string>
+ <string name="CnipMmi">Calling number present</string>
+ <string name="CnirMmi">Calling number restricted</string>
+ <string name="ThreeWCMmi">Three way calling</string>
+ <string name="RuacMmi">Rejection of undesired annoying calls</string>
+ <string name="CndMmi">Calling number delivery</string>
+ <string name="DndMmi">Do not disturb</string>
<string name="CLIRDefaultOnNextCallOn">Caller ID defaults to restricted. Next call: Restricted</string>
<string name="CLIRDefaultOnNextCallOff">Caller ID defaults to restricted. Next call: Not restricted</string>
diff --git a/j b/j
new file mode 100644
index 000000000000..ba2eec9e51ed
--- /dev/null
+++ b/j
@@ -0,0 +1,44 @@
+telephony/java/android/telephony/SmsManager.java
+telephony/java/android/telephony/SmsMessage.java
+telephony/java/android/telephony/cdma/package.html
+telephony/java/android/telephony/gsm/SmsMessage.java
+telephony/java/com/android/internal/telephony/CommandException.java
+telephony/java/com/android/internal/telephony/DataConnection.java
+telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+telephony/java/com/android/internal/telephony/DataLink.java
+telephony/java/com/android/internal/telephony/DataLinkInterface.java
+telephony/java/com/android/internal/telephony/EncodeException.java
+telephony/java/com/android/internal/telephony/GsmAlphabet.java
+telephony/java/com/android/internal/telephony/ISms.aidl
+telephony/java/com/android/internal/telephony/SMSDispatcher.java
+telephony/java/com/android/internal/telephony/SmsAddress.java
+telephony/java/com/android/internal/telephony/SmsHeader.java
+telephony/java/com/android/internal/telephony/SmsMessageBase.java
+telephony/java/com/android/internal/telephony/SmsRawData.aidl
+telephony/java/com/android/internal/telephony/SmsRawData.java
+telephony/java/com/android/internal/telephony/SmsResponse.java
+telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+telephony/java/com/android/internal/telephony/cdma/FeatureCode.java
+telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
+telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
+telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+telephony/java/com/android/internal/telephony/cdma/TtyIntent.java
+telephony/java/com/android/internal/telephony/cdma/package.html
+telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
+telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java
+telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
+telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
+telephony/java/com/android/internal/telephony/cdma/sms/package.html
+telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
+telephony/java/com/android/internal/telephony/gsm/MccTable.java
+telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
+telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
+telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
+telephony/jni/cdmasms/Android.mk
+telephony/jni/cdmasms/cdma_sms_jni.cpp
+telephony/jni/cdmasms/cdma_sms_jni.h
diff --git a/location/java/com/android/internal/location/CellState.java b/location/java/com/android/internal/location/CellState.java
index 868d84a39b45..96fe145a1649 100644
--- a/location/java/com/android/internal/location/CellState.java
+++ b/location/java/com/android/internal/location/CellState.java
@@ -81,7 +81,7 @@ public class CellState {
// Get Home MCC/MNC
String homeOperator = SystemProperties.get(
- TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC);
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC);
if (homeOperator != null && !homeOperator.equals("")) {
String mcc = homeOperator.substring(0, 3);
String mnc = homeOperator.substring(3);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index d58879deb743..a7d1385b5859 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -568,11 +568,15 @@ class DatabaseHelper extends SQLiteOpenHelper {
// Set the preferred network mode to 0 = Global, CDMA default
loadSetting(stmt, Settings.System.PREFERRED_NETWORK_MODE,
- RILConstants.NETWORK_MODE_GLOBAL);
+ RILConstants.PREFERRED_NETWORK_MODE);
+
+ // Enable or disable Cell Broadcast SMS
+ loadSetting(stmt, Settings.System.CDMA_CELL_BROADCAST_SMS,
+ RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
// Set the preferred cdma subscription to 0 = Subscription from RUIM, when available
loadSetting(stmt, Settings.System.PREFERRED_CDMA_SUBSCRIPTION,
- RILConstants.SUBSCRIPTION_FROM_RUIM);
+ RILConstants.PREFERRED_CDMA_SUBSCRIPTION);
// Don't do this. The SystemServer will initialize ADB_ENABLED from a
// persistent system property instead.
diff --git a/preloaded-classes b/preloaded-classes
index 4d5e9b69ca6b..3a637cd4e193 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -270,8 +270,8 @@ android.speech.recognition.impl.MicrophoneImpl
android.speech.recognition.impl.System
android.telephony.PhoneNumberUtils
android.telephony.ServiceState
-android.telephony.gsm.SmsManager
-android.telephony.gsm.SmsMessage
+android.telephony.SmsManager
+android.telephony.SmsMessage
android.text.AutoText
android.text.BoringLayout
android.text.BoringLayout$Metrics
@@ -490,6 +490,8 @@ com.android.internal.policy.impl.PhoneWindow$PanelFeatureState
com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState
com.android.internal.telephony.BaseCommands
com.android.internal.telephony.CommandsInterface
+com.android.internal.telephony.GsmAlphabet
+com.android.internal.telephony.ISms$Stub
com.android.internal.telephony.Phone
com.android.internal.telephony.Phone$DataActivityState
com.android.internal.telephony.Phone$DataState
@@ -498,9 +500,6 @@ com.android.internal.telephony.PhoneBase
com.android.internal.telephony.PhoneStateIntentReceiver
com.android.internal.telephony.RIL
com.android.internal.telephony.gsm.GSMPhone
-com.android.internal.telephony.gsm.GsmAlphabet
-com.android.internal.telephony.gsm.ISms$Stub
-com.android.internal.telephony.gsm.PdpConnection$PdpFailCause
com.android.internal.telephony.gsm.GsmServiceStateTracker
com.android.internal.telephony.gsm.SimCard
com.android.internal.view.menu.MenuDialogHelper
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index 8789d580c80d..ab19e3c25f0f 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -52,7 +52,7 @@ import com.android.internal.R;
import com.android.internal.location.GpsLocationProvider;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.TelephonyIntents;
-import android.telephony.cdma.TtyIntent;
+import com.android.internal.telephony.cdma.TtyIntent;
import java.util.Calendar;
import java.util.TimeZone;
@@ -193,7 +193,7 @@ public class StatusBarPolicy {
private IBinder mVolumeIcon;
private IconData mVolumeData;
private boolean mVolumeVisible;
-
+
// bluetooth device status
private IBinder mBluetoothIcon;
private IconData mBluetoothData;
@@ -325,13 +325,13 @@ public class StatusBarPolicy {
mWifiIcon = service.addIcon(mWifiData, null);
service.setIconVisibility(mWifiIcon, false);
// wifi will get updated by the sticky intents
-
+
// TTY status
mTTYModeEnableIconData = IconData.makeIcon("tty",
null, com.android.internal.R.drawable.stat_sys_tty_mode, 0, 0);
mTTYModeIcon = service.addIcon(mTTYModeEnableIconData, null);
service.setIconVisibility(mTTYModeIcon, false);
-
+
// bluetooth status
mBluetoothData = IconData.makeIcon("bluetooth",
null, com.android.internal.R.drawable.stat_sys_data_bluetooth, 0, 0);
@@ -366,7 +366,7 @@ public class StatusBarPolicy {
null, com.android.internal.R.drawable.stat_sys_ringer_silent, 0, 0);
mVolumeIcon = service.addIcon(mVolumeData, null);
service.setIconVisibility(mVolumeIcon, false);
-
+
IntentFilter filter = new IntentFilter();
// Register for Intent broadcasts for...
@@ -520,7 +520,7 @@ public class StatusBarPolicy {
com.android.internal.R.styleable.Theme);
lp.dimAmount = a.getFloat(android.R.styleable.Theme_backgroundDimAmount, 0.5f);
a.recycle();
-
+
lp.setTitle("Battery");
TextView levelTextView = (TextView)v.findViewById(com.android.internal.R.id.level_percent);
@@ -729,15 +729,15 @@ public class StatusBarPolicy {
|| ss.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_IS95A
|| ss.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_IS95B) {
switch(ss.getExtendedCdmaRoaming()) {
- case ServiceState.REGISTRATION_STATE_ROAMING:
- iconList = this.sSignalImages_r_cdma;
- break;
- case ServiceState.REGISTRATION_STATE_ROAMING_AFFILIATE:
- iconList = this.sSignalImages_ra_cdma;
- break;
- default:
- iconList = this.sSignalImages_cdma;
- break;
+ case ServiceState.REGISTRATION_STATE_ROAMING:
+ iconList = this.sSignalImages_r_cdma;
+ break;
+ case ServiceState.REGISTRATION_STATE_ROAMING_AFFILIATE:
+ iconList = this.sSignalImages_ra_cdma;
+ break;
+ default:
+ iconList = this.sSignalImages_cdma;
+ break;
}
}
@@ -750,31 +750,31 @@ public class StatusBarPolicy {
ServiceState ss = this.mServiceState;
switch (net) {
- case TelephonyManager.NETWORK_TYPE_EDGE:
- mDataIconList = sDataNetType_e;
- break;
- case TelephonyManager.NETWORK_TYPE_UMTS:
- mDataIconList = sDataNetType_3g;
- break;
- case TelephonyManager.NETWORK_TYPE_CDMA:
- //TODO check if IS95 has to be displayed or if the warning can be removed!
- if( (ss.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_IS95A) ||
- ss.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_IS95B) {
- Log.w(TAG, "Warning! CDMA radio technology is either IS95A or IS95B,"
- + " but you will see 1xRTT!");
- }
- mDataIconList = this.sDataNetType_1xrtt;
- break;
+ case TelephonyManager.NETWORK_TYPE_EDGE:
+ mDataIconList = sDataNetType_e;
+ break;
+ case TelephonyManager.NETWORK_TYPE_UMTS:
+ mDataIconList = sDataNetType_3g;
+ break;
+ case TelephonyManager.NETWORK_TYPE_CDMA:
+ // display 1xRTT for IS95A/B
+ if( (ss.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_IS95A) ||
+ ss.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_IS95B) {
+ Log.w(TAG, "Warning! CDMA radio technology is either IS95A or IS95B,"
+ + " but you will see 1xRTT!");
+ }
+ mDataIconList = this.sDataNetType_1xrtt;
+ break;
case TelephonyManager.NETWORK_TYPE_1xRTT:
mDataIconList = this.sDataNetType_1xrtt;
break;
- case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
- case TelephonyManager.NETWORK_TYPE_EVDO_A:
- mDataIconList = sDataNetType_evdo;
+ case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
+ case TelephonyManager.NETWORK_TYPE_EVDO_A:
+ mDataIconList = sDataNetType_evdo;
break;
- default:
- mDataIconList = sDataNetType_g;
- break;
+ default:
+ mDataIconList = sDataNetType_g;
+ break;
}
}
@@ -784,7 +784,7 @@ public class StatusBarPolicy {
if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
int data = mDataState;
-
+
int[] list = mDataIconList;
ServiceState ss = mServiceState;
@@ -827,7 +827,7 @@ public class StatusBarPolicy {
private final void updateVolume(Intent intent) {
// This can be called from two different received intents, so don't use extras.
-
+
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
final int ringerMode = audioManager.getRingerMode();
final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT ||
@@ -881,17 +881,17 @@ public class StatusBarPolicy {
private final void updateWifi(Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-
+
final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
-
+
if (!enabled) {
// If disabled, hide the icon. (We show icon when connected.)
mService.setIconVisibility(mWifiIcon, false);
}
-
+
} else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-
+
final NetworkInfo networkInfo = (NetworkInfo)
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
@@ -903,10 +903,10 @@ public class StatusBarPolicy {
} else {
iconId = sWifiSignalImages[mLastWifiSignalLevel];
}
-
+
// Show the icon since wi-fi is connected
mService.setIconVisibility(mWifiIcon, true);
-
+
} else {
mLastWifiSignalLevel = -1;
mIsWifiConnected = false;
@@ -956,16 +956,16 @@ public class StatusBarPolicy {
final String action = intent.getAction();
final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false);
- Log.w(TAG, "updateTTY: enabled: " + enabled);
-
+ Log.i(TAG, "updateTTY: enabled: " + enabled);
+
if (enabled) {
// TTY is on
- Log.w(TAG, "updateTTY: set TTY on");
+ Log.i(TAG, "updateTTY: set TTY on");
mService.updateIcon(mTTYModeIcon, mTTYModeEnableIconData, null);
mService.setIconVisibility(mTTYModeIcon, true);
} else {
// TTY is off
- Log.w(TAG, "updateTTY: set TTY off");
+ Log.i(TAG, "updateTTY: set TTY off");
mService.setIconVisibility(mTTYModeIcon, false);
}
}
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index 5d2cb2d32e72..5df97684048c 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -62,8 +62,10 @@ public abstract class CellLocation {
* @hide
*/
public static CellLocation newFromBundle(Bundle bundle) {
- if (RILConstants.CDMA_PHONE ==
- SystemProperties.getInt(Settings.System.CURRENT_ACTIVE_PHONE, 0)) {
+ // NOTE here TelephonyManager.getDefault().getPhoneType() cannot be used since at startup
+ // ITelephony have not been created
+ if (RILConstants.CDMA_PHONE ==
+ SystemProperties.getInt(Settings.System.CURRENT_ACTIVE_PHONE, 0)) {
return new CdmaCellLocation(bundle);
} else {
return new GsmCellLocation(bundle);
@@ -80,13 +82,15 @@ public abstract class CellLocation {
*
*/
public static CellLocation getEmpty() {
- if (RILConstants.CDMA_PHONE ==
- SystemProperties.getInt(Settings.System.CURRENT_ACTIVE_PHONE, 0)) {
+ // NOTE here TelephonyManager.getDefault().getPhoneType() cannot be used since at startup
+ // ITelephony have not been created
+ if (RILConstants.CDMA_PHONE ==
+ SystemProperties.getInt(Settings.System.CURRENT_ACTIVE_PHONE, 0)) {
return new CdmaCellLocation();
} else {
return new GsmCellLocation();
}
}
-
+
}
diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
index 0bc6c041a82a..8a4733941622 100644
--- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
+++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
@@ -25,7 +25,7 @@ import java.util.Locale;
/**
* Watches a {@link TextView} and if a phone number is entered will format it using
- * {@link PhoneNumberUtils#formatNumber(Editable, int)}. The formatting is based on
+ * {@link PhoneNumberUtils#formatNumber(Editable, int)}. The formatting is based on
* the current system locale when this object is created and future locale changes
* may not take effect on this instance.
*/
@@ -35,7 +35,7 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher {
static private Locale sCachedLocale;
private boolean mFormatting;
private boolean mDeletingHyphen;
- private int mHyphenStart;
+ private int mHyphenStart;
private boolean mDeletingBackward;
public PhoneNumberFormattingTextWatcher() {
@@ -60,7 +60,7 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher {
text.delete(mHyphenStart, mHyphenStart + 1);
}
}
-
+
PhoneNumberUtils.formatNumber(text, sFormatType);
mFormatting = false;
@@ -73,8 +73,8 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher {
// Make sure user is deleting one char, without a selection
final int selStart = Selection.getSelectionStart(s);
final int selEnd = Selection.getSelectionEnd(s);
- if (s.length() > 1 // Can delete another character
- && count == 1 // Deleting only one character
+ if (s.length() > 1 // Can delete another character
+ && count == 1 // Deleting only one character
&& after == 0 // Deleting
&& s.charAt(start) == '-' // a hyphen
&& selStart == selEnd) { // no selection
@@ -89,7 +89,7 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher {
} else {
mDeletingHyphen = false;
}
- }
+ }
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index f2b63cc0dfef..3578c9936dd1 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -932,7 +932,7 @@ public class PhoneNumberUtils
return;
}
CharSequence saved = text.subSequence(0, length);
-
+
// Strip the dashes first, as we're going to add them back
int p = 0;
while (p < text.length()) {
@@ -1013,7 +1013,7 @@ public class PhoneNumberUtils
int pos = dashPositions[i];
text.replace(pos + i, pos + i, "-");
}
-
+
// Remove trailing dashes
int len = text.length();
while (len > 0) {
@@ -1040,10 +1040,10 @@ public class PhoneNumberUtils
* listed in the ril / sim, then return true, otherwise false.
*/
public static boolean isEmergencyNumber(String number) {
- // Strip the separators from the number before comparing it
+ // Strip the separators from the number before comparing it
// to the list.
number = extractNetworkPortion(number);
-
+
// retrieve the list of emergency numbers
String numbers = SystemProperties.get("ro.ril.ecclist");
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 8a8a675e7c47..df6860b08365 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -11,18 +11,18 @@ import com.android.internal.telephony.IPhoneStateListener;
/**
* A listener class for monitoring changes in specific telephony states
- * on the device, including service state, signal strength, message
+ * on the device, including service state, signal strength, message
* waiting indicator (voicemail), and others.
* <p>
- * Override the methods for the state that you wish to receive updates for, and
+ * Override the methods for the state that you wish to receive updates for, and
* pass your PhoneStateListener object, along with bitwise-or of the LISTEN_
* flags to {@link TelephonyManager#listen TelephonyManager.listen()}.
* <p>
* Note that access to some telephony information is
- * permission-protected. Your application won't receive updates for protected
- * information unless it has the appropriate permissions declared in
+ * permission-protected. Your application won't receive updates for protected
+ * information unless it has the appropriate permissions declared in
* its manifest file. Where permissions apply, they are noted in the
- * appropriate LISTEN_ flags.
+ * appropriate LISTEN_ flags.
*/
public class PhoneStateListener {
@@ -67,17 +67,17 @@ public class PhoneStateListener {
public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008;
/**
- * Listen for changes to the device's cell location. Note that
+ * Listen for changes to the device's cell location. Note that
* this will result in frequent callbacks to the listener.
* {@more}
* Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
* ACCESS_COARSE_LOCATION}
* <p>
- * If you need regular location updates but want more control over
- * the update interval or location precision, you can set up a listener
- * through the {@link android.location.LocationManager location manager}
- * instead.
- *
+ * If you need regular location updates but want more control over
+ * the update interval or location precision, you can set up a listener
+ * through the {@link android.location.LocationManager location manager}
+ * instead.
+ *
* @see #onCellLocationChanged
*/
public static final int LISTEN_CELL_LOCATION = 0x00000010;
@@ -100,7 +100,7 @@ public class PhoneStateListener {
* Listen for changes to the direction of data traffic on the data
* connection (cellular).
*
- * Example: The status bar uses this to display the appropriate
+ * Example: The status bar uses this to display the appropriate
* data-traffic icon.
*
* @see #onDataActivity
@@ -111,7 +111,7 @@ public class PhoneStateListener {
}
/**
- * Callback invoked when device service state changes.
+ * Callback invoked when device service state changes.
*
* @see ServiceState#STATE_EMERGENCY_ONLY
* @see ServiceState#STATE_IN_SERVICE
@@ -135,28 +135,28 @@ public class PhoneStateListener {
}
/**
- * Callback invoked when the message-waiting indicator changes.
+ * Callback invoked when the message-waiting indicator changes.
*/
public void onMessageWaitingIndicatorChanged(boolean mwi) {
// default implementation empty
}
/**
- * Callback invoked when the call-forwarding indicator changes.
+ * Callback invoked when the call-forwarding indicator changes.
*/
public void onCallForwardingIndicatorChanged(boolean cfi) {
// default implementation empty
}
/**
- * Callback invoked when device cell location changes.
+ * Callback invoked when device cell location changes.
*/
public void onCellLocationChanged(CellLocation location) {
// default implementation empty
}
/**
- * Callback invoked when device call state changes.
+ * Callback invoked when device call state changes.
*
* @see TelephonyManager#CALL_STATE_IDLE
* @see TelephonyManager#CALL_STATE_RINGING
@@ -167,7 +167,7 @@ public class PhoneStateListener {
}
/**
- * Callback invoked when connection state changes.
+ * Callback invoked when connection state changes.
*
* @see TelephonyManager#DATA_DISCONNECTED
* @see TelephonyManager#DATA_CONNECTING
@@ -179,7 +179,7 @@ public class PhoneStateListener {
}
/**
- * Callback invoked when data activity state changes.
+ * Callback invoked when data activity state changes.
*
* @see TelephonyManager#DATA_ACTIVITY_NONE
* @see TelephonyManager#DATA_ACTIVITY_IN
diff --git a/telephony/java/android/telephony/ServiceState.aidl b/telephony/java/android/telephony/ServiceState.aidl
index b1cf3790ead5..852288937ef0 100644
--- a/telephony/java/android/telephony/ServiceState.aidl
+++ b/telephony/java/android/telephony/ServiceState.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/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 7414a2c5c913..7098b7753df7 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -35,7 +35,7 @@ import android.util.Log;
*/
public class ServiceState implements Parcelable {
- static final String LOG_TAG = "ServiceState";
+ static final String LOG_TAG = "PHONE";
/**
* Normal operation condition, the phone is registered
@@ -278,7 +278,7 @@ public class ServiceState implements Parcelable {
@Override
public boolean equals (Object o) {
ServiceState s;
-
+
try {
s = (ServiceState) o;
} catch (ClassCastException ex) {
@@ -400,7 +400,7 @@ public class ServiceState implements Parcelable {
public void setIsManualSelection(boolean isManual) {
mIsManualNetworkSelection = isManual;
}
-
+
/**
* Test whether two objects hold the same data values or both are null
*
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
new file mode 100644
index 000000000000..8f271083a298
--- /dev/null
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.app.PendingIntent;
+import android.os.RemoteException;
+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;
+
+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;
+
+/**
+ * Manages SMS operations such as sending data, text, and pdu SMS messages.
+ * Get this object by calling the static method SmsManager.getDefault().
+ */
+public final class SmsManager {
+ private static SmsManager sInstance;
+
+ /**
+ * Send a text based SMS.
+ *
+ * @param destinationAddress the address to send the message to
+ * @param scAddress is the service center address or null to use
+ * the current default SMSC
+ * @param text the body of the message to send
+ * @param sentIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is sucessfully sent, or failed.
+ * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * or one of these errors:
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code>
+ * <code>RESULT_ERROR_RADIO_OFF</code>
+ * <code>RESULT_ERROR_NULL_PDU</code>.
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applications,
+ * which cause smaller number of SMS to be sent in checking period.
+ * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is delivered to the recipient. The
+ * raw pdu of the status report is in the extended data ("pdu").
+ *
+ * @throws IllegalArgumentException if destinationAddress or text are empty
+ */
+ public void sendTextMessage(
+ String destinationAddress, String scAddress, String text,
+ PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ if (TextUtils.isEmpty(destinationAddress)) {
+ throw new IllegalArgumentException("Invalid destinationAddress");
+ }
+
+ if (TextUtils.isEmpty(text)) {
+ throw new IllegalArgumentException("Invalid message body");
+ }
+
+ SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(
+ scAddress, destinationAddress, text, (deliveryIntent != null));
+ sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
+ }
+
+ /**
+ * Divide a text message into several messages, none bigger than
+ * the maximum SMS message size.
+ *
+ * @param text the original message. Must not be null.
+ * @return an <code>ArrayList</code> of strings that, in order,
+ * 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;
+ }
+
+ /**
+ * Send a multi-part text based SMS. The callee should have already
+ * divided the message into correctly sized parts by calling
+ * <code>divideMessage</code>.
+ *
+ * @param destinationAddress the address to send the message to
+ * @param scAddress is the service center address or null to use
+ * the current default SMSC
+ * @param parts an <code>ArrayList</code> of strings that, in order,
+ * comprise the original message
+ * @param sentIntents if not null, an <code>ArrayList</code> of
+ * <code>PendingIntent</code>s (one for each message part) that is
+ * broadcast when the corresponding message part has been sent.
+ * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * or one of these errors:
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code>
+ * <code>RESULT_ERROR_RADIO_OFF</code>
+ * <code>RESULT_ERROR_NULL_PDU</code>.
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applicaitons,
+ * which cause smaller number of SMS to be sent in checking period.
+ * @param deliveryIntents if not null, an <code>ArrayList</code> of
+ * <code>PendingIntent</code>s (one for each message part) that is
+ * broadcast when the corresponding message part has been delivered
+ * to the recipient. The raw pdu of the status report is in the
+ * extended data ("pdu").
+ *
+ * @throws IllegalArgumentException if destinationAddress or data are empty
+ */
+ public void sendMultipartTextMessage(
+ String destinationAddress, String scAddress, ArrayList<String> parts,
+ ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
+ if (TextUtils.isEmpty(destinationAddress)) {
+ throw new IllegalArgumentException("Invalid destinationAddress");
+ }
+ if (parts == null || parts.size() < 1) {
+ throw new IllegalArgumentException("Invalid message body");
+ }
+
+ if (parts.size() > 1) {
+ try {
+ ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ if (iccISms != null) {
+ iccISms.sendMultipartText(destinationAddress, scAddress, parts,
+ sentIntents, deliveryIntents);
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+ } else {
+ PendingIntent sentIntent = null;
+ PendingIntent deliveryIntent = null;
+ if (sentIntents != null && sentIntents.size() > 0) {
+ sentIntent = sentIntents.get(0);
+ }
+ if (deliveryIntents != null && deliveryIntents.size() > 0) {
+ deliveryIntent = deliveryIntents.get(0);
+ }
+ sendTextMessage(destinationAddress, scAddress, parts.get(0),
+ sentIntent, deliveryIntent);
+ }
+ }
+
+ /**
+ * Send a data based SMS to a specific application port.
+ *
+ * @param destinationAddress the address to send the message to
+ * @param scAddress is the service center address or null to use
+ * the current default SMSC
+ * @param destinationPort the port to deliver the message to
+ * @param data the body of the message to send
+ * @param sentIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is sucessfully sent, or failed.
+ * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * or one of these errors:
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code>
+ * <code>RESULT_ERROR_RADIO_OFF</code>
+ * <code>RESULT_ERROR_NULL_PDU</code>.
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applicaitons,
+ * which cause smaller number of SMS to be sent in checking period.
+ * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is delivered to the recipient. The
+ * raw pdu of the status report is in the extended data ("pdu").
+ *
+ * @throws IllegalArgumentException if destinationAddress or data are empty
+ */
+ public void sendDataMessage(
+ String destinationAddress, String scAddress, short destinationPort,
+ byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ if (TextUtils.isEmpty(destinationAddress)) {
+ throw new IllegalArgumentException("Invalid destinationAddress");
+ }
+
+ if (data == null || data.length == 0) {
+ throw new IllegalArgumentException("Invalid message data");
+ }
+
+ SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(
+ scAddress, destinationAddress,
+ destinationPort, data, (deliveryIntent != null));
+ sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
+ }
+
+ /**
+ * Send a raw SMS PDU.
+ *
+ * @param smsc the SMSC to send the message through, or NULL for the
+ * default SMSC
+ * @param pdu the raw PDU to send
+ * @param sentIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is successfully sent, or failed.
+ * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * or one of these errors:
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code>
+ * <code>RESULT_ERROR_RADIO_OFF</code>
+ * <code>RESULT_ERROR_NULL_PDU</code>.
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applications,
+ * which cause smaller number of SMS to be sent in checking period.
+ * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is delivered to the recipient. The
+ * raw pdu of the status report is in the extended data ("pdu").
+ *
+ * @hide
+ */
+ private void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
+ PendingIntent deliveryIntent) {
+ try {
+ ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ if (iccISms != null) {
+ iccISms.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+ }
+
+ /**
+ * Get the default instance of the SmsManager
+ *
+ * @return the default instance of the SmsManager
+ */
+ public static SmsManager getDefault() {
+ if (sInstance == null) {
+ sInstance = new SmsManager();
+ }
+ return sInstance;
+ }
+
+ private SmsManager() {
+ //nothing
+ }
+
+ /**
+ * Copy a raw SMS PDU to the ICC.
+ *
+ * @param smsc the SMSC for this message, or NULL for the default SMSC
+ * @param pdu the raw PDU to store
+ * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
+ * STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
+ * @return true for success
+ *
+ * {@hide}
+ */
+ public boolean copyMessageToIcc(byte[] smsc, byte[] pdu, int status) {
+ boolean success = false;
+
+ try {
+ ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ if (iccISms != null) {
+ success = iccISms.copyMessageToIccEf(status, pdu, smsc);
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return success;
+ }
+
+ /**
+ * Delete the specified message from the ICC.
+ *
+ * @param messageIndex is the record index of the message on ICC
+ * @return true for success
+ *
+ * {@hide}
+ */
+ public boolean
+ deleteMessageFromIcc(int messageIndex) {
+ boolean success = false;
+ byte[] pdu = new byte[IccConstants.SMS_RECORD_LENGTH-1];
+ Arrays.fill(pdu, (byte)0xff);
+
+ try {
+ ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ if (iccISms != null) {
+ success = iccISms.updateMessageOnIccEf(messageIndex, STATUS_ON_ICC_FREE, pdu);
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return success;
+ }
+
+ /**
+ * Update the specified message on the ICC.
+ *
+ * @param messageIndex record index of message to update
+ * @param newStatus new message status (STATUS_ON_ICC_READ,
+ * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
+ * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
+ * @param pdu the raw PDU to store
+ * @return true for success
+ *
+ * {@hide}
+ */
+ public boolean updateMessageOnIcc(int messageIndex, int newStatus, byte[] pdu) {
+ boolean success = false;
+
+ try {
+ ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ if (iccISms != null) {
+ success = iccISms.updateMessageOnIccEf(messageIndex, newStatus, pdu);
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return success;
+ }
+
+ /**
+ * Retrieves all messages currently stored on ICC.
+ *
+ * @return <code>ArrayList</code> of <code>SmsMessage</code> objects
+ *
+ * {@hide}
+ */
+ public ArrayList<SmsMessage> getAllMessagesFromIcc() {
+ List<SmsRawData> records = null;
+
+ try {
+ ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ if (iccISms != null) {
+ records = iccISms.getAllMessagesFromIccEf();
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return createMessageListFromRawRecords(records);
+ }
+
+ /**
+ * Create a list of <code>SmsMessage</code>s from a list of RawSmsData
+ * records returned by <code>getAllMessagesFromIcc()</code>
+ *
+ * @param records SMS EF records, returned by
+ * <code>getAllMessagesFromIcc</code>
+ * @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
+ */
+ private ArrayList<SmsMessage> createMessageListFromRawRecords(List records) {
+ ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
+ if (records != null) {
+ int count = records.size();
+ for (int i = 0; i < count; i++) {
+ SmsRawData data = (SmsRawData)records.get(i);
+ // List contains all records, including "free" records (null)
+ if (data != null) {
+ SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes());
+ messages.add(sms);
+ }
+ }
+ }
+ return messages;
+ }
+
+ // see SmsMessage.getStatusOnIcc
+
+ /** Free space (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
+ static public final int STATUS_ON_ICC_FREE = 0;
+
+ /** Received and read (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
+ static public final int STATUS_ON_ICC_READ = 1;
+
+ /** Received and unread (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
+ static public final int STATUS_ON_ICC_UNREAD = 3;
+
+ /** Stored and sent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
+ static public final int STATUS_ON_ICC_SENT = 5;
+
+ /** Stored and unsent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
+ static public final int STATUS_ON_ICC_UNSENT = 7;
+
+ // SMS send failure result codes
+
+ /** Generic failure cause */
+ static public final int RESULT_ERROR_GENERIC_FAILURE = 1;
+ /** Failed because radio was explicitly turned off */
+ static public final int RESULT_ERROR_RADIO_OFF = 2;
+ /** Failed because no pdu provided */
+ static public final int RESULT_ERROR_NULL_PDU = 3;
+ /** Failed because service is currently unavailable */
+ static public final int RESULT_ERROR_NO_SERVICE = 4;
+}
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
new file mode 100644
index 000000000000..1790bba86f9b
--- /dev/null
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+
+import com.android.internal.telephony.GsmAlphabet;
+import com.android.internal.telephony.EncodeException;
+import com.android.internal.telephony.SmsMessageBase;
+import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
+
+import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
+
+
+/**
+ * A Short Message Service message.
+ *
+ */
+public class SmsMessage {
+ private static final boolean LOCAL_DEBUG = true;
+ private static final String LOG_TAG = "SMS";
+
+ /**
+ * SMS Class enumeration.
+ * See TS 23.038.
+ *
+ */
+ public enum MessageClass{
+ UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
+ }
+
+ /** Unknown encoding scheme (see TS 23.038) */
+ 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;
+
+ /**
+ * 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.
+ *
+ * @hide pending API Council approval to extend the public API
+ */
+ public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
+
+ /** The maximum number of payload septets per message */
+ public static final int MAX_USER_DATA_SEPTETS = 160;
+
+ /**
+ * The maximum number of payload septets per message if a user data header
+ * is present. This assumes the header only contains the
+ * CONCATENATED_8_BIT_REFERENCE element.
+ */
+ public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
+
+ /** Contains actual SmsMessage. Only public for debugging and for framework layer.
+ * {@hide}
+ */
+ public SmsMessageBase mWrappedSmsMessage;
+
+ public static class SubmitPdu extends SubmitPduBase {
+
+ //Constructor
+ public SubmitPdu() {
+ }
+
+ /* {@hide} */
+ protected SubmitPdu(SubmitPduBase spb) {
+ this.encodedMessage = spb.encodedMessage;
+ this.encodedScAddress = spb.encodedScAddress;
+ }
+
+ }
+
+ // Constructor
+ public SmsMessage() {
+ this(getSmsFacility());
+ }
+
+ private SmsMessage(SmsMessageBase smb) {
+ mWrappedSmsMessage = smb;
+ }
+
+ /**
+ * Create an SmsMessage from a raw PDU.
+ */
+ public static SmsMessage createFromPdu(byte[] pdu) {
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
+ }
+
+ return new SmsMessage(wrappedMessage);
+ }
+
+ /**
+ * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
+ * +CMT unsolicited response (PDU mode, of course)
+ * +CMT: [&lt;alpha>],<length><CR><LF><pdu>
+ *
+ * Only public for debugging and for RIL
+ *
+ * {@hide}
+ */
+ public static SmsMessage newFromCMT(String[] lines){
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCMT(lines);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCMT(lines);
+ }
+
+ return new SmsMessage(wrappedMessage);
+ }
+
+ /** @hide */
+ protected static SmsMessage newFromCMTI(String line) {
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCMTI(line);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCMTI(line);
+ }
+
+ return new SmsMessage(wrappedMessage);
+ }
+
+ /** @hide */
+ public static SmsMessage newFromCDS(String line) {
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCDS(line);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCDS(line);
+ }
+
+ return new SmsMessage(wrappedMessage);
+ }
+
+ /** @hide */
+ public static SmsMessage newFromParcel(Parcel p) {
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromParcel(p);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromParcel(p);
+ }
+
+ return new SmsMessage(wrappedMessage);
+ }
+
+ /**
+ * Create an SmsMessage from an SMS EF record.
+ *
+ * @param index Index of SMS record. This should be index in ArrayList
+ * returned by SmsManager.getAllMessagesFromSim + 1.
+ * @param data Record data.
+ * @return An SmsMessage representing the record.
+ *
+ * @hide
+ */
+ public static SmsMessage createFromEfRecord(int index, byte[] data) {
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromEfRecord(
+ index, data);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromEfRecord(
+ index, data);
+ }
+
+ return new SmsMessage(wrappedMessage);
+ }
+
+ /**
+ * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
+ * length in bytes (not hex chars) less the SMSC header
+ */
+ public static int getTPLayerLengthForPDU(String pdu) {
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ return com.android.internal.telephony.cdma.SmsMessage.getTPLayerLengthForPDU(pdu);
+ } else {
+ return com.android.internal.telephony.gsm.SmsMessage.getTPLayerLengthForPDU(pdu);
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @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(String messageBody, boolean use7bitOnly) {
+ int ret[] = new int[4];
+
+ 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] = septets % MAX_USER_DATA_SEPTETS_WITH_HEADER;
+ } else {
+ ret[0] = 1;
+ ret[2] = MAX_USER_DATA_SEPTETS - septets;
+ }
+ ret[3] = ENCODING_7BIT;
+ } catch (EncodeException ex) {
+ // fall back to USC-2
+ int octets = messageBody.length() * 2;
+ ret[1] = octets;
+ 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] = octets % MAX_USER_DATA_BYTES_WITH_HEADER;
+ } else {
+ ret[0] = 1;
+ ret[2] = MAX_USER_DATA_BYTES - octets;
+ }
+ ret[3] = ENCODING_16BIT;
+ }
+
+ return ret;
+ }
+
+ /**
+ * 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.
+ * @hide
+ */
+ public static SubmitPdu getSubmitPdu(String scAddress,
+ String destinationAddress, String message,
+ boolean statusReportRequested, byte[] header) {
+ SubmitPduBase spb;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, message, statusReportRequested, header);
+ } else {
+ spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, message, statusReportRequested, header);
+ }
+
+ return new SubmitPdu(spb);
+ }
+
+ /**
+ * 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) {
+ SubmitPduBase spb;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, message, statusReportRequested);
+ } else {
+ spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, message, statusReportRequested);
+ }
+
+ return new SubmitPdu(spb);
+ }
+
+ /**
+ * 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
+ * destination
+ * @param data the dat 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 destinationAddress, short destinationPort, byte[] data,
+ boolean statusReportRequested) {
+ SubmitPduBase spb;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, destinationPort, data, statusReportRequested);
+ } else {
+ spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, destinationPort, data, statusReportRequested);
+ }
+
+ return new SubmitPdu(spb);
+ }
+
+ /**
+ * Returns the address of the SMS service center that relayed this message
+ * or null if there is none.
+ */
+ public String getServiceCenterAddress() {
+ return mWrappedSmsMessage.getServiceCenterAddress();
+ }
+
+ /**
+ * Returns the originating address (sender) of this SMS message in String
+ * form or null if unavailable
+ */
+ public String getOriginatingAddress() {
+ return mWrappedSmsMessage.getOriginatingAddress();
+ }
+
+ /**
+ * Returns the originating address, or email from address if this message
+ * was from an email gateway. Returns null if originating address
+ * unavailable.
+ */
+ public String getDisplayOriginatingAddress() {
+ return mWrappedSmsMessage.getDisplayOriginatingAddress();
+ }
+
+ /**
+ * Returns the message body as a String, if it exists and is text based.
+ * @return message body is there is one, otherwise null
+ */
+ public String getMessageBody() {
+ return mWrappedSmsMessage.getMessageBody();
+ }
+
+ /**
+ * Returns the class of this message.
+ */
+ public MessageClass getMessageClass() {
+ return mWrappedSmsMessage.getMessageClass();
+ }
+
+ /**
+ * Returns the message body, or email message body if this message was from
+ * an email gateway. Returns null if message body unavailable.
+ */
+ public String getDisplayMessageBody() {
+ return mWrappedSmsMessage.getDisplayMessageBody();
+ }
+
+ /**
+ * Unofficial convention of a subject line enclosed in parens empty string
+ * if not present
+ */
+ public String getPseudoSubject() {
+ return mWrappedSmsMessage.getPseudoSubject();
+ }
+
+ /**
+ * Returns the service centre timestamp in currentTimeMillis() format
+ */
+ public long getTimestampMillis() {
+ return mWrappedSmsMessage.getTimestampMillis();
+ }
+
+ /**
+ * Returns true if message is an email.
+ *
+ * @return true if this message came through an email gateway and email
+ * sender / subject / parsed body are available
+ */
+ public boolean isEmail() {
+ return mWrappedSmsMessage.isEmail();
+ }
+
+ /**
+ * @return if isEmail() is true, body of the email sent through the gateway.
+ * null otherwise
+ */
+ public String getEmailBody() {
+ return mWrappedSmsMessage.getEmailBody();
+ }
+
+ /**
+ * @return if isEmail() is true, email from address of email sent through
+ * the gateway. null otherwise
+ */
+ public String getEmailFrom() {
+ return mWrappedSmsMessage.getEmailFrom();
+ }
+
+ /**
+ * Get protocol identifier.
+ */
+ public int getProtocolIdentifier() {
+ return mWrappedSmsMessage.getProtocolIdentifier();
+ }
+
+ /**
+ * See TS 23.040 9.2.3.9 returns true if this is a "replace short message"
+ * SMS
+ */
+ public boolean isReplace() {
+ return mWrappedSmsMessage.isReplace();
+ }
+
+ /**
+ * Returns true for CPHS MWI toggle message.
+ *
+ * @return true if this is a CPHS MWI toggle message See CPHS 4.2 section
+ * B.4.2
+ */
+ public boolean isCphsMwiMessage() {
+ return mWrappedSmsMessage.isCphsMwiMessage();
+ }
+
+ /**
+ * returns true if this message is a CPHS voicemail / message waiting
+ * indicator (MWI) clear message
+ */
+ public boolean isMWIClearMessage() {
+ return mWrappedSmsMessage.isMWIClearMessage();
+ }
+
+ /**
+ * returns true if this message is a CPHS voicemail / message waiting
+ * indicator (MWI) set message
+ */
+ public boolean isMWISetMessage() {
+ return mWrappedSmsMessage.isMWISetMessage();
+ }
+
+ /**
+ * returns true if this message is a "Message Waiting Indication Group:
+ * Discard Message" notification and should not be stored.
+ */
+ public boolean isMwiDontStore() {
+ return mWrappedSmsMessage.isMwiDontStore();
+ }
+
+ /**
+ * returns the user data section minus the user data header if one was
+ * present.
+ */
+ public byte[] getUserData() {
+ return mWrappedSmsMessage.getUserData();
+ }
+
+ /* Not part of the SDK interface and only needed by specific classes:
+ protected SmsHeader getUserDataHeader()
+ */
+
+ /**
+ * Returns the raw PDU for the message.
+ *
+ * @return the raw PDU for the message.
+ */
+ public byte[] getPdu() {
+ return mWrappedSmsMessage.getPdu();
+ }
+
+ /**
+ * Returns the status of the message on the SIM (read, unread, sent, unsent).
+ *
+ * @return the status of the message on the SIM. These are:
+ * SmsManager.STATUS_ON_SIM_FREE
+ * SmsManager.STATUS_ON_SIM_READ
+ * SmsManager.STATUS_ON_SIM_UNREAD
+ * SmsManager.STATUS_ON_SIM_SEND
+ * SmsManager.STATUS_ON_SIM_UNSENT
+ * @deprecated Use getStatusOnIcc instead.
+ */
+ @Deprecated public int getStatusOnSim() {
+ return mWrappedSmsMessage.getStatusOnIcc();
+ }
+
+ /**
+ * Returns the status of the message on the ICC (read, unread, sent, unsent).
+ *
+ * @return the status of the message on the ICC. These are:
+ * SmsManager.STATUS_ON_ICC_FREE
+ * SmsManager.STATUS_ON_ICC_READ
+ * SmsManager.STATUS_ON_ICC_UNREAD
+ * SmsManager.STATUS_ON_ICC_SEND
+ * SmsManager.STATUS_ON_ICC_UNSENT
+ */
+ public int getStatusOnIcc() {
+
+ return mWrappedSmsMessage.getStatusOnIcc();
+ }
+
+ /**
+ * Returns the record index of the message on the SIM (1-based index).
+ * @return the record index of the message on the SIM, or -1 if this
+ * SmsMessage was not created from a SIM SMS EF record.
+ * @deprecated Use getIndexOnIcc instead.
+ */
+ @Deprecated public int getIndexOnSim() {
+ return mWrappedSmsMessage.getIndexOnIcc();
+ }
+
+ /**
+ * Returns the record index of the message on the ICC (1-based index).
+ * @return the record index of the message on the ICC, or -1 if this
+ * SmsMessage was not created from a ICC SMS EF record.
+ */
+ public int getIndexOnIcc() {
+
+ return mWrappedSmsMessage.getIndexOnIcc();
+ }
+
+ /**
+ * GSM:
+ * For an SMS-STATUS-REPORT message, this returns the status field from
+ * the status report. This field indicates the status of a previously
+ * submitted SMS, if requested. See TS 23.040, 9.2.3.15 TP-Status for a
+ * description of values.
+ * CDMA:
+ * For not interfering with status codes from GSM, the value is
+ * shifted to the bits 31-16.
+ * The value is composed of an error class (bits 25-24) and a status code (bits 23-16).
+ * Possible codes are described in C.S0015-B, v2.0, 4.5.21.
+ *
+ * @return 0 indicates the previously sent message was received.
+ * See TS 23.040, 9.9.2.3.15 and C.S0015-B, v2.0, 4.5.21
+ * for a description of other possible values.
+ */
+ public int getStatus() {
+ return mWrappedSmsMessage.getStatus();
+ }
+
+ /**
+ * Return true iff the message is a SMS-STATUS-REPORT message.
+ */
+ public boolean isStatusReportMessage() {
+ return mWrappedSmsMessage.isStatusReportMessage();
+ }
+
+ /**
+ * Returns true iff the <code>TP-Reply-Path</code> bit is set in
+ * this message.
+ */
+ public boolean isReplyPathPresent() {
+ return mWrappedSmsMessage.isReplyPathPresent();
+ }
+
+ /** This method returns the reference to a specific
+ * SmsMessage object, which is used for accessing its static methods.
+ * @return Specific SmsMessage.
+ */
+ private static final SmsMessageBase getSmsFacility(){
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+ if (PHONE_TYPE_CDMA == activePhone) {
+ return new com.android.internal.telephony.cdma.SmsMessage();
+ } else {
+ return new com.android.internal.telephony.gsm.SmsMessage();
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 82e612073df7..55983d19a385 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -21,30 +21,31 @@ import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
-import android.telephony.CellLocation;
+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.RILConstants;
import com.android.internal.telephony.TelephonyProperties;
/**
* Provides access to information about the telephony services on
* the device. Applications can use the methods in this class to
* determine telephony services and states, as well as to access some
- * types of subscriber information. Applications can also register
- * a listener to receive notification of telephony state changes.
+ * types of subscriber information. Applications can also register
+ * a listener to receive notification of telephony state changes.
* <p>
* You do not instantiate this class directly; instead, you retrieve
- * a reference to an instance through
+ * a reference to an instance through
* {@link android.content.Context#getSystemService
* Context.getSystemService(Context.TELEPHONY_SERVICE)}.
* <p>
* Note that acess to some telephony information is
- * permission-protected. Your application cannot access the protected
- * information unless it has the appropriate permissions declared in
- * its manifest file. Where permissions apply, they are noted in the
- * the methods through which you access the protected information.
+ * permission-protected. Your application cannot access the protected
+ * information unless it has the appropriate permissions declared in
+ * its manifest file. Where permissions apply, they are noted in the
+ * the methods through which you access the protected information.
*/
public class TelephonyManager {
private static final String TAG = "TelephonyManager";
@@ -77,10 +78,10 @@ public class TelephonyManager {
//
/**
- * Returns the software version number for the device, for example,
+ * Returns the software version number for the device, for example,
* the IMEI/SV for GSM phones.
*
- * <p>Requires Permission:
+ * <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getDeviceSoftwareVersion() {
@@ -92,10 +93,10 @@ public class TelephonyManager {
}
/**
- * Returns the unique device ID, for example,the IMEI for GSM
+ * Returns the unique device ID, for example, the IMEI for GSM and the MEID for CDMA
* phones.
*
- * <p>Requires Permission:
+ * <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getDeviceId() {
@@ -115,9 +116,7 @@ public class TelephonyManager {
public CellLocation getCellLocation() {
try {
Bundle bundle = getITelephony().getCellLocation();
- // TODO remove cdma and gsmCellLocation make CellLocation
- // active and define different impl in the phone
- return CellLocation.newFromBundle(bundle);
+ return CellLocation.newFromBundle(bundle);
} catch (RemoteException ex) {
}
return null;
@@ -127,7 +126,7 @@ public class TelephonyManager {
* Enables location update notifications. {@link PhoneStateListener#onCellLocationChanged
* PhoneStateListener.onCellLocationChanged} will be called on location updates.
*
- * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
+ * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
* CONTROL_LOCATION_UPDATES}
*
* @hide
@@ -166,23 +165,36 @@ public class TelephonyManager {
public static final int PHONE_TYPE_GSM = 1;
/**
- * Returns a constant indicating the device phone type.
- *
+ * CDMA phone
+ */
+ public static final int PHONE_TYPE_CDMA = 2;
+
+ /**
+ * Returns a constant indicating the device phone type.
+ *
* @see #PHONE_TYPE_NONE
* @see #PHONE_TYPE_GSM
+ * @see #PHONE_TYPE_CDMA
*/
public int getPhoneType() {
- // in the future, we should really check this
- return PHONE_TYPE_GSM;
+ try{
+ if(getITelephony().getActivePhoneType() == RILConstants.CDMA_PHONE) {
+ return PHONE_TYPE_CDMA;
+ } else {
+ return PHONE_TYPE_GSM;
+ }
+ }catch(RemoteException ex){
+ return PHONE_TYPE_NONE;
+ }
}
//
- //
+ //
// Current Network
//
//
- /**
+ /**
* Returns the alphabetic name of current registered operator.
* <p>
* Availability: Only when user is registered to a network
@@ -191,7 +203,7 @@ public class TelephonyManager {
return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ALPHA);
}
- /**
+ /**
* Returns the numeric name (MCC+MNC) of current registered operator.
* <p>
* Availability: Only when user is registered to a network
@@ -200,7 +212,7 @@ public class TelephonyManager {
return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
}
- /**
+ /**
* Returns true if the device is considered roaming on the current
* network, for GSM purposes.
* <p>
@@ -210,7 +222,7 @@ public class TelephonyManager {
return "true".equals(SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
}
- /**
+ /**
* Returns the ISO country code equivilent of the current registered
* operator's MCC (Mobile Country Code).
* <p>
@@ -237,7 +249,7 @@ public class TelephonyManager {
public static final int NETWORK_TYPE_1xRTT = 7;
/**
- * Returns a constant indicating the radio technology (network type)
+ * Returns a constant indicating the radio technology (network type)
* currently in use on the device.
*
* @see #NETWORK_TYPE_UNKNOWN
@@ -285,7 +297,7 @@ public class TelephonyManager {
/** SIM card state: Unknown. Signifies that the SIM is in transition
* between states. For example, when the user inputs the SIM pin
- * under PIN_REQUIRED state, a query for sim status returns
+ * under PIN_REQUIRED state, a query for sim status returns
* this state before turning to SIM_STATE_READY. */
public static final int SIM_STATE_UNKNOWN = 0;
/** SIM card state: no SIM card is available in the device */
@@ -298,11 +310,11 @@ public class TelephonyManager {
public static final int SIM_STATE_NETWORK_LOCKED = 4;
/** SIM card state: Ready */
public static final int SIM_STATE_READY = 5;
-
- /**
- * Returns a constant indicating the state of the
+
+ /**
+ * Returns a constant indicating the state of the
* device SIM card.
- *
+ *
* @see #SIM_STATE_UNKNOWN
* @see #SIM_STATE_ABSENT
* @see #SIM_STATE_PIN_REQUIRED
@@ -332,7 +344,7 @@ public class TelephonyManager {
}
}
- /**
+ /**
* Returns the MCC+MNC (mobile country code + mobile network code) of the
* provider of the SIM. 5 or 6 decimal digits.
* <p>
@@ -341,31 +353,31 @@ public class TelephonyManager {
* @see #getSimState
*/
public String getSimOperator() {
- return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC);
+ return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC);
}
- /**
- * Returns the Service Provider Name (SPN).
+ /**
+ * Returns the Service Provider Name (SPN).
* <p>
* Availability: SIM state must be {@link #SIM_STATE_READY}
*
* @see #getSimState
*/
public String getSimOperatorName() {
- return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_ALPHA);
+ return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA);
}
- /**
+ /**
* Returns the ISO country code equivalent for the SIM provider's country code.
*/
public String getSimCountryIso() {
- return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_ISO_COUNTRY);
+ return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY);
}
/**
* Returns the serial number of the SIM, if applicable.
* <p>
- * Requires Permission:
+ * Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getSimSerialNumber() {
@@ -385,7 +397,7 @@ public class TelephonyManager {
/**
* Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
* <p>
- * Requires Permission:
+ * Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getSubscriberId() {
@@ -397,10 +409,10 @@ public class TelephonyManager {
}
/**
- * Returns the phone number string for line 1, for example, the MSISDN
+ * Returns the phone number string for line 1, for example, the MSISDN
* for a GSM phone.
* <p>
- * Requires Permission:
+ * Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getLine1Number() {
@@ -412,9 +424,9 @@ public class TelephonyManager {
}
/**
- * Returns the alphabetic identifier associated with the line 1 number.
+ * Returns the alphabetic identifier associated with the line 1 number.
* <p>
- * Requires Permission:
+ * Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
* @hide
* nobody seems to call this.
@@ -430,7 +442,7 @@ public class TelephonyManager {
/**
* Returns the voice mail number.
* <p>
- * Requires Permission:
+ * Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getVoiceMailNumber() {
@@ -445,7 +457,7 @@ public class TelephonyManager {
* Retrieves the alphabetic identifier associated with the voice
* mail number.
* <p>
- * Requires Permission:
+ * Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getVoiceMailAlphaTag() {
@@ -465,10 +477,10 @@ public class TelephonyManager {
/** Device call state: No activity. */
public static final int CALL_STATE_IDLE = 0;
/** Device call state: Ringing. A new call arrived and is
- * ringing or waiting. In the latter case, another call is
+ * ringing or waiting. In the latter case, another call is
* already active. */
public static final int CALL_STATE_RINGING = 1;
- /** Device call state: Off-hook. At least one call exists
+ /** Device call state: Off-hook. At least one call exists
* that is dialing, active, or on hold, and no calls are ringing
* or waiting. */
public static final int CALL_STATE_OFFHOOK = 2;
@@ -519,13 +531,13 @@ public class TelephonyManager {
public static final int DATA_CONNECTING = 1;
/** Data connection state: Connected. IP traffic should be available. */
public static final int DATA_CONNECTED = 2;
- /** Data connection state: Suspended. The connection is up, but IP
- * traffic is temporarily unavailable. For example, in a 2G network,
+ /** Data connection state: Suspended. The connection is up, but IP
+ * traffic is temporarily unavailable. For example, in a 2G network,
* data activity may be suspended when a voice call arrives. */
public static final int DATA_SUSPENDED = 3;
/**
- * Returns a constant indicating the current data connection state
+ * Returns a constant indicating the current data connection state
* (cellular).
*
* @see #DATA_DISCONNECTED
@@ -553,26 +565,26 @@ public class TelephonyManager {
//
/**
- * Registers a listener object to receive notification of changes
- * in specified telephony states.
+ * Registers a listener object to receive notification of changes
+ * in specified telephony states.
* <p>
* To register a listener, pass a {@link PhoneStateListener}
- * and specify at least one telephony state of interest in
- * the events argument.
- *
+ * and specify at least one telephony state of interest in
+ * the events argument.
+ *
* At registration, and when a specified telephony state
- * changes, the telephony manager invokes the appropriate
- * callback method on the listener object and passes the
+ * changes, the telephony manager invokes the appropriate
+ * callback method on the listener object and passes the
* current (udpated) values.
* <p>
* To unregister a listener, pass the listener object and set the
- * events argument to
+ * events argument to
* {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
- *
+ *
* @param listener The {@link PhoneStateListener} object to register
* (or unregister)
* @param events The telephony state(s) of interest to the listener,
- * as a bitwise-OR combination of {@link PhoneStateListener}
+ * as a bitwise-OR combination of {@link PhoneStateListener}
* LISTEN_ flags.
*/
public void listen(PhoneStateListener listener, int events) {
@@ -624,8 +636,8 @@ public class TelephonyManager {
* These have not been implemented because they're not public IMHO. -joeo
*/
- /*
- * Baseband version
+ /*
+ * Baseband version
* Availability: property is available any time radio is on
*/
/*
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index 7cf8a9a66b0a..18e62f836dfb 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -78,7 +78,7 @@ public class CdmaCellLocation extends CellLocation {
/**
* Set the cell location data.
*/
- public void setCellLocationData(int baseStationId, int baseStationLatitude,
+ public void setCellLocationData(int baseStationId, int baseStationLatitude,
int baseStationLongitude) {
// The following values have to be written in the correct sequence
this.mBaseStationId = baseStationId;
@@ -114,7 +114,7 @@ public class CdmaCellLocation extends CellLocation {
@Override
public String toString() {
return "[" + this.mBaseStationId + ","
- + this.mBaseStationLatitude + ","
+ + this.mBaseStationLatitude + ","
+ this.mBaseStationLongitude + "]";
}
diff --git a/telephony/java/android/telephony/cdma/TtyIntent.java b/telephony/java/android/telephony/cdma/TtyIntent.java
deleted file mode 100644
index 4b8759c214d9..000000000000
--- a/telephony/java/android/telephony/cdma/TtyIntent.java
+++ /dev/null
@@ -1,98 +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 android.telephony.cdma;
-
-/*import android.os.RemoteException;
-import android.util.Log;
-import com.android.internal.telephony.Phone;
-import android.os.Message;
-import android.os.Handler;
-import android.os.AsyncResult;
-*/
-
-public class TtyIntent {
-
- private static final String TAG = "TtyIntent";
-
-// private Phone mPhone;
-// private boolean mTTYenabled = false;
-
- /** Event for TTY mode change */
-// private static final int EVENT_TTY_EXECUTED = 1;
-
- /**
- * Broadcast intent action indicating that the TTY has either been
- * enabled or disabled. An intent extra provides this state as a boolean,
- * where {@code true} means enabled.
- * @see #TTY_ENABLED
- *
- * {@hide}
- */
- public static final String TTY_ENABLED_CHANGE_ACTION =
- "android.telephony.cdma.intent.action.TTY_ENABLED_CHANGE";
-
- /**
- * The lookup key for a boolean that indicates whether TTY mode is enabled or
- * disabled. {@code true} means TTY mode is enabled. Retrieve it with
- * {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- *
- * {@hide}
- */
- public static final String TTY_ENABLED = "ttyEnabled";
-
- /**
- * Get the current status of TTY status.
- *
- * @return true if TTY Mode enabled, false otherwise.
- */
-/* public boolean isEnabled() {
- mPhone.queryTTYModeEnabled(Message.obtain(mQueryTTYComplete, EVENT_TTY_EXECUTED));
-
- return mTTYenabled;
- }
-
- private Handler mQueryTTYComplete = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_TTY_EXECUTED:
- //handleQueryTTYModeMessage((AsyncResult) msg.obj);
- AsyncResult ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- Log.w(TAG, "handleMessage: Error getting TTY enable state.");
- }
- else {
- int ttyArray[] = (int[]) ar.result;
- if (ttyArray[0] == 1) {
- //TTY Mode enabled
- mTTYenabled = true;
- Log.w(TAG, "handleMessage: mTTYenabled: " + mTTYenabled);
- }
- else {
- // TTY disabled
- mTTYenabled = false;
- Log.w(TAG, "handleMessage: mTTYenabled: " + mTTYenabled);
- }
- }
- break;
- default:
- // TODO: should never reach this, may want to throw exception
- }
- }
- };
- */
-}
diff --git a/telephony/java/android/telephony/cdma/package.html b/telephony/java/android/telephony/cdma/package.html
new file mode 100644
index 000000000000..ee4af5e30f09
--- /dev/null
+++ b/telephony/java/android/telephony/cdma/package.html
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+Provides APIs for utilizing CDMA-specific telephony features.
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/telephony/java/android/telephony/gsm/GsmCellLocation.java b/telephony/java/android/telephony/gsm/GsmCellLocation.java
index 7a5218c1ff17..637a11cb819f 100644
--- a/telephony/java/android/telephony/gsm/GsmCellLocation.java
+++ b/telephony/java/android/telephony/gsm/GsmCellLocation.java
@@ -80,7 +80,7 @@ public class GsmCellLocation extends CellLocation {
@Override
public boolean equals(Object o) {
GsmCellLocation s;
-
+
try {
s = (GsmCellLocation)o;
} catch (ClassCastException ex) {
@@ -98,7 +98,7 @@ public class GsmCellLocation extends CellLocation {
public String toString() {
return "["+ mLac + "," + mCid + "]";
}
-
+
/**
* Test whether two objects hold the same data values or both are null
*
diff --git a/telephony/java/android/telephony/gsm/SmsManager.java b/telephony/java/android/telephony/gsm/SmsManager.java
index fd7521199f47..cdd707e629a2 100644
--- a/telephony/java/android/telephony/gsm/SmsManager.java
+++ b/telephony/java/android/telephony/gsm/SmsManager.java
@@ -17,28 +17,35 @@
package android.telephony.gsm;
import android.app.PendingIntent;
-import android.os.RemoteException;
-import android.os.IServiceManager;
-import android.os.ServiceManager;
-import android.os.ServiceManagerNative;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.gsm.EncodeException;
-import com.android.internal.telephony.gsm.GsmAlphabet;
-import com.android.internal.telephony.gsm.ISms;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.gsm.SmsRawData;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+
/**
* Manages SMS operations such as sending data, text, and pdu SMS messages.
* Get this object by calling the static method SmsManager.getDefault().
+ * @deprecated Replaced by android.telephony.SmsManager that supports both GSM and CDMA.
*/
-public final class SmsManager {
+@Deprecated public final class SmsManager {
private static SmsManager sInstance;
+ private android.telephony.SmsManager mSmsMgrProxy;
+
+ /** Get the default instance of the SmsManager
+ *
+ * @return the default instance of the SmsManager
+ * @deprecated Use android.telephony.SmsManager.
+ */
+ @Deprecated
+ public static final SmsManager getDefault() {
+ if (sInstance == null) {
+ sInstance = new SmsManager();
+ }
+ return sInstance;
+ }
+
+ private SmsManager() {
+ mSmsMgrProxy = android.telephony.SmsManager.getDefault();
+ }
/**
* Send a text based SMS.
@@ -55,28 +62,21 @@ public final class SmsManager {
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
* The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applicaitons,
+ * is NULL the caller will be checked against all unknown applications,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*
* @throws IllegalArgumentException if destinationAddress or text are empty
+ * @deprecated Use android.telephony.SmsManager.
*/
- public void sendTextMessage(
+ @Deprecated
+ public final void sendTextMessage(
String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
- if (TextUtils.isEmpty(destinationAddress)) {
- throw new IllegalArgumentException("Invalid destinationAddress");
- }
-
- if (TextUtils.isEmpty(text)) {
- throw new IllegalArgumentException("Invalid message body");
- }
-
- SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(
- scAddress, destinationAddress, text, (deliveryIntent != null));
- sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
+ mSmsMgrProxy.sendTextMessage(destinationAddress, scAddress, text,
+ sentIntent, deliveryIntent);
}
/**
@@ -86,56 +86,24 @@ public final class SmsManager {
* @param text the original message. Must not be null.
* @return an <code>ArrayList</code> of strings that, in order,
* comprise the original message
+ * @deprecated Use android.telephony.SmsManager.
*/
- 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 == SmsMessage.ENCODING_7BIT)?
- SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER
- : SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
- } else {
- limit = (encodingType == SmsMessage.ENCODING_7BIT)?
- SmsMessage.MAX_USER_DATA_SEPTETS: SmsMessage.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;
+ @Deprecated
+ public final ArrayList<String> divideMessage(String text) {
+ return mSmsMgrProxy.divideMessage(text);
}
/**
* Send a multi-part text based SMS. The callee should have already
* divided the message into correctly sized parts by calling
* <code>divideMessage</code>.
- *
+ *
* @param destinationAddress the address to send the message to
* @param scAddress is the service center address or null to use
* the current default SMSC
* @param parts an <code>ArrayList</code> of strings that, in order,
* comprise the original message
- * @param sentIntents if not null, an <code>ArrayList</code> of
+ * @param sentIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been sent.
* The result code will be <code>Activity.RESULT_OK<code> for success,
@@ -146,44 +114,21 @@ public final class SmsManager {
* The per-application based SMS control checks sentIntent. If sentIntent
* is NULL the caller will be checked against all unknown applicaitons,
* which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntents if not null, an <code>ArrayList</code> of
+ * @param deliveryIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been delivered
* to the recipient. The raw pdu of the status report is in the
* extended data ("pdu").
+ *
+ * @throws IllegalArgumentException if destinationAddress or data are empty
+ * @deprecated Use android.telephony.SmsManager.
*/
- public void sendMultipartTextMessage(
+ @Deprecated
+ public final void sendMultipartTextMessage(
String destinationAddress, String scAddress, ArrayList<String> parts,
ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
- if (TextUtils.isEmpty(destinationAddress)) {
- throw new IllegalArgumentException("Invalid destinationAddress");
- }
- if (parts == null || parts.size() < 1) {
- throw new IllegalArgumentException("Invalid message body");
- }
-
- if (parts.size() > 1) {
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- simISms.sendMultipartText(destinationAddress, scAddress, parts,
- sentIntents, deliveryIntents);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
- } else {
- PendingIntent sentIntent = null;
- PendingIntent deliveryIntent = null;
- if (sentIntents != null && sentIntents.size() > 0) {
- sentIntent = sentIntents.get(0);
- }
- if (deliveryIntents != null && deliveryIntents.size() > 0) {
- deliveryIntent = deliveryIntents.get(0);
- }
- sendTextMessage(destinationAddress, scAddress, parts.get(0),
- sentIntent, deliveryIntent);
- }
+ mSmsMgrProxy.sendMultipartTextMessage(destinationAddress, scAddress, parts,
+ sentIntents, deliveryIntents);
}
/**
@@ -209,70 +154,14 @@ public final class SmsManager {
* raw pdu of the status report is in the extended data ("pdu").
*
* @throws IllegalArgumentException if destinationAddress or data are empty
+ * @deprecated Use android.telephony.SmsManager.
*/
- public void sendDataMessage(
+ @Deprecated
+ public final void sendDataMessage(
String destinationAddress, String scAddress, short destinationPort,
byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
- if (TextUtils.isEmpty(destinationAddress)) {
- throw new IllegalArgumentException("Invalid destinationAddress");
- }
-
- if (data == null || data.length == 0) {
- throw new IllegalArgumentException("Invalid message data");
- }
-
- SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
- destinationPort, data, (deliveryIntent != null));
- sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
- }
-
- /**
- * Send a raw SMS PDU.
- *
- * @param smsc the SMSC to send the message through, or NULL for the
- * default SMSC
- * @param pdu the raw PDU to send
- * @param sentIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is sucessfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:
- * <code>RESULT_ERROR_GENERIC_FAILURE</code>
- * <code>RESULT_ERROR_RADIO_OFF</code>
- * <code>RESULT_ERROR_NULL_PDU</code>.
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applicaitons,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- *
- */
- private void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent) {
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- simISms.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
- }
-
- /**
- * Get the default instance of the SmsManager
- *
- * @return the default instance of the SmsManager
- */
- public static SmsManager getDefault() {
- if (sInstance == null) {
- sInstance = new SmsManager();
- }
- return sInstance;
- }
-
- private SmsManager() {
- // nothing to see here
+ mSmsMgrProxy.sendDataMessage(destinationAddress, scAddress, destinationPort,
+ data, sentIntent, deliveryIntent);
}
/**
@@ -283,22 +172,12 @@ public final class SmsManager {
* @param status message status (STATUS_ON_SIM_READ, STATUS_ON_SIM_UNREAD,
* STATUS_ON_SIM_SENT, STATUS_ON_SIM_UNSENT)
* @return true for success
- *
+ * @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
- public boolean copyMessageToSim(byte[] smsc, byte[] pdu, int status) {
- boolean success = false;
-
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- success = simISms.copyMessageToSimEf(status, pdu, smsc);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return success;
+ @Deprecated
+ public final boolean copyMessageToSim(byte[] smsc, byte[] pdu, int status) {
+ return mSmsMgrProxy.copyMessageToIcc(smsc, pdu, status);
}
/**
@@ -306,26 +185,12 @@ public final class SmsManager {
*
* @param messageIndex is the record index of the message on SIM
* @return true for success
- *
+ * @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
- public boolean
- deleteMessageFromSim(int messageIndex) {
- boolean success = false;
- byte[] pdu = new byte[IccConstants.SMS_RECORD_LENGTH-1];
- Arrays.fill(pdu, (byte)0xff);
-
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- success = simISms.updateMessageOnSimEf(messageIndex,
- STATUS_ON_SIM_FREE, pdu);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return success;
+ @Deprecated
+ public final boolean deleteMessageFromSim(int messageIndex) {
+ return mSmsMgrProxy.deleteMessageFromIcc(messageIndex);
}
/**
@@ -337,97 +202,59 @@ public final class SmsManager {
* STATUS_ON_SIM_UNSENT, STATUS_ON_SIM_FREE)
* @param pdu the raw PDU to store
* @return true for success
- *
+ * @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
- public boolean updateMessageOnSim(int messageIndex, int newStatus,
- byte[] pdu) {
- boolean success = false;
-
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- success = simISms.updateMessageOnSimEf(messageIndex, newStatus, pdu);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return success;
+ @Deprecated
+ public final boolean updateMessageOnSim(int messageIndex, int newStatus, byte[] pdu) {
+ return mSmsMgrProxy.updateMessageOnIcc(messageIndex, newStatus, pdu);
}
-
/**
* Retrieves all messages currently stored on SIM.
- *
* @return <code>ArrayList</code> of <code>SmsMessage</code> objects
- *
+ * @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
- public ArrayList<SmsMessage> getAllMessagesFromSim() {
- List<SmsRawData> records = null;
+ @Deprecated
+ public final ArrayList<android.telephony.SmsMessage> getAllMessagesFromSim() {
+ return mSmsMgrProxy.getAllMessagesFromIcc();
+ }
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- records = simISms.getAllMessagesFromSimEf();
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return createMessageListFromRawRecords(records);
- }
+ /** Free space (TS 51.011 10.5.3).
+ * @deprecated Use android.telephony.SmsManager. */
+ @Deprecated static public final int STATUS_ON_SIM_FREE = 0;
- /**
- * Create a list of <code>SmsMessage</code>s from a list of RawSmsData
- * records returned by <code>getAllMessagesFromSim()</code>
- *
- * @param records SMS EF records, returned by
- * <code>getAllMessagesFromSim</code>
- * @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
- */
- private ArrayList<SmsMessage> createMessageListFromRawRecords(List records) {
- ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
- if (records != null) {
- int count = records.size();
- for (int i = 0; i < count; i++) {
- SmsRawData data = (SmsRawData)records.get(i);
- // List contains all records, including "free" records (null)
- if (data != null) {
- SmsMessage sms =
- SmsMessage.createFromEfRecord(i+1, data.getBytes());
- messages.add(sms);
- }
- }
- }
- return messages;
- }
+ /** Received and read (TS 51.011 10.5.3).
+ * @deprecated Use android.telephony.SmsManager. */
+ @Deprecated static public final int STATUS_ON_SIM_READ = 1;
- /** Free space (TS 51.011 10.5.3). */
- static public final int STATUS_ON_SIM_FREE = 0;
+ /** Received and unread (TS 51.011 10.5.3).
+ * @deprecated Use android.telephony.SmsManager. */
+ @Deprecated static public final int STATUS_ON_SIM_UNREAD = 3;
- /** Received and read (TS 51.011 10.5.3). */
- static public final int STATUS_ON_SIM_READ = 1;
+ /** Stored and sent (TS 51.011 10.5.3).
+ * @deprecated Use android.telephony.SmsManager. */
+ @Deprecated static public final int STATUS_ON_SIM_SENT = 5;
- /** Received and unread (TS 51.011 10.5.3). */
- static public final int STATUS_ON_SIM_UNREAD = 3;
+ /** Stored and unsent (TS 51.011 10.5.3).
+ * @deprecated Use android.telephony.SmsManager. */
+ @Deprecated static public final int STATUS_ON_SIM_UNSENT = 7;
- /** Stored and sent (TS 51.011 10.5.3). */
- static public final int STATUS_ON_SIM_SENT = 5;
+ /** Generic failure cause
+ * @deprecated Use android.telephony.SmsManager. */
+ @Deprecated static public final int RESULT_ERROR_GENERIC_FAILURE = 1;
- /** Stored and unsent (TS 51.011 10.5.3). */
- static public final int STATUS_ON_SIM_UNSENT = 7;
+ /** Failed because radio was explicitly turned off
+ * @deprecated Use android.telephony.SmsManager. */
+ @Deprecated static public final int RESULT_ERROR_RADIO_OFF = 2;
+ /** Failed because no pdu provided
+ * @deprecated Use android.telephony.SmsManager. */
+ @Deprecated static public final int RESULT_ERROR_NULL_PDU = 3;
- // SMS send failure result codes
+ /** Failed because service is currently unavailable
+ * @deprecated Use android.telephony.SmsManager. */
+ @Deprecated static public final int RESULT_ERROR_NO_SERVICE = 4;
- /** Generic failure cause */
- static public final int RESULT_ERROR_GENERIC_FAILURE = 1;
- /** Failed because radio was explicitly turned off */
- static public final int RESULT_ERROR_RADIO_OFF = 2;
- /** Failed because no pdu provided */
- static public final int RESULT_ERROR_NULL_PDU = 3;
- /** Failed because service is currently unavailable */
- static public final int RESULT_ERROR_NO_SERVICE = 4;
}
diff --git a/telephony/java/android/telephony/gsm/SmsMessage.java b/telephony/java/android/telephony/gsm/SmsMessage.java
index 9ccfa90d2e24..0bc1567e9e93 100644
--- a/telephony/java/android/telephony/gsm/SmsMessage.java
+++ b/telephony/java/android/telephony/gsm/SmsMessage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,323 +16,117 @@
package android.telephony.gsm;
-import android.pim.Time;
-import android.telephony.PhoneNumberUtils;
-import android.util.Config;
-import android.util.Log;
-import android.telephony.PhoneNumberUtils;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.gsm.EncodeException;
-import com.android.internal.telephony.gsm.GsmAlphabet;
-import com.android.internal.telephony.gsm.SmsHeader;
-
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-
-class SmsAddress {
- // From TS 23.040 9.1.2.5 and TS 24.008 table 10.5.118
- static final int TON_UNKNOWN = 0;
-
- static final int TON_INTERNATIONAL = 1;
-
- static final int TON_NATIONAL = 2;
-
- static final int TON_NETWORK = 3;
-
- static final int TON_SUBSCRIBER = 4;
-
- static final int TON_ALPHANUMERIC = 5;
+import android.os.Parcel;
+import android.telephony.TelephonyManager;
- static final int TON_APPREVIATED = 6;
+import com.android.internal.telephony.GsmAlphabet;
+import com.android.internal.telephony.EncodeException;
+import com.android.internal.telephony.SmsMessageBase;
+import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
- static final int OFFSET_ADDRESS_LENGTH = 0;
-
- static final int OFFSET_TOA = 1;
-
- static final int OFFSET_ADDRESS_VALUE = 2;
+import java.util.Arrays;
- int ton;
+import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
- String address;
- byte[] origBytes;
+/**
+ * A Short Message Service message.
+ * @deprecated Replaced by android.telephony.SmsMessage that supports both GSM and CDMA.
+ */
+@Deprecated
+public class SmsMessage {
+ private static final boolean LOCAL_DEBUG = true;
+ private static final String LOG_TAG = "SMS";
/**
- * New SmsAddress from TS 23.040 9.1.2.5 Address Field
- *
- * @param offset the offset of the Address-Length byte
- * @param length the length in bytes rounded up, e.g. "2 +
- * (addressLength + 1) / 2"
+ * SMS Class enumeration.
+ * See TS 23.038.
+ * @deprecated Use android.telephony.SmsMessage.
*/
-
- SmsAddress(byte[] data, int offset, int length) {
- origBytes = new byte[length];
- System.arraycopy(data, offset, origBytes, 0, length);
-
- // addressLength is the count of semi-octets, not bytes
- int addressLength = origBytes[OFFSET_ADDRESS_LENGTH] & 0xff;
-
- int toa = origBytes[OFFSET_TOA] & 0xff;
- ton = 0x7 & (toa >> 4);
-
- // TOA must have its high bit set
- if ((toa & 0x80) != 0x80) {
- throw new RuntimeException("Invalid TOA - high bit must be set");
- }
-
- if (isAlphanumeric()) {
- // An alphanumeric address
- int countSeptets = addressLength * 4 / 7;
-
- address = GsmAlphabet.gsm7BitPackedToString(origBytes,
- OFFSET_ADDRESS_VALUE, countSeptets);
- } else {
- // TS 23.040 9.1.2.5 says
- // that "the MS shall interpret reserved values as 'Unknown'
- // but shall store them exactly as received"
-
- byte lastByte = origBytes[length - 1];
-
- if ((addressLength & 1) == 1) {
- // Make sure the final unused BCD digit is 0xf
- origBytes[length - 1] |= 0xf0;
- }
- address = PhoneNumberUtils.calledPartyBCDToString(origBytes,
- OFFSET_TOA, length - OFFSET_TOA);
-
- // And restore origBytes
- origBytes[length - 1] = lastByte;
- }
- }
-
- public String getAddressString() {
- return address;
+ @Deprecated
+ public enum MessageClass{
+ UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
}
- /**
- * Returns true if this is an alphanumeric addres
+ /** Unknown encoding scheme (see TS 23.038)
+ * @deprecated Use android.telephony.SmsMessage.
*/
- public boolean isAlphanumeric() {
- return ton == TON_ALPHANUMERIC;
- }
-
- public boolean isNetworkSpecific() {
- return ton == TON_NETWORK;
- }
+ @Deprecated public static final int ENCODING_UNKNOWN = 0;
- /**
- * Returns true of this is a valid CPHS voice message waiting indicator
- * address
+ /** 7-bit encoding scheme (see TS 23.038)
+ * @deprecated Use android.telephony.SmsMessage.
*/
- public boolean isCphsVoiceMessageIndicatorAddress() {
- // CPHS-style MWI message
- // See CPHS 4.7 B.4.2.1
- //
- // Basically:
- //
- // - Originating address should be 4 bytes long and alphanumeric
- // - Decode will result with two chars:
- // - Char 1
- // 76543210
- // ^ set/clear indicator (0 = clear)
- // ^^^ type of indicator (000 = voice)
- // ^^^^ must be equal to 0001
- // - Char 2:
- // 76543210
- // ^ line number (0 = line 1)
- // ^^^^^^^ set to 0
- //
- // Remember, since the alpha address is stored in 7-bit compact form,
- // the "line number" is really the top bit of the first address value
- // byte
-
- return (origBytes[OFFSET_ADDRESS_LENGTH] & 0xff) == 4
- && isAlphanumeric() && (origBytes[OFFSET_TOA] & 0x0f) == 0;
- }
+ @Deprecated public static final int ENCODING_7BIT = 1;
- /**
- * Returns true if this is a valid CPHS voice message waiting indicator
- * address indicating a "set" of "indicator 1" of type "voice message
- * waiting"
+ /** 8-bit encoding scheme (see TS 23.038)
+ * @deprecated Use android.telephony.SmsMessage.
*/
- public boolean isCphsVoiceMessageSet() {
- // 0x11 means "set" "voice message waiting" "indicator 1"
- return isCphsVoiceMessageIndicatorAddress()
- && (origBytes[OFFSET_ADDRESS_VALUE] & 0xff) == 0x11;
+ @Deprecated public static final int ENCODING_8BIT = 2;
- }
-
- /**
- * Returns true if this is a valid CPHS voice message waiting indicator
- * address indicationg a "clear" of "indicator 1" of type "voice message
- * waiting"
+ /** 16-bit encoding scheme (see TS 23.038)
+ * @deprecated Use android.telephony.SmsMessage.
*/
- public boolean isCphsVoiceMessageClear() {
- // 0x10 means "clear" "voice message waiting" "indicator 1"
- return isCphsVoiceMessageIndicatorAddress()
- && (origBytes[OFFSET_ADDRESS_VALUE] & 0xff) == 0x10;
+ @Deprecated public static final int ENCODING_16BIT = 3;
- }
-
- public boolean couldBeEmailGateway() {
- // Some carriers seems to send email gateway messages in this form:
- // from: an UNKNOWN TON, 3 or 4 digits long, beginning with a 5
- // PID: 0x00, Data coding scheme 0x03
- // So we just attempt to treat any message from an address length <= 4
- // as an email gateway
-
- return address.length() <= 4;
- }
-
-}
-
-/**
- * A Short Message Service message.
- *
- */
-public class SmsMessage {
- static final String LOG_TAG = "GSM";
-
- /**
- * SMS Class enumeration.
- * See TS 23.038.
- *
+ /** The maximum number of payload bytes per message
+ * @deprecated Use android.telephony.SmsMessage.
*/
- public enum MessageClass {
- UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
- }
-
- /** Unknown encoding scheme (see TS 23.038) */
- 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;
+ @Deprecated public static final int MAX_USER_DATA_BYTES = 140;
/**
* 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.
- *
+ *
+ * @deprecated Use android.telephony.SmsMessage.
* @hide pending API Council approval to extend the public API
*/
- public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
+ @Deprecated public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
- /** The maximum number of payload septets per message */
- public static final int MAX_USER_DATA_SEPTETS = 160;
+ /** The maximum number of payload septets per message
+ * @deprecated Use android.telephony.SmsMessage.
+ */
+ @Deprecated public static final int MAX_USER_DATA_SEPTETS = 160;
/**
* The maximum number of payload septets per message if a user data header
* is present. This assumes the header only contains the
* CONCATENATED_8_BIT_REFERENCE element.
+ * @deprecated Use android.telephony.SmsMessage.
*/
- public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
-
- /** The address of the SMSC. May be null */
- String scAddress;
-
- /** The address of the sender */
- SmsAddress originatingAddress;
-
- /** The message body as a string. May be null if the message isn't text */
- String messageBody;
-
- String pseudoSubject;
-
- /** Non-null this is an email gateway message */
- String emailFrom;
-
- /** Non-null if this is an email gateway message */
- String emailBody;
-
- boolean isEmail;
-
- long scTimeMillis;
-
- /** The raw PDU of the message */
- byte[] mPdu;
-
- /** The raw bytes for the user data section of the message */
- byte[] userData;
-
- SmsHeader userDataHeader;
-
- /**
- * TP-Message-Type-Indicator
- * 9.2.3
- */
- int mti;
-
- /** TP-Protocol-Identifier (TP-PID) */
- int protocolIdentifier;
-
- // TP-Data-Coding-Scheme
- // see TS 23.038
- int dataCodingScheme;
-
- // TP-Reply-Path
- // e.g. 23.040 9.2.2.1
- boolean replyPathPresent = false;
-
- // "Message Marked for Automatic Deletion Group"
- // 23.038 Section 4
- boolean automaticDeletion;
-
- // "Message Waiting Indication Group"
- // 23.038 Section 4
- private boolean isMwi;
-
- private boolean mwiSense;
-
- private boolean mwiDontStore;
-
- MessageClass messageClass;
-
- /**
- * Indicates status for messages stored on the SIM.
- */
- int statusOnSim = -1;
+ @Deprecated public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
- /**
- * Record index of message in the EF.
+ /** Contains actual SmsMessage. Only public for debugging and for framework layer.
+ * @deprecated Use android.telephony.SmsMessage.
+ * {@hide}
*/
- int indexOnSim = -1;
-
- /** TP-Message-Reference - Message Reference of sent message. @hide */
- public int messageRef;
-
- /** True if Status Report is for SMS-SUBMIT; false for SMS-COMMAND. */
- boolean forSubmit;
-
- /** The address of the receiver. */
- SmsAddress recipientAddress;
-
- /** Time when SMS-SUBMIT was delivered from SC to MSE. */
- long dischargeTimeMillis;
+ @Deprecated public SmsMessageBase mWrappedSmsMessage;
- /**
- * TP-Status - status of a previously submitted SMS.
- * This field applies to SMS-STATUS-REPORT messages. 0 indicates success;
- * see TS 23.040, 9.2.3.15 for description of other possible values.
- */
- int status;
+ /** @deprecated Use android.telephony.SmsMessage. */
+ @Deprecated
+ public static class SubmitPdu {
+ /** @deprecated Use android.telephony.SmsMessage. */
+ @Deprecated public byte[] encodedScAddress; // Null if not applicable.
+ /** @deprecated Use android.telephony.SmsMessage. */
+ @Deprecated public byte[] encodedMessage;
- /**
- * TP-Status - status of a previously submitted SMS.
- * This field is true iff the message is a SMS-STATUS-REPORT message.
- */
- boolean isStatusReportMessage = false;
+ //Constructor
+ /** @deprecated Use android.telephony.SmsMessage. */
+ @Deprecated
+ public SubmitPdu() {
+ }
- public static class SubmitPdu {
- public byte[] encodedScAddress; // Null if not applicable.
- public byte[] encodedMessage;
+ /** @deprecated Use android.telephony.SmsMessage.
+ * {@hide}
+ */
+ @Deprecated
+ protected SubmitPdu(SubmitPduBase spb) {
+ this.encodedMessage = spb.encodedMessage;
+ this.encodedScAddress = spb.encodedScAddress;
+ }
+ /** @deprecated Use android.telephony.SmsMessage. */
+ @Deprecated
public String toString() {
return "SubmitPdu: encodedScAddress = "
+ Arrays.toString(encodedScAddress)
@@ -341,18 +135,33 @@ public class SmsMessage {
}
}
+ // Constructor
+ /** @deprecated Use android.telephony.SmsMessage. */
+ @Deprecated
+ public SmsMessage() {
+ this(getSmsFacility());
+ }
+
+ private SmsMessage(SmsMessageBase smb) {
+ mWrappedSmsMessage = smb;
+ }
+
/**
* Create an SmsMessage from a raw PDU.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public static SmsMessage createFromPdu(byte[] pdu) {
- try {
- SmsMessage msg = new SmsMessage();
- msg.parsePdu(pdu);
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
- return null;
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
}
+
+ return new SmsMessage(wrappedMessage);
}
/**
@@ -360,38 +169,70 @@ public class SmsMessage {
* +CMT unsolicited response (PDU mode, of course)
* +CMT: [&lt;alpha>],<length><CR><LF><pdu>
*
- * Only public for debugging
- *
+ * Only public for debugging and for RIL
+ * @deprecated Use android.telephony.SmsMessage.
* {@hide}
*/
- /* package */ public static SmsMessage newFromCMT(String[] lines) {
- try {
- SmsMessage msg = new SmsMessage();
- msg.parsePdu(IccUtils.hexStringToBytes(lines[1]));
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
- return null;
+ @Deprecated
+ public static SmsMessage newFromCMT(String[] lines){
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCMT(lines);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCMT(lines);
}
+
+ return new SmsMessage(wrappedMessage);
}
- /* pacakge */ static SmsMessage newFromCMTI(String line) {
- // the thinking here is not to read the message immediately
- // FTA test case
- Log.e(LOG_TAG, "newFromCMTI: not yet supported");
- return null;
+ /** @deprecated Use android.telephony.SmsMessage.
+ * @hide */
+ @Deprecated
+ protected static SmsMessage newFromCMTI(String line) {
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCMTI(line);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCMTI(line);
+ }
+
+ return new SmsMessage(wrappedMessage);
}
- /** @hide */
- /* package */ public static SmsMessage newFromCDS(String line) {
- try {
- SmsMessage msg = new SmsMessage();
- msg.parsePdu(IccUtils.hexStringToBytes(line));
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "CDS SMS PDU parsing failed: ", ex);
- return null;
+ /** @deprecated Use android.telephony.SmsMessage.
+ * @hide */
+ @Deprecated
+ public static SmsMessage newFromCDS(String line) {
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCDS(line);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCDS(line);
+ }
+
+ return new SmsMessage(wrappedMessage);
+ }
+
+ /** @deprecated Use android.telephony.SmsMessage.
+ * @hide */
+ @Deprecated
+ public static SmsMessage newFromParcel(Parcel p) {
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromParcel(p);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromParcel(p);
}
+
+ return new SmsMessage(wrappedMessage);
}
/**
@@ -401,51 +242,40 @@ public class SmsMessage {
* returned by SmsManager.getAllMessagesFromSim + 1.
* @param data Record data.
* @return An SmsMessage representing the record.
- *
+ *
+ * @deprecated Use android.telephony.SmsMessage.
* @hide
*/
+ @Deprecated
public static SmsMessage createFromEfRecord(int index, byte[] data) {
- try {
- SmsMessage msg = new SmsMessage();
-
- msg.indexOnSim = index;
-
- // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT,
- // or STORED_UNSENT
- // See TS 51.011 10.5.3
- if ((data[0] & 1) == 0) {
- Log.w(LOG_TAG,
- "SMS parsing failed: Trying to parse a free record");
- return null;
- } else {
- msg.statusOnSim = data[0] & 0x07;
- }
+ SmsMessageBase wrappedMessage;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
- int size = data.length - 1;
-
- // Note: Data may include trailing FF's. That's OK; message
- // should still parse correctly.
- byte[] pdu = new byte[size];
- System.arraycopy(data, 1, pdu, 0, size);
- msg.parsePdu(pdu);
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
- return null;
+ if (PHONE_TYPE_CDMA == activePhone) {
+ wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromEfRecord(
+ index, data);
+ } else {
+ wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromEfRecord(
+ index, data);
}
+
+ return new SmsMessage(wrappedMessage);
}
/**
* Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
* length in bytes (not hex chars) less the SMSC header
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public static int getTPLayerLengthForPDU(String pdu) {
- int len = pdu.length() / 2;
- int smscLen = 0;
-
- smscLen = Integer.parseInt(pdu.substring(0, 2), 16);
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
- return len - smscLen - 1;
+ if (PHONE_TYPE_CDMA == activePhone) {
+ return com.android.internal.telephony.cdma.SmsMessage.getTPLayerLengthForPDU(pdu);
+ } else {
+ return com.android.internal.telephony.gsm.SmsMessage.getTPLayerLengthForPDU(pdu);
+ }
}
/**
@@ -462,7 +292,9 @@ public class SmsMessage {
* 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.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public static int[] calculateLength(String messageBody, boolean use7bitOnly) {
int ret[] = new int[4];
@@ -496,7 +328,6 @@ public class SmsMessage {
return ret;
}
-
/**
* Get an SMS-SUBMIT PDU for a destination address and a message
*
@@ -504,88 +335,27 @@ public class SmsMessage {
* @return a <code>SubmitPdu</code> containing the encoded SC
* address, if applicable, and the encoded message.
* Returns null on encode error.
+ * @deprecated Use android.telephony.SmsMessage.
* @hide
*/
+ @Deprecated
public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, String message,
boolean statusReportRequested, byte[] header) {
+ SubmitPduBase spb;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
- // Perform null parameter checks.
- if (message == null || destinationAddress == null) {
- return null;
- }
-
- SubmitPdu ret = new SubmitPdu();
- // MTI = SMS-SUBMIT, UDHI = header != null
- byte mtiByte = (byte)(0x01 | (header != null ? 0x40 : 0x00));
- ByteArrayOutputStream bo = getSubmitPduHead(
- scAddress, destinationAddress, mtiByte,
- statusReportRequested, ret);
-
- try {
- // First, try encoding it with the GSM alphabet
-
- // User Data (and length)
- byte[] userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header);
-
- if ((0xff & userData[0]) > MAX_USER_DATA_SEPTETS) {
- // Message too long
- return null;
- }
-
- // TP-Data-Coding-Scheme
- // Default encoding, uncompressed
- bo.write(0x00);
-
- // (no TP-Validity-Period)
-
- bo.write(userData, 0, userData.length);
- } catch (EncodeException ex) {
- byte[] userData, textPart;
- // Encoding to the 7-bit alphabet failed. Let's see if we can
- // send it as a UCS-2 encoded message
-
- try {
- textPart = message.getBytes("utf-16be");
- } catch (UnsupportedEncodingException uex) {
- Log.e(LOG_TAG,
- "Implausible UnsupportedEncodingException ",
- uex);
- return null;
- }
-
- if (header != null) {
- userData = new byte[header.length + textPart.length];
-
- System.arraycopy(header, 0, userData, 0, header.length);
- System.arraycopy(textPart, 0, userData, header.length, textPart.length);
- }
- else {
- userData = textPart;
- }
-
- if (userData.length > MAX_USER_DATA_BYTES) {
- // Message too long
- return null;
- }
-
- // TP-Data-Coding-Scheme
- // Class 3, UCS-2 encoding, uncompressed
- bo.write(0x0b);
-
- // (no TP-Validity-Period)
-
- // TP-UDL
- bo.write(userData.length);
-
- bo.write(userData, 0, userData.length);
+ if (PHONE_TYPE_CDMA == activePhone) {
+ spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, message, statusReportRequested, header);
+ } else {
+ spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, message, statusReportRequested, header);
}
- ret.encodedMessage = bo.toByteArray();
- return ret;
+ return new SubmitPdu(spb);
}
-
/**
* Get an SMS-SUBMIT PDU for a destination address and a message
*
@@ -593,12 +363,23 @@ public class SmsMessage {
* @return a <code>SubmitPdu</code> containing the encoded SC
* address, if applicable, and the encoded message.
* Returns null on encode error.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public static SubmitPdu getSubmitPdu(String scAddress,
- String destinationAddress, String message,
- boolean statusReportRequested) {
+ String destinationAddress, String message, boolean statusReportRequested) {
+ SubmitPduBase spb;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
- return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, null);
+ if (PHONE_TYPE_CDMA == activePhone) {
+ spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, message, statusReportRequested);
+ } else {
+ spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, message, statusReportRequested);
+ }
+
+ return new SubmitPdu(spb);
}
/**
@@ -612,475 +393,105 @@ public class SmsMessage {
* @return a <code>SubmitPdu</code> containing the encoded SC
* address, if applicable, and the encoded message.
* Returns null on encode error.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, short destinationPort, byte[] data,
boolean statusReportRequested) {
- if (data.length > (MAX_USER_DATA_BYTES - 7 /* UDH size */)) {
- Log.e(LOG_TAG, "SMS data message may only contain "
- + (MAX_USER_DATA_BYTES - 7) + " bytes");
- return null;
- }
-
- SubmitPdu ret = new SubmitPdu();
- ByteArrayOutputStream bo = getSubmitPduHead(
- scAddress, destinationAddress, (byte) 0x41, // MTI = SMS-SUBMIT,
- // TP-UDHI = true
- statusReportRequested, ret);
-
- // TP-Data-Coding-Scheme
- // No class, 8 bit data
- bo.write(0x04);
-
- // (no TP-Validity-Period)
-
- // User data size
- bo.write(data.length + 7);
-
- // User data header size
- bo.write(0x06); // header is 6 octets
-
- // 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
- bo.write(data, 0, data.length);
-
- ret.encodedMessage = bo.toByteArray();
- return ret;
- }
+ SubmitPduBase spb;
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
- /**
- * Create the beginning of a SUBMIT PDU. This is the part of the
- * SUBMIT PDU that is common to the two versions of {@link #getSubmitPdu},
- * one of which takes a byte array and the other of which takes a
- * <code>String</code>.
- *
- * @param scAddress Service Centre address. null == use default
- * @param destinationAddress the address of the destination for the message
- * @param mtiByte
- * @param ret <code>SubmitPdu</code> containing the encoded SC
- * address, if applicable, and the encoded message
- */
- private static ByteArrayOutputStream getSubmitPduHead(
- String scAddress, String destinationAddress, byte mtiByte,
- boolean statusReportRequested, SubmitPdu ret) {
- ByteArrayOutputStream bo = new ByteArrayOutputStream(
- MAX_USER_DATA_BYTES + 40);
-
- // SMSC address with length octet, or 0
- if (scAddress == null) {
- ret.encodedScAddress = null;
+ if (PHONE_TYPE_CDMA == activePhone) {
+ spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, destinationPort, data, statusReportRequested);
} else {
- ret.encodedScAddress = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(
- scAddress);
- }
-
- // TP-Message-Type-Indicator (and friends)
- if (statusReportRequested) {
- // Set TP-Status-Report-Request bit.
- mtiByte |= 0x20;
- if (Config.LOGD) Log.d(LOG_TAG, "SMS status report requested");
- }
- bo.write(mtiByte);
-
- // space for TP-Message-Reference
- bo.write(0);
-
- byte[] daBytes;
-
- daBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(destinationAddress);
-
- // destination address length in BCD digits, ignoring TON byte and pad
- // TODO Should be better.
- bo.write((daBytes.length - 1) * 2
- - ((daBytes[daBytes.length - 1] & 0xf0) == 0xf0 ? 1 : 0));
-
- // destination address
- bo.write(daBytes, 0, daBytes.length);
-
- // TP-Protocol-Identifier
- bo.write(0);
- return bo;
- }
-
- static class PduParser {
- byte pdu[];
-
- int cur;
-
- SmsHeader userDataHeader;
-
- byte[] userData;
-
- int mUserDataSeptetPadding;
-
- int mUserDataSize;
-
- PduParser(String s) {
- this(IccUtils.hexStringToBytes(s));
+ spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
+ destinationAddress, destinationPort, data, statusReportRequested);
}
- PduParser(byte[] pdu) {
- this.pdu = pdu;
- cur = 0;
- mUserDataSeptetPadding = 0;
- }
-
- /**
- * Parse and return the SC address prepended to SMS messages coming via
- * the TS 27.005 / AT interface. Returns null on invalid address
- */
- String getSCAddress() {
- int len;
- String ret;
-
- // length of SC Address
- len = getByte();
-
- if (len == 0) {
- // no SC address
- ret = null;
- } else {
- // SC address
- try {
- ret = PhoneNumberUtils
- .calledPartyBCDToString(pdu, cur, len);
- } catch (RuntimeException tr) {
- Log.d(LOG_TAG, "invalid SC address: ", tr);
- ret = null;
- }
- }
-
- cur += len;
-
- return ret;
- }
-
- /**
- * returns non-sign-extended byte value
- */
- int getByte() {
- return pdu[cur++] & 0xff;
- }
-
- /**
- * Any address except the SC address (eg, originating address) See TS
- * 23.040 9.1.2.5
- */
- SmsAddress getAddress() {
- SmsAddress ret;
-
- // "The Address-Length field is an integer representation of
- // the number field, i.e. excludes any semi octet containing only
- // fill bits."
- // The TOA field is not included as part of this
- int addressLength = pdu[cur] & 0xff;
- int lengthBytes = 2 + (addressLength + 1) / 2;
-
- ret = new SmsAddress(pdu, cur, lengthBytes);
-
- cur += lengthBytes;
-
- return ret;
- }
-
- /**
- * Parses an SC timestamp and returns a currentTimeMillis()-style
- * timestamp
- */
-
- long getSCTimestampMillis() {
- // TP-Service-Centre-Time-Stamp
- int year = IccUtils.bcdByteToInt(pdu[cur++]);
- int month = IccUtils.bcdByteToInt(pdu[cur++]);
- int day = IccUtils.bcdByteToInt(pdu[cur++]);
- int hour = IccUtils.bcdByteToInt(pdu[cur++]);
- int minute = IccUtils.bcdByteToInt(pdu[cur++]);
- int second = IccUtils.bcdByteToInt(pdu[cur++]);
-
- // For the timezone, the most significant bit of the
- // least signficant nibble is the sign byte
- // (meaning the max range of this field is 79 quarter-hours,
- // which is more than enough)
-
- byte tzByte = pdu[cur++];
-
- // Mask out sign bit.
- int timezoneOffset = IccUtils
- .bcdByteToInt((byte) (tzByte & (~0x08)));
-
- timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset
- : -timezoneOffset;
-
- Time time = new Time(Time.TIMEZONE_UTC);
-
- // It's 2006. Should I really support years < 2000?
- time.year = year >= 90 ? year + 1900 : year + 2000;
- time.month = month - 1;
- time.monthDay = day;
- time.hour = hour;
- time.minute = minute;
- time.second = second;
-
- // Timezone offset is in quarter hours.
- return time.toMillis(true) - (timezoneOffset * 15 * 60 * 1000);
- }
-
- /**
- * Pulls the user data out of the PDU, and separates the payload from
- * the header if there is one.
- *
- * @param hasUserDataHeader true if there is a user data header
- * @param dataInSeptets true if the data payload is in septets instead
- * of octets
- * @return the number of septets or octets in the user data payload
- */
- int constructUserData(boolean hasUserDataHeader, boolean dataInSeptets) {
- int offset = cur;
- int userDataLength = pdu[offset++] & 0xff;
- int headerSeptets = 0;
-
- if (hasUserDataHeader) {
- int userDataHeaderLength = pdu[offset++] & 0xff;
-
- byte[] udh = new byte[userDataHeaderLength];
- System.arraycopy(pdu, offset, udh, 0, userDataHeaderLength);
- userDataHeader = SmsHeader.parse(udh);
- offset += userDataHeaderLength;
-
- int headerBits = (userDataHeaderLength + 1) * 8;
- headerSeptets = headerBits / 7;
- headerSeptets += (headerBits % 7) > 0 ? 1 : 0;
- 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];
- System.arraycopy(pdu, offset, userData, 0, userData.length);
- cur = offset;
-
- if (dataInSeptets) {
- // Return the number of septets
- return userDataLength - headerSeptets;
- } else {
- // Return the number of octets
- return userData.length;
- }
- }
-
- /**
- * Returns the user data payload, not including the headers
- *
- * @return the user data payload, not including the headers
- */
- byte[] getUserData() {
- return userData;
- }
-
- /**
- * Returns the number of padding bits at the begining of the user data
- * array before the start of the septets.
- *
- * @return the number of padding bits at the begining of the user data
- * array before the start of the septets
- */
- int getUserDataSeptetPadding() {
- return mUserDataSeptetPadding;
- }
-
- /**
- * Returns an object representing the user data headers
- *
- * @return an object representing the user data headers
- *
- * {@hide}
- */
- SmsHeader getUserDataHeader() {
- return userDataHeader;
- }
-
-/*
- XXX Not sure what this one is supposed to be doing, and no one is using
- it.
- String getUserDataGSM8bit() {
- // System.out.println("remainder of pud:" +
- // HexDump.dumpHexString(pdu, cur, pdu.length - cur));
- int count = pdu[cur++] & 0xff;
- int size = pdu[cur++];
-
- // skip over header for now
- cur += size;
-
- if (pdu[cur - 1] == 0x01) {
- int tid = pdu[cur++] & 0xff;
- int type = pdu[cur++] & 0xff;
-
- size = pdu[cur++] & 0xff;
-
- int i = cur;
-
- while (pdu[i++] != '\0') {
- }
-
- int length = i - cur;
- String mimeType = new String(pdu, cur, length);
-
- cur += length;
-
- if (false) {
- System.out.println("tid = 0x" + HexDump.toHexString(tid));
- System.out.println("type = 0x" + HexDump.toHexString(type));
- System.out.println("header size = " + size);
- System.out.println("mimeType = " + mimeType);
- System.out.println("remainder of header:" +
- HexDump.dumpHexString(pdu, cur, (size - mimeType.length())));
- }
-
- cur += size - mimeType.length();
-
- // System.out.println("data count = " + count + " cur = " + cur
- // + " :" + HexDump.dumpHexString(pdu, cur, pdu.length - cur));
-
- MMSMessage msg = MMSMessage.parseEncoding(mContext, pdu, cur,
- pdu.length - cur);
- } else {
- System.out.println(new String(pdu, cur, pdu.length - cur - 1));
- }
-
- return IccUtils.bytesToHexString(pdu);
- }
-*/
-
- /**
- * Interprets the user data payload as pack GSM 7bit characters, and
- * decodes them into a String.
- *
- * @param septetCount the number of septets in the user data payload
- * @return a String with the decoded characters
- */
- String getUserDataGSM7Bit(int septetCount) {
- String ret;
-
- ret = GsmAlphabet.gsm7BitPackedToString(pdu, cur, septetCount,
- mUserDataSeptetPadding);
-
- cur += (septetCount * 7) / 8;
-
- return ret;
- }
-
- /**
- * Interprets the user data payload as UCS2 characters, and
- * decodes them into a String.
- *
- * @param byteCount the number of bytes in the user data payload
- * @return a String with the decoded characters
- */
- String getUserDataUCS2(int byteCount) {
- String ret;
-
- try {
- ret = new String(pdu, cur, byteCount, "utf-16");
- } catch (UnsupportedEncodingException ex) {
- ret = "";
- Log.e(LOG_TAG, "implausible UnsupportedEncodingException", ex);
- }
-
- cur += byteCount;
- return ret;
- }
-
- boolean moreDataPresent() {
- return (pdu.length > cur);
- }
+ return new SubmitPdu(spb);
}
/**
* Returns the address of the SMS service center that relayed this message
* or null if there is none.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public String getServiceCenterAddress() {
- return scAddress;
+ return mWrappedSmsMessage.getServiceCenterAddress();
}
/**
* Returns the originating address (sender) of this SMS message in String
* form or null if unavailable
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public String getOriginatingAddress() {
- if (originatingAddress == null) {
- return null;
- }
-
- return originatingAddress.getAddressString();
+ return mWrappedSmsMessage.getOriginatingAddress();
}
/**
* Returns the originating address, or email from address if this message
* was from an email gateway. Returns null if originating address
* unavailable.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public String getDisplayOriginatingAddress() {
- if (isEmail) {
- return emailFrom;
- } else {
- return getOriginatingAddress();
- }
+ return mWrappedSmsMessage.getDisplayOriginatingAddress();
}
/**
* Returns the message body as a String, if it exists and is text based.
* @return message body is there is one, otherwise null
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public String getMessageBody() {
- return messageBody;
+ return mWrappedSmsMessage.getMessageBody();
}
/**
* Returns the class of this message.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public MessageClass getMessageClass() {
- return messageClass;
+ int index = mWrappedSmsMessage.getMessageClass().ordinal();
+
+ return MessageClass.values()[index];
}
/**
* Returns the message body, or email message body if this message was from
* an email gateway. Returns null if message body unavailable.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public String getDisplayMessageBody() {
- if (isEmail) {
- return emailBody;
- } else {
- return getMessageBody();
- }
+ return mWrappedSmsMessage.getDisplayMessageBody();
}
/**
* Unofficial convention of a subject line enclosed in parens empty string
* if not present
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public String getPseudoSubject() {
- return pseudoSubject == null ? "" : pseudoSubject;
+ return mWrappedSmsMessage.getPseudoSubject();
}
/**
* Returns the service centre timestamp in currentTimeMillis() format
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public long getTimestampMillis() {
- return scTimeMillis;
+ return mWrappedSmsMessage.getTimestampMillis();
}
/**
@@ -1088,129 +499,114 @@ public class SmsMessage {
*
* @return true if this message came through an email gateway and email
* sender / subject / parsed body are available
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public boolean isEmail() {
- return isEmail;
+ return mWrappedSmsMessage.isEmail();
}
- /**
+ /**
* @return if isEmail() is true, body of the email sent through the gateway.
* null otherwise
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public String getEmailBody() {
- return emailBody;
+ return mWrappedSmsMessage.getEmailBody();
}
/**
* @return if isEmail() is true, email from address of email sent through
* the gateway. null otherwise
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public String getEmailFrom() {
- return emailFrom;
+ return mWrappedSmsMessage.getEmailFrom();
}
/**
* Get protocol identifier.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public int getProtocolIdentifier() {
- return protocolIdentifier;
+ return mWrappedSmsMessage.getProtocolIdentifier();
}
/**
- * See TS 23.040 9.2.3.9 returns true if this is a "replace short message"
- * SMS
+ * See TS 23.040 9.2.3.9 returns true if this is a "replace short message" SMS
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public boolean isReplace() {
- return (protocolIdentifier & 0xc0) == 0x40
- && (protocolIdentifier & 0x3f) > 0
- && (protocolIdentifier & 0x3f) < 8;
+ return mWrappedSmsMessage.isReplace();
}
/**
* Returns true for CPHS MWI toggle message.
*
- * @return true if this is a CPHS MWI toggle message See CPHS 4.2 section
- * B.4.2
+ * @return true if this is a CPHS MWI toggle message See CPHS 4.2 section B.4.2
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public boolean isCphsMwiMessage() {
- return originatingAddress.isCphsVoiceMessageClear()
- || originatingAddress.isCphsVoiceMessageSet();
+ return mWrappedSmsMessage.isCphsMwiMessage();
}
/**
* returns true if this message is a CPHS voicemail / message waiting
* indicator (MWI) clear message
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public boolean isMWIClearMessage() {
- if (isMwi && (mwiSense == false)) {
- return true;
- }
-
- return originatingAddress != null
- && originatingAddress.isCphsVoiceMessageClear();
+ return mWrappedSmsMessage.isMWIClearMessage();
}
/**
* returns true if this message is a CPHS voicemail / message waiting
* indicator (MWI) set message
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public boolean isMWISetMessage() {
- if (isMwi && (mwiSense == true)) {
- return true;
- }
-
- return originatingAddress != null
- && originatingAddress.isCphsVoiceMessageSet();
+ return mWrappedSmsMessage.isMWISetMessage();
}
/**
* returns true if this message is a "Message Waiting Indication Group:
* Discard Message" notification and should not be stored.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public boolean isMwiDontStore() {
- if (isMwi && mwiDontStore) {
- return true;
- }
-
- if (isCphsMwiMessage()) {
- // See CPHS 4.2 Section B.4.2.1
- // If the user data is a single space char, do not store
- // the message. Otherwise, store and display as usual
- if (" ".equals(getMessageBody())) {
- ;
- }
- return true;
- }
-
- return false;
+ return mWrappedSmsMessage.isMwiDontStore();
}
/**
- * returns the user data section minus the user data header if one was
- * present.
+ * returns the user data section minus the user data header if one was present.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public byte[] getUserData() {
- return userData;
+ return mWrappedSmsMessage.getUserData();
}
- /**
- * Returns an object representing the user data header
- *
- * @return an object representing the user data header
- *
- * {@hide}
- */
- public SmsHeader getUserDataHeader() {
- return userDataHeader;
- }
+ /* Not part of the SDK interface and only needed by specific classes:
+ protected SmsHeader getUserDataHeader()
+ */
/**
* Returns the raw PDU for the message.
*
* @return the raw PDU for the message.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public byte[] getPdu() {
- return mPdu;
+ return mWrappedSmsMessage.getPdu();
}
/**
@@ -1222,369 +618,105 @@ public class SmsMessage {
* SmsManager.STATUS_ON_SIM_UNREAD
* SmsManager.STATUS_ON_SIM_SEND
* SmsManager.STATUS_ON_SIM_UNSENT
+ * @deprecated Use android.telephony.SmsMessage and getStatusOnIcc instead.
*/
+ @Deprecated
public int getStatusOnSim() {
- return statusOnSim;
+ return mWrappedSmsMessage.getStatusOnIcc();
+ }
+
+ /**
+ * Returns the status of the message on the ICC (read, unread, sent, unsent).
+ *
+ * @return the status of the message on the ICC. These are:
+ * SmsManager.STATUS_ON_ICC_FREE
+ * SmsManager.STATUS_ON_ICC_READ
+ * SmsManager.STATUS_ON_ICC_UNREAD
+ * SmsManager.STATUS_ON_ICC_SEND
+ * SmsManager.STATUS_ON_ICC_UNSENT
+ * @deprecated Use android.telephony.SmsMessage.
+ */
+ @Deprecated
+ public int getStatusOnIcc() {
+
+ return mWrappedSmsMessage.getStatusOnIcc();
}
/**
* Returns the record index of the message on the SIM (1-based index).
* @return the record index of the message on the SIM, or -1 if this
* SmsMessage was not created from a SIM SMS EF record.
+ * @deprecated Use android.telephony.SmsMessage and getIndexOnIcc instead.
*/
+ @Deprecated
public int getIndexOnSim() {
- return indexOnSim;
+ return mWrappedSmsMessage.getIndexOnIcc();
}
/**
+ * Returns the record index of the message on the ICC (1-based index).
+ * @return the record index of the message on the ICC, or -1 if this
+ * SmsMessage was not created from a ICC SMS EF record.
+ * @deprecated Use android.telephony.SmsMessage.
+ */
+ @Deprecated
+ public int getIndexOnIcc() {
+
+ return mWrappedSmsMessage.getIndexOnIcc();
+ }
+
+ /**
+ * GSM:
* For an SMS-STATUS-REPORT message, this returns the status field from
- * the status report. This field indicates the status of a previousely
+ * the status report. This field indicates the status of a previously
* submitted SMS, if requested. See TS 23.040, 9.2.3.15 TP-Status for a
* description of values.
+ * CDMA:
+ * For not interfering with status codes from GSM, the value is
+ * shifted to the bits 31-16.
+ * The value is composed of an error class (bits 25-24) and a status code (bits 23-16).
+ * Possible codes are described in C.S0015-B, v2.0, 4.5.21.
*
* @return 0 indicates the previously sent message was received.
- * See TS 23.040, 9.9.2.3.15 for a description of other possible
- * values.
+ * See TS 23.040, 9.9.2.3.15 and C.S0015-B, v2.0, 4.5.21
+ * for a description of other possible values.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public int getStatus() {
- return status;
+ return mWrappedSmsMessage.getStatus();
}
/**
* Return true iff the message is a SMS-STATUS-REPORT message.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public boolean isStatusReportMessage() {
- return isStatusReportMessage;
+ return mWrappedSmsMessage.isStatusReportMessage();
}
/**
* Returns true iff the <code>TP-Reply-Path</code> bit is set in
* this message.
+ * @deprecated Use android.telephony.SmsMessage.
*/
+ @Deprecated
public boolean isReplyPathPresent() {
- return replyPathPresent;
+ return mWrappedSmsMessage.isReplyPathPresent();
}
- /**
- * TS 27.005 3.1, <pdu> definition "In the case of SMS: 3GPP TS 24.011 [6]
- * SC address followed by 3GPP TS 23.040 [3] TPDU in hexadecimal format:
- * ME/TA converts each octet of TP data unit into two IRA character long
- * hexad number (e.g. octet with integer value 42 is presented to TE as two
- * characters 2A (IRA 50 and 65))" ...in the case of cell broadcast,
- * something else...
+ /** This method returns the reference to a specific
+ * SmsMessage object, which is used for accessing its static methods.
+ * @return Specific SmsMessage.
+ * @deprecated Use android.telephony.SmsMessage.
*/
- private void parsePdu(byte[] pdu) {
- mPdu = pdu;
- // Log.d(LOG_TAG, "raw sms mesage:");
- // Log.d(LOG_TAG, s);
-
- PduParser p = new PduParser(pdu);
-
- scAddress = p.getSCAddress();
-
- if (scAddress != null) {
- if (Config.LOGD) Log.d(LOG_TAG, "SMS SC address: " + scAddress);
- }
-
- // TODO(mkf) support reply path, user data header indicator
-
- // TP-Message-Type-Indicator
- // 9.2.3
- int firstByte = p.getByte();
-
- mti = firstByte & 0x3;
- switch (mti) {
- // TP-Message-Type-Indicator
- // 9.2.3
- case 0:
- parseSmsDeliver(p, firstByte);
- break;
- case 2:
- parseSmsStatusReport(p, firstByte);
- break;
- default:
- // TODO(mkf) the rest of these
- throw new RuntimeException("Unsupported message type");
- }
- }
-
- /**
- * Parses a SMS-STATUS-REPORT message.
- *
- * @param p A PduParser, cued past the first byte.
- * @param firstByte The first byte of the PDU, which contains MTI, etc.
- */
- private void parseSmsStatusReport(PduParser p, int firstByte) {
- isStatusReportMessage = true;
-
- // TP-Status-Report-Qualifier bit == 0 for SUBMIT
- forSubmit = (firstByte & 0x20) == 0x00;
- // TP-Message-Reference
- messageRef = p.getByte();
- // TP-Recipient-Address
- recipientAddress = p.getAddress();
- // TP-Service-Centre-Time-Stamp
- scTimeMillis = p.getSCTimestampMillis();
- // TP-Discharge-Time
- dischargeTimeMillis = p.getSCTimestampMillis();
- // TP-Status
- status = p.getByte();
-
- // The following are optional fields that may or may not be present.
- if (p.moreDataPresent()) {
- // TP-Parameter-Indicator
- int extraParams = p.getByte();
- int moreExtraParams = extraParams;
- while ((moreExtraParams & 0x80) != 0) {
- // We only know how to parse a few extra parameters, all
- // indicated in the first TP-PI octet, so skip over any
- // additional TP-PI octets.
- moreExtraParams = p.getByte();
- }
- // TP-Protocol-Identifier
- if ((extraParams & 0x01) != 0) {
- protocolIdentifier = p.getByte();
- }
- // TP-Data-Coding-Scheme
- if ((extraParams & 0x02) != 0) {
- dataCodingScheme = p.getByte();
- }
- // TP-User-Data-Length (implies existence of TP-User-Data)
- if ((extraParams & 0x04) != 0) {
- boolean hasUserDataHeader = (firstByte & 0x40) == 0x40;
- parseUserData(p, hasUserDataHeader);
- }
- }
- }
-
- private void parseSmsDeliver(PduParser p, int firstByte) {
- replyPathPresent = (firstByte & 0x80) == 0x80;
-
- originatingAddress = p.getAddress();
-
- if (originatingAddress != null) {
- if (Config.LOGV) Log.v(LOG_TAG, "SMS originating address: "
- + originatingAddress.address);
- }
-
- // TP-Protocol-Identifier (TP-PID)
- // TS 23.040 9.2.3.9
- protocolIdentifier = p.getByte();
-
- // TP-Data-Coding-Scheme
- // see TS 23.038
- dataCodingScheme = p.getByte();
-
- if (Config.LOGV) {
- Log.v(LOG_TAG, "SMS TP-PID:" + protocolIdentifier
- + " data coding scheme: " + dataCodingScheme);
- }
-
- scTimeMillis = p.getSCTimestampMillis();
-
- if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
-
- boolean hasUserDataHeader = (firstByte & 0x40) == 0x40;
-
- parseUserData(p, hasUserDataHeader);
- }
-
- /**
- * Parses the User Data of an SMS.
- *
- * @param p The current PduParser.
- * @param hasUserDataHeader Indicates whether a header is present in the
- * User Data.
- */
- private void parseUserData(PduParser p, boolean hasUserDataHeader) {
- boolean hasMessageClass = false;
- boolean userDataCompressed = false;
-
- int encodingType = ENCODING_UNKNOWN;
-
- // Look up the data encoding scheme
- if ((dataCodingScheme & 0x80) == 0) {
- // Bits 7..4 == 0xxx
- automaticDeletion = (0 != (dataCodingScheme & 0x40));
- userDataCompressed = (0 != (dataCodingScheme & 0x20));
- hasMessageClass = (0 != (dataCodingScheme & 0x10));
-
- if (userDataCompressed) {
- Log.w(LOG_TAG, "4 - Unsupported SMS data coding scheme "
- + "(compression) " + (dataCodingScheme & 0xff));
- } else {
- switch ((dataCodingScheme >> 2) & 0x3) {
- case 0: // GSM 7 bit default alphabet
- encodingType = ENCODING_7BIT;
- break;
-
- case 2: // UCS 2 (16bit)
- encodingType = ENCODING_16BIT;
- break;
-
- case 1: // 8 bit data
- case 3: // reserved
- Log.w(LOG_TAG, "1 - Unsupported SMS data coding scheme "
- + (dataCodingScheme & 0xff));
- encodingType = ENCODING_8BIT;
- break;
- }
- }
- } else if ((dataCodingScheme & 0xf0) == 0xf0) {
- automaticDeletion = false;
- hasMessageClass = true;
- userDataCompressed = false;
-
- if (0 == (dataCodingScheme & 0x04)) {
- // GSM 7 bit default alphabet
- encodingType = ENCODING_7BIT;
- } else {
- // 8 bit data
- encodingType = ENCODING_8BIT;
- }
- } else if ((dataCodingScheme & 0xF0) == 0xC0
- || (dataCodingScheme & 0xF0) == 0xD0
- || (dataCodingScheme & 0xF0) == 0xE0) {
- // 3GPP TS 23.038 V7.0.0 (2006-03) section 4
-
- // 0xC0 == 7 bit, don't store
- // 0xD0 == 7 bit, store
- // 0xE0 == UCS-2, store
-
- if ((dataCodingScheme & 0xF0) == 0xE0) {
- encodingType = ENCODING_16BIT;
- } else {
- encodingType = ENCODING_7BIT;
- }
-
- userDataCompressed = false;
- boolean active = ((dataCodingScheme & 0x08) == 0x08);
-
- // bit 0x04 reserved
-
- if ((dataCodingScheme & 0x03) == 0x00) {
- isMwi = true;
- mwiSense = active;
- mwiDontStore = ((dataCodingScheme & 0xF0) == 0xC0);
- } else {
- isMwi = false;
-
- Log.w(LOG_TAG, "MWI for fax, email, or other "
- + (dataCodingScheme & 0xff));
- }
- } else {
- Log.w(LOG_TAG, "3 - Unsupported SMS data coding scheme "
- + (dataCodingScheme & 0xff));
- }
-
- // set both the user data and the user data header.
- int count = p.constructUserData(hasUserDataHeader,
- encodingType == ENCODING_7BIT);
- this.userData = p.getUserData();
- this.userDataHeader = p.getUserDataHeader();
-
- switch (encodingType) {
- case ENCODING_UNKNOWN:
- case ENCODING_8BIT:
- messageBody = null;
- break;
-
- case ENCODING_7BIT:
- messageBody = p.getUserDataGSM7Bit(count);
- break;
-
- case ENCODING_16BIT:
- messageBody = p.getUserDataUCS2(count);
- break;
- }
-
- if (Config.LOGV) Log.v(LOG_TAG, "SMS message body (raw): '" + messageBody + "'");
-
- if (messageBody != null) {
- parseMessageBody();
- }
-
- if (!hasMessageClass) {
- messageClass = MessageClass.UNKNOWN;
+ private static final SmsMessageBase getSmsFacility(){
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
+ if (PHONE_TYPE_CDMA == activePhone) {
+ return new com.android.internal.telephony.cdma.SmsMessage();
} else {
- switch (dataCodingScheme & 0x3) {
- case 0:
- messageClass = MessageClass.CLASS_0;
- break;
- case 1:
- messageClass = MessageClass.CLASS_1;
- break;
- case 2:
- messageClass = MessageClass.CLASS_2;
- break;
- case 3:
- messageClass = MessageClass.CLASS_3;
- break;
- }
- }
- }
-
- private void parseMessageBody() {
- if (originatingAddress.couldBeEmailGateway()) {
- extractEmailAddressFromMessageBody();
- }
- }
-
- /**
- * Try to parse this message as an email gateway message -> Neither
- * of the standard ways are currently supported: There are two ways
- * specified in TS 23.040 Section 3.8 (not supported via this mechanism) -
- * SMS message "may have its TP-PID set for internet electronic mail - MT
- * SMS format: [<from-address><space>]<message> - "Depending on the
- * nature of the gateway, the destination/origination address is either
- * derived from the content of the SMS TP-OA or TP-DA field, or the
- * TP-OA/TP-DA field contains a generic gateway address and the to/from
- * address is added at the beginning as shown above." - multiple addreses
- * separated by commas, no spaces - subject field delimited by '()' or '##'
- * and '#' Section 9.2.3.24.11
- */
- private void extractEmailAddressFromMessageBody() {
-
- /*
- * a little guesswork here. I haven't found doc for this.
- * the format could be either
- *
- * 1. [x@y][ ]/[subject][ ]/[body]
- * -or-
- * 2. [x@y][ ]/[body]
- */
- int slash = 0, slash2 = 0, atSymbol = 0;
-
- try {
- slash = messageBody.indexOf(" /");
- if (slash == -1) {
- return;
- }
-
- atSymbol = messageBody.indexOf('@');
- if (atSymbol == -1 || atSymbol > slash) {
- return;
- }
-
- emailFrom = messageBody.substring(0, slash);
-
- slash2 = messageBody.indexOf(" /", slash + 2);
-
- if (slash2 == -1) {
- pseudoSubject = null;
- emailBody = messageBody.substring(slash + 2);
- } else {
- pseudoSubject = messageBody.substring(slash + 2, slash2);
- emailBody = messageBody.substring(slash2 + 2);
- }
-
- isEmail = true;
- } catch (Exception ex) {
- Log.w(LOG_TAG,
- "extractEmailAddressFromMessageBody: exception slash="
- + slash + ", atSymbol=" + atSymbol + ", slash2="
- + slash2, ex);
+ return new com.android.internal.telephony.gsm.SmsMessage();
}
}
-
}
diff --git a/telephony/java/com/android/internal/telephony/ATResponseParser.java b/telephony/java/com/android/internal/telephony/ATResponseParser.java
index 93ec45588418..fdb05262da4c 100644
--- a/telephony/java/com/android/internal/telephony/ATResponseParser.java
+++ b/telephony/java/com/android/internal/telephony/ATResponseParser.java
@@ -34,7 +34,7 @@ public class ATResponseParser
{
this.line = line;
}
-
+
public boolean
nextBoolean()
{
@@ -147,7 +147,7 @@ public class ATResponseParser
}
}
-
+
/** Throws ATParseEx if whitespace extends to the end of string */
private char
skipWhiteSpace (char c)
diff --git a/telephony/java/com/android/internal/telephony/AdnRecord.aidl b/telephony/java/com/android/internal/telephony/AdnRecord.aidl
index d3576be2b923..b4a1a298aefd 100644
--- a/telephony/java/com/android/internal/telephony/AdnRecord.aidl
+++ b/telephony/java/com/android/internal/telephony/AdnRecord.aidl
@@ -18,4 +18,3 @@ package com.android.internal.telephony;
parcelable AdnRecord;
-// TODO T: move to telephony and implement proxy-service as for all AIDL
diff --git a/telephony/java/com/android/internal/telephony/AdnRecord.java b/telephony/java/com/android/internal/telephony/AdnRecord.java
index 6273b0f1008a..5f40579b272a 100644
--- a/telephony/java/com/android/internal/telephony/AdnRecord.java
+++ b/telephony/java/com/android/internal/telephony/AdnRecord.java
@@ -16,21 +16,16 @@
package com.android.internal.telephony;
-import com.android.internal.telephony.*;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.Message;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.AsyncResult;
-import android.util.Log;
import android.telephony.PhoneNumberUtils;
-import java.util.ArrayList;
-import com.android.internal.telephony.gsm.GsmAlphabet;
+import android.util.Log;
+
+import com.android.internal.telephony.GsmAlphabet;
/**
- *
+ *
* Used to load or store ADNs (Abbreviated Dialing Numbers).
*
* {@hide}
@@ -38,7 +33,7 @@ import com.android.internal.telephony.gsm.GsmAlphabet;
*/
public class AdnRecord implements Parcelable {
static final String LOG_TAG = "GSM";
-
+
//***** Instance Variables
String alphaTag = "";
@@ -111,7 +106,7 @@ public class AdnRecord implements Parcelable {
AdnRecord (String alphaTag, String number) {
this(0, 0, alphaTag, number);
}
-
+
public
AdnRecord (int efid, int recordNumber, String alphaTag, String number) {
this.efid = efid;
@@ -119,7 +114,7 @@ public class AdnRecord implements Parcelable {
this.alphaTag = alphaTag;
this.number = number;
}
-
+
//***** Instance Methods
public String getAlphaTag() {
@@ -219,7 +214,7 @@ public class AdnRecord implements Parcelable {
* See TS 51.011 10.5.10
*/
public void
- appendExtRecord (byte[] extRecord) {
+ appendExtRecord (byte[] extRecord) {
try {
if (extRecord.length != EXT_RECORD_LENGTH_BYTES) {
return;
@@ -268,9 +263,9 @@ public class AdnRecord implements Parcelable {
// Please note 51.011 10.5.1:
//
- // "If the Dialling Number/SSC String does not contain
- // a dialling number, e.g. a control string deactivating
- // a service, the TON/NPI byte shall be set to 'FF' by
+ // "If the Dialling Number/SSC String does not contain
+ // a dialling number, e.g. a control string deactivating
+ // a service, the TON/NPI byte shall be set to 'FF' by
// the ME (see note 2)."
number = PhoneNumberUtils.calledPartyBCDToString(
@@ -283,6 +278,6 @@ public class AdnRecord implements Parcelable {
Log.w(LOG_TAG, "Error parsing AdnRecord", ex);
number = "";
alphaTag = "";
- }
+ }
}
}
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordCache.java b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
index 2654e427691d..c270ae5087b8 100644
--- a/telephony/java/com/android/internal/telephony/AdnRecordCache.java
+++ b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
@@ -34,7 +34,7 @@ public final class AdnRecordCache extends Handler implements IccConstants {
PhoneBase phone;
// Indexed by EF ID
- SparseArray<ArrayList<AdnRecord>> adnLikeFiles
+ SparseArray<ArrayList<AdnRecord>> adnLikeFiles
= new SparseArray<ArrayList<AdnRecord>>();
// People waiting for ADN-like files to be loaded
@@ -52,7 +52,7 @@ public final class AdnRecordCache extends Handler implements IccConstants {
//***** Constructor
-
+
public AdnRecordCache(PhoneBase phone) {
this.phone = phone;
}
@@ -67,7 +67,7 @@ public final class AdnRecordCache extends Handler implements IccConstants {
clearWaiters();
clearUserWriters();
-
+
}
private void clearWaiters() {
@@ -98,7 +98,7 @@ public final class AdnRecordCache extends Handler implements IccConstants {
}
/**
- * Returns extension ef associated with ADN-like EF or -1 if
+ * Returns extension ef associated with ADN-like EF or -1 if
* we don't know.
*
* See 3GPP TS 51.011 for this mapping
@@ -110,9 +110,9 @@ public final class AdnRecordCache extends Handler implements IccConstants {
case EF_ADN: return EF_EXT1;
case EF_SDN: return EF_EXT3;
case EF_FDN: return EF_EXT2;
- case EF_MSISDN: return EF_EXT1;
+ case EF_MSISDN: return EF_EXT1;
default: return -1;
- }
+ }
}
private void sendErrorResponse(Message response, String errString) {
@@ -250,25 +250,25 @@ public final class AdnRecordCache extends Handler implements IccConstants {
waiters.add(response);
return;
}
-
+
// Start loading efid
-
+
waiters = new ArrayList<Message>();
waiters.add(response);
adnLikeWaiters.put(efid, waiters);
int extensionEF = extensionEfForEf(efid);
-
+
if (extensionEF < 0) {
// respond with error if not known ADN-like record
if (response != null) {
- AsyncResult.forMessage(response).exception
+ AsyncResult.forMessage(response).exception
= new RuntimeException("EF is not known ADN-like EF:" + efid);
response.sendToTarget();
}
-
+
return;
}
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java b/telephony/java/com/android/internal/telephony/AdnRecordLoader.java
index 721cce9ecadc..cfb5aaa84b39 100644
--- a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java
+++ b/telephony/java/com/android/internal/telephony/AdnRecordLoader.java
@@ -25,7 +25,7 @@ import android.util.Log;
public class AdnRecordLoader extends Handler {
- static final String LOG_TAG = "AdnRecordLoader";
+ static String LOG_TAG;
//***** Instance Variables
@@ -59,9 +59,10 @@ public class AdnRecordLoader extends Handler {
public AdnRecordLoader(PhoneBase phone) {
// The telephony unit-test cases may create AdnRecords
// in secondary threads
- super(phone.h.getLooper());
+ super(phone.getHandler().getLooper());
this.phone = phone;
+ LOG_TAG = phone.getPhoneName();
}
/**
@@ -69,16 +70,16 @@ public class AdnRecordLoader extends Handler {
* or response.obj.exception is set
*/
public void
- loadFromEF(int ef, int extensionEF, int recordNumber,
+ loadFromEF(int ef, int extensionEF, int recordNumber,
Message response) {
this.ef = ef;
this.extensionEF = extensionEF;
this.recordNumber = recordNumber;
this.userResponse = response;
-
+
phone.mIccFileHandler.loadEFLinearFixed(
- ef, recordNumber,
- obtainMessage(EVENT_ADN_LOAD_DONE));
+ ef, recordNumber,
+ obtainMessage(EVENT_ADN_LOAD_DONE));
}
@@ -88,15 +89,15 @@ public class AdnRecordLoader extends Handler {
* or response.obj.exception is set
*/
public void
- loadAllFromEF(int ef, int extensionEF,
+ loadAllFromEF(int ef, int extensionEF,
Message response) {
this.ef = ef;
this.extensionEF = extensionEF;
this.userResponse = response;
-
+
phone.mIccFileHandler.loadEFLinearFixedAll(
- ef,
- obtainMessage(EVENT_ADN_LOAD_ALL_DONE));
+ ef,
+ obtainMessage(EVENT_ADN_LOAD_ALL_DONE));
}
@@ -127,7 +128,7 @@ public class AdnRecordLoader extends Handler {
//***** Overridden from Handler
- public void
+ public void
handleMessage(Message msg) {
AsyncResult ar;
byte data[];
@@ -180,18 +181,18 @@ public class AdnRecordLoader extends Handler {
case EVENT_ADN_LOAD_DONE:
ar = (AsyncResult)(msg.obj);
data = (byte[])(ar.result);
-
+
if (ar.exception != null) {
throw new RuntimeException("load failed", ar.exception);
}
if (false) {
- Log.d(LOG_TAG,"ADN EF: 0x"
+ Log.d(LOG_TAG,"ADN EF: 0x"
+ Integer.toHexString(ef)
+ ":" + recordNumber
+ "\n" + IccUtils.bytesToHexString(data));
}
-
+
adn = new AdnRecord(ef, recordNumber, data);
result = adn;
@@ -201,10 +202,10 @@ public class AdnRecordLoader extends Handler {
// ext record and append it
pendingExtLoads = 1;
-
+
phone.mIccFileHandler.loadEFLinearFixed(
- extensionEF, adn.extRecord,
- obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
+ extensionEF, adn.extRecord,
+ obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
}
break;
@@ -212,12 +213,12 @@ public class AdnRecordLoader extends Handler {
ar = (AsyncResult)(msg.obj);
data = (byte[])(ar.result);
adn = (AdnRecord)(ar.userObj);
-
+
if (ar.exception != null) {
throw new RuntimeException("load failed", ar.exception);
}
- Log.d(LOG_TAG,"ADN extention EF: 0x"
+ Log.d(LOG_TAG,"ADN extention EF: 0x"
+ Integer.toHexString(extensionEF)
+ ":" + adn.extRecord
+ "\n" + IccUtils.bytesToHexString(data));
@@ -225,14 +226,14 @@ public class AdnRecordLoader extends Handler {
adn.appendExtRecord(data);
pendingExtLoads--;
- // result should have been set in
+ // result should have been set in
// EVENT_ADN_LOAD_DONE or EVENT_ADN_LOAD_ALL_DONE
- break;
+ break;
case EVENT_ADN_LOAD_ALL_DONE:
ar = (AsyncResult)(msg.obj);
ArrayList<byte[]> datas = (ArrayList<byte[]>)(ar.result);
-
+
if (ar.exception != null) {
throw new RuntimeException("load failed", ar.exception);
}
@@ -251,17 +252,17 @@ public class AdnRecordLoader extends Handler {
// ext record and append it
pendingExtLoads++;
-
+
phone.mIccFileHandler.loadEFLinearFixed(
- extensionEF, adn.extRecord,
- obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
+ extensionEF, adn.extRecord,
+ obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
}
}
break;
}
- } catch (RuntimeException exc) {
+ } catch (RuntimeException exc) {
if (userResponse != null) {
- AsyncResult.forMessage(userResponse)
+ AsyncResult.forMessage(userResponse)
.exception = exc;
userResponse.sendToTarget();
// Loading is all or nothing--either every load succeeds
@@ -272,13 +273,13 @@ public class AdnRecordLoader extends Handler {
}
if (userResponse != null && pendingExtLoads == 0) {
- AsyncResult.forMessage(userResponse).result
+ AsyncResult.forMessage(userResponse).result
= result;
userResponse.sendToTarget();
userResponse = null;
}
}
-
+
}
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 37117e67923c..f603ddc17426 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -22,7 +22,6 @@ import android.os.RegistrantList;
import android.os.Registrant;
import android.os.Handler;
import android.os.AsyncResult;
-import android.os.SystemProperties;
import android.provider.Checkin;
import android.util.Config;
import android.util.Log;
@@ -50,8 +49,11 @@ public abstract class BaseCommands implements CommandsInterface {
protected RegistrantList mNVReadyRegistrants = new RegistrantList();
protected RegistrantList mCallStateRegistrants = new RegistrantList();
protected RegistrantList mNetworkStateRegistrants = new RegistrantList();
- protected RegistrantList mPDPRegistrants = new RegistrantList();
- protected RegistrantList mRadioTechnologyChangedRegistrants= new RegistrantList();
+ protected RegistrantList mDataConnectionRegistrants = new RegistrantList();
+ protected RegistrantList mRadioTechnologyChangedRegistrants = new RegistrantList();
+ protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
+ protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
+ protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
protected Registrant mSMSRegistrant;
protected Registrant mNITZTimeRegistrant;
protected Registrant mSignalStrengthRegistrant;
@@ -65,8 +67,8 @@ public abstract class BaseCommands implements CommandsInterface {
protected Registrant mStkProCmdRegistrant;
protected Registrant mStkEventRegistrant;
protected Registrant mStkCallSetUpRegistrant;
- /** Registrant for handling SIM SMS storage full messages */
- protected Registrant mSimSmsFullRegistrant;
+ /** Registrant for handling SIM/RUIM SMS storage full messages */
+ protected Registrant mIccSmsFullRegistrant;
/** Registrant for handling Icc Refresh notifications */
protected Registrant mIccRefreshRegistrant;
/** Registrant for handling RING notifications */
@@ -76,25 +78,22 @@ public abstract class BaseCommands implements CommandsInterface {
protected int mNetworkMode;
//CDMA subscription received from PhoneFactory
protected int mCdmaSubscription;
- //Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
- //TODO check if at init has to be set from mNetworkMode
- protected int mPhoneType;
+ //Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
+ protected int mPhoneType;
+
-
public BaseCommands(Context context) {
mContext = context; // May be null (if so we won't log statistics)
}
//***** CommandsInterface implementation
- public RadioState
- getRadioState() {
+ public RadioState getRadioState() {
return mState;
}
- public void
- registerForRadioStateChanged(Handler h, int what, Object obj) {
+ public void registerForRadioStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
@@ -103,8 +102,13 @@ public abstract class BaseCommands implements CommandsInterface {
}
}
- public void
- registerForOn(Handler h, int what, Object obj) {
+ public void unregisterForRadioStateChanged(Handler h) {
+ synchronized (mStateMonitor) {
+ mRadioStateChangedRegistrants.remove(h);
+ }
+ }
+
+ public void registerForOn(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
@@ -115,10 +119,14 @@ public abstract class BaseCommands implements CommandsInterface {
}
}
}
-
+ public void unregisterForOn(Handler h) {
+ synchronized (mStateMonitor) {
+ mOnRegistrants.remove(h);
+ }
+ }
+
- public void
- registerForAvailable(Handler h, int what, Object obj) {
+ public void registerForAvailable(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
@@ -130,8 +138,13 @@ public abstract class BaseCommands implements CommandsInterface {
}
}
- public void
- registerForNotAvailable(Handler h, int what, Object obj) {
+ public void unregisterForAvailable(Handler h) {
+ synchronized(mStateMonitor) {
+ mAvailRegistrants.remove(h);
+ }
+ }
+
+ public void registerForNotAvailable(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
@@ -143,8 +156,13 @@ public abstract class BaseCommands implements CommandsInterface {
}
}
- public void
- registerForOffOrNotAvailable(Handler h, int what, Object obj) {
+ public void unregisterForNotAvailable(Handler h) {
+ synchronized (mStateMonitor) {
+ mNotAvailRegistrants.remove(h);
+ }
+ }
+
+ public void registerForOffOrNotAvailable(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
@@ -155,11 +173,15 @@ public abstract class BaseCommands implements CommandsInterface {
}
}
}
+ public void unregisterForOffOrNotAvailable(Handler h) {
+ synchronized(mStateMonitor) {
+ mOffOrNotAvailRegistrants.remove(h);
+ }
+ }
/** Any transition into SIM_READY */
- public void
- registerForSIMReady(Handler h, int what, Object obj) {
+ public void registerForSIMReady(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
@@ -171,9 +193,14 @@ public abstract class BaseCommands implements CommandsInterface {
}
}
+ public void unregisterForSIMReady(Handler h) {
+ synchronized (mStateMonitor) {
+ mSIMReadyRegistrants.remove(h);
+ }
+ }
+
/** Any transition into RUIM_READY */
- public void
- registerForRUIMReady(Handler h, int what, Object obj) {
+ public void registerForRUIMReady(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
@@ -184,10 +211,15 @@ public abstract class BaseCommands implements CommandsInterface {
}
}
}
-
+
+ public void unregisterForRUIMReady(Handler h) {
+ synchronized(mStateMonitor) {
+ mRUIMReadyRegistrants.remove(h);
+ }
+ }
+
/** Any transition into NV_READY */
- public void
- registerForNVReady(Handler h, int what, Object obj) {
+ public void registerForNVReady(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
@@ -199,8 +231,13 @@ public abstract class BaseCommands implements CommandsInterface {
}
}
- public void
- registerForSIMLockedOrAbsent(Handler h, int what, Object obj) {
+ public void unregisterForNVReady(Handler h) {
+ synchronized (mStateMonitor) {
+ mNVReadyRegistrants.remove(h);
+ }
+ }
+
+ public void registerForSIMLockedOrAbsent(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
@@ -212,8 +249,13 @@ public abstract class BaseCommands implements CommandsInterface {
}
}
- public void
- registerForRUIMLockedOrAbsent(Handler h, int what, Object obj) {
+ public void unregisterForSIMLockedOrAbsent(Handler h) {
+ synchronized (mStateMonitor) {
+ mSIMLockedRegistrants.remove(h);
+ }
+ }
+
+ public void registerForRUIMLockedOrAbsent(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
@@ -224,101 +266,192 @@ public abstract class BaseCommands implements CommandsInterface {
}
}
}
-
- public void
- registerForCallStateChanged(Handler h, int what, Object obj) {
+
+ public void unregisterForRUIMLockedOrAbsent(Handler h) {
+ synchronized (mStateMonitor) {
+ mRUIMLockedRegistrants.remove(h);
+ }
+ }
+
+ public void registerForCallStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mCallStateRegistrants.add(r);
}
- public void
- registerForNetworkStateChanged(Handler h, int what, Object obj) {
+ public void unregisterForCallStateChanged(Handler h) {
+ mCallStateRegistrants.remove(h);
+ }
+
+ public void registerForNetworkStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mNetworkStateRegistrants.add(r);
}
- public void
- registerForPDPStateChanged(Handler h, int what, Object obj) {
+ public void unregisterForNetworkStateChanged(Handler h) {
+ mNetworkStateRegistrants.remove(h);
+ }
+
+ public void registerForDataStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
- mPDPRegistrants.add(r);
+ mDataConnectionRegistrants.add(r);
+ }
+
+ public void unregisterForDataStateChanged(Handler h) {
+ mDataConnectionRegistrants.remove(h);
}
- public void
- registerForRadioTechnologyChanged(Handler h, int what, Object obj) {
+ public void registerForRadioTechnologyChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mRadioTechnologyChangedRegistrants.add(r);
}
-
- public void
- setOnNewSMS(Handler h, int what, Object obj) {
+
+ public void unregisterForRadioTechnologyChanged(Handler h) {
+ mRadioTechnologyChangedRegistrants.remove(h);
+ }
+
+ public void registerForIccStatusChanged(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mIccStatusChangedRegistrants.add(r);
+ }
+
+ public void unregisterForIccStatusChanged(Handler h) {
+ mIccStatusChangedRegistrants.remove(h);
+ }
+
+ public void setOnNewSMS(Handler h, int what, Object obj) {
mSMSRegistrant = new Registrant (h, what, obj);
}
- public void
- setOnSmsOnSim(Handler h, int what, Object obj) {
+ public void unSetOnNewSMS(Handler h) {
+ mSMSRegistrant.clear();
+ }
+
+ public void setOnSmsOnSim(Handler h, int what, Object obj) {
mSmsOnSimRegistrant = new Registrant (h, what, obj);
}
-
+
+ public void unSetOnSmsOnSim(Handler h) {
+ mSmsOnSimRegistrant.clear();
+ }
+
public void setOnSmsStatus(Handler h, int what, Object obj) {
mSmsStatusRegistrant = new Registrant (h, what, obj);
}
- public void
- setOnSignalStrengthUpdate(Handler h, int what, Object obj) {
+ public void unSetOnSmsStatus(Handler h) {
+ mSmsStatusRegistrant.clear();
+ }
+
+ public void setOnSignalStrengthUpdate(Handler h, int what, Object obj) {
mSignalStrengthRegistrant = new Registrant (h, what, obj);
}
- public void
- setOnNITZTime(Handler h, int what, Object obj) {
+ public void unSetOnSignalStrengthUpdate(Handler h) {
+ mSignalStrengthRegistrant.clear();
+ }
+
+ public void setOnNITZTime(Handler h, int what, Object obj) {
mNITZTimeRegistrant = new Registrant (h, what, obj);
}
-
- public void
- setOnUSSD(Handler h, int what, Object obj) {
+
+ public void unSetOnNITZTime(Handler h) {
+ mNITZTimeRegistrant.clear();
+ }
+
+ public void setOnUSSD(Handler h, int what, Object obj) {
mUSSDRegistrant = new Registrant (h, what, obj);
}
- public void
- setOnSuppServiceNotification(Handler h, int what, Object obj) {
+ public void unSetOnUSSD(Handler h) {
+ mUSSDRegistrant.clear();
+ }
+
+ public void setOnSuppServiceNotification(Handler h, int what, Object obj) {
mSsnRegistrant = new Registrant (h, what, obj);
}
- public void
- setOnStkSessionEnd(Handler h, int what, Object obj) {
+ public void unSetOnSuppServiceNotification(Handler h) {
+ mSsnRegistrant.clear();
+ }
+
+ public void setOnStkSessionEnd(Handler h, int what, Object obj) {
mStkSessionEndRegistrant = new Registrant (h, what, obj);
}
- public void
- setOnStkProactiveCmd(Handler h, int what, Object obj) {
+ public void unSetOnStkSessionEnd(Handler h) {
+ mStkSessionEndRegistrant.clear();
+ }
+
+ public void setOnStkProactiveCmd(Handler h, int what, Object obj) {
mStkProCmdRegistrant = new Registrant (h, what, obj);
}
- public void
- setOnStkEvent(Handler h, int what, Object obj) {
+ public void unSetOnStkProactiveCmd(Handler h) {
+ mStkProCmdRegistrant.clear();
+ }
+
+ public void setOnStkEvent(Handler h, int what, Object obj) {
mStkEventRegistrant = new Registrant (h, what, obj);
}
- public void
- setOnStkCallSetUp(Handler h, int what, Object obj) {
+ public void unSetOnStkEvent(Handler h) {
+ mStkEventRegistrant.clear();
+ }
+
+ public void setOnStkCallSetUp(Handler h, int what, Object obj) {
mStkCallSetUpRegistrant = new Registrant (h, what, obj);
}
- public void setOnSimSmsFull(Handler h, int what, Object obj) {
- mSimSmsFullRegistrant = new Registrant (h, what, obj);
+ public void unSetOnStkCallSetUp(Handler h) {
+ mStkCallSetUpRegistrant.clear();
+ }
+
+ public void setOnIccSmsFull(Handler h, int what, Object obj) {
+ mIccSmsFullRegistrant = new Registrant (h, what, obj);
+ }
+
+ public void unSetOnIccSmsFull(Handler h) {
+ mIccSmsFullRegistrant.clear();
}
public void setOnIccRefresh(Handler h, int what, Object obj) {
mIccRefreshRegistrant = new Registrant (h, what, obj);
}
-
+
+ public void unSetOnIccRefresh(Handler h) {
+ mIccRefreshRegistrant.clear();
+ }
+
public void setOnCallRing(Handler h, int what, Object obj) {
mRingRegistrant = new Registrant (h, what, obj);
}
-
-
+
+ public void unSetOnCallRing(Handler h) {
+ mRingRegistrant.clear();
+ }
+
+ public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
+ Registrant r = new Registrant (h, what, obj);
+ mVoicePrivacyOnRegistrants.add(r);
+ }
+
+ public void unregisterForInCallVoicePrivacyOn(Handler h){
+ mVoicePrivacyOnRegistrants.remove(h);
+ }
+
+ public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
+ Registrant r = new Registrant (h, what, obj);
+ mVoicePrivacyOffRegistrants.add(r);
+ }
+
+ public void unregisterForInCallVoicePrivacyOff(Handler h){
+ mVoicePrivacyOffRegistrants.remove(h);
+ }
+
+
//***** Protected Methods
/**
* Store new RadioState and send notification based on the changes
@@ -333,24 +466,24 @@ public abstract class BaseCommands implements CommandsInterface {
*/
protected void setRadioState(RadioState newState) {
RadioState oldState;
-
+
synchronized (mStateMonitor) {
if (Config.LOGV) {
Log.v(LOG_TAG, "setRadioState old: " + mState
+ " new " + newState);
}
-
+
oldState = mState;
mState = newState;
-
+
if (oldState == mState) {
// no state transition
return;
}
if (mContext != null &&
- newState == RadioState.RADIO_UNAVAILABLE &&
- oldState != RadioState.RADIO_OFF) {
+ newState == RadioState.RADIO_UNAVAILABLE &&
+ oldState != RadioState.RADIO_OFF) {
Checkin.updateStats(mContext.getContentResolver(),
Checkin.Stats.Tag.PHONE_RADIO_RESETS, 1, 0.0);
}
@@ -376,7 +509,7 @@ public abstract class BaseCommands implements CommandsInterface {
if (mState == RadioState.SIM_LOCKED_OR_ABSENT) {
Log.d(LOG_TAG,"Notifying: SIM locked or absent");
mSIMLockedRegistrants.notifyRegistrants();
- }
+ }
if (mState.isRUIMReady() && !oldState.isRUIMReady()) {
Log.d(LOG_TAG,"Notifying: RUIM ready");
@@ -386,7 +519,7 @@ public abstract class BaseCommands implements CommandsInterface {
if (mState == RadioState.RUIM_LOCKED_OR_ABSENT) {
Log.d(LOG_TAG,"Notifying: RUIM locked or absent");
mRUIMLockedRegistrants.notifyRegistrants();
- }
+ }
if (mState.isNVReady() && !oldState.isNVReady()) {
Log.d(LOG_TAG,"Notifying: NV ready");
mNVReadyRegistrants.notifyRegistrants();
@@ -395,34 +528,44 @@ public abstract class BaseCommands implements CommandsInterface {
if (mState.isOn() && !oldState.isOn()) {
Log.d(LOG_TAG,"Notifying: Radio On");
mOnRegistrants.notifyRegistrants();
- }
+ }
- if ((!mState.isOn() || !mState.isAvailable())
+ if ((!mState.isOn() || !mState.isAvailable())
&& !((!oldState.isOn() || !oldState.isAvailable()))
) {
Log.d(LOG_TAG,"Notifying: radio off or not available");
mOffOrNotAvailRegistrants.notifyRegistrants();
}
- if ((mState.isGsm() && !oldState.isGsm())
- || (mState.isCdma() && !oldState.isCdma())) {
- Log.d(LOG_TAG,"Notifying: radio technology change");
+ /* Radio Technology Change events
+ * NOTE: isGsm and isCdma have no common states in RADIO_OFF or RADIO_UNAVAILABLE; the
+ * current phone is determined by mPhoneType
+ * NOTE: at startup no phone have been created and the RIL determines the mPhoneType
+ * looking based on the networkMode set by the PhoneFactory in the constructor
+ */
+
+ if (mState.isGsm() && oldState.isCdma()) {
+ Log.d(LOG_TAG,"Notifying: radio technology change CDMA to GSM");
+ mRadioTechnologyChangedRegistrants.notifyRegistrants();
+ }
+
+ if (mState.isGsm() && !oldState.isOn() && (mPhoneType == RILConstants.CDMA_PHONE)) {
+ Log.d(LOG_TAG,"Notifying: radio technology change CDMA OFF to GSM");
+ mRadioTechnologyChangedRegistrants.notifyRegistrants();
+ }
+
+ if (mState.isCdma() && oldState.isGsm()) {
+ Log.d(LOG_TAG,"Notifying: radio technology change GSM to CDMA");
mRadioTechnologyChangedRegistrants.notifyRegistrants();
}
- if ( (mState.isGsm() && !mState.isCdma() &&!oldState.isOn()
- && (mPhoneType == RILConstants.CDMA_PHONE))
- || (mState.isCdma() && !mState.isCdma() &&!oldState.isOn()
- && (mPhoneType == RILConstants.GSM_PHONE)) ){
- //NOTE isGsm and isCdma shares 2 common states
- //NOTE second || should never happen
- Log.d(LOG_TAG,"Notifying: radio technology change at startup");
+ if (mState.isCdma() && !oldState.isOn() && (mPhoneType == RILConstants.GSM_PHONE)) {
+ Log.d(LOG_TAG,"Notifying: radio technology change GSM OFF to CDMA");
mRadioTechnologyChangedRegistrants.notifyRegistrants();
}
}
}
- protected void
- onRadioAvailable() {
+ protected void onRadioAvailable() {
}
}
diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java
index 75485e0fd5ad..70471b634153 100644
--- a/telephony/java/com/android/internal/telephony/Call.java
+++ b/telephony/java/com/android/internal/telephony/Call.java
@@ -40,13 +40,13 @@ public abstract class Call {
}
}
-
+
/* Instance Variables */
-
+
public State state = State.IDLE;
-
-
+
+
/* Instance Methods */
/** Do not modify the List result!!! This list is not yours to keep
@@ -61,28 +61,28 @@ public abstract class Call {
/**
* hasConnection
- *
+ *
* @param c a Connection object
* @return true if the call contains the connection object passed in
*/
public boolean hasConnection(Connection c) {
return c.getCall() == this;
}
-
+
/**
* hasConnections
* @return true if the call contains one or more connections
*/
public boolean hasConnections() {
List connections = getConnections();
-
+
if (connections == null) {
return false;
}
-
+
return connections.size() > 0;
}
-
+
/**
* getState
* @return state of class call
@@ -90,10 +90,10 @@ public abstract class Call {
public State getState() {
return state;
}
-
+
/**
* isIdle
- *
+ *
* FIXME rename
* @return true if the call contains only disconnected connections (if any)
*/
@@ -111,27 +111,27 @@ public abstract class Call {
long time = Long.MAX_VALUE;
Connection c;
Connection earliest = null;
-
+
l = getConnections();
-
+
if (l.size() == 0) {
return null;
}
-
+
for (int i = 0, s = l.size() ; i < s ; i++) {
c = (Connection) l.get(i);
long t;
-
+
t = c.getCreateTime();
-
+
if (t < time) {
earliest = c;
}
}
-
+
return earliest;
}
-
+
public long
getEarliestCreateTime() {
List l;
diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java
index 770236e3231e..eb339f869b8a 100644
--- a/telephony/java/com/android/internal/telephony/CallTracker.java
+++ b/telephony/java/com/android/internal/telephony/CallTracker.java
@@ -16,40 +16,34 @@
package com.android.internal.telephony;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.android.internal.telephony.gsm.CommandException;
-//import com.android.internal.telephony.gsm.DriverCall;
-//import com.android.internal.telephony.gsm.GsmConnection;
-
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
+import com.android.internal.telephony.CommandException;
+
+
/**
* {@hide}
*/
public abstract class CallTracker extends Handler {
- static final String LOG_TAG = "CallTracker";
-
+
private static final boolean DBG_POLL = false;
-
+
//***** Constants
static final int POLL_DELAY_MSEC = 250;
-
+
protected int pendingOperations;
protected boolean needsPoll;
protected Message lastRelevantPoll;
-
+
public CommandsInterface cm;
-
-
-
+
+
//***** 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;
@@ -62,20 +56,17 @@ public abstract class CallTracker extends Handler {
protected static final int EVENT_CONFERENCE_RESULT = 11;
protected static final int EVENT_SEPARATE_RESULT = 12;
protected static final int EVENT_ECT_RESULT = 13;
-
- // Events for CDMA support
-
protected void pollCallsWhenSafe() {
needsPoll = true;
if (checkNoOperationsPending()) {
lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
- cm.getCurrentCalls(lastRelevantPoll);
+ cm.getCurrentCalls(lastRelevantPoll);
}
}
-
+
protected void
pollCallsAfterDelay() {
Message msg = obtainMessage();
@@ -84,27 +75,24 @@ public abstract class CallTracker extends Handler {
sendMessageDelayed(msg, POLL_DELAY_MSEC);
}
-
-
protected boolean
isCommandExceptionRadioNotAvailable(Throwable e) {
return e != null && e instanceof CommandException
&& ((CommandException)e).getCommandError()
== CommandException.Error.RADIO_NOT_AVAILABLE;
}
-
+
protected abstract void handlePollCalls(AsyncResult ar);
-
protected void handleRadioAvailable() {
pollCallsWhenSafe();
}
-
+
/**
* Obtain a complete message that indicates that this operation
* does not require polling of getCurrentCalls(). However, if other
- * operations that do need getCurrentCalls() are pending or are
- * scheduled while this operation is pending, the invocatoin
+ * operations that do need getCurrentCalls() are pending or are
+ * scheduled while this operation is pending, the invocation
* of getCurrentCalls() will be postponed until this
* operation is also complete.
*/
@@ -114,7 +102,7 @@ public abstract class CallTracker extends Handler {
lastRelevantPoll = null;
return obtainMessage(what);
}
-
+
/**
* @return true if we're idle or there's a call to getCurrentCalls() pending
* but nothing else
@@ -125,15 +113,11 @@ public abstract class CallTracker extends Handler {
pendingOperations);
return pendingOperations == 0;
}
-
-
-
-
- //***** Overridden from Handler
+
+
+ //***** Overridden from Handler
public abstract void handleMessage (Message msg);
- private void log(String msg) {
- Log.d(LOG_TAG, "[CallTracker] " + msg);
- }
-
+ protected abstract void log(String msg);
+
}
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 5f630f80b860..9bf64e91eadf 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -46,13 +46,13 @@ public class CallerInfo {
/* 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;
@@ -82,7 +82,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;
@@ -90,9 +90,9 @@ public class CallerInfo {
info.numberLabel = null;
info.cachedPhoto = null;
info.isCachedPhotoCurrent = false;
-
+
if (Config.LOGV) Log.v(TAG, "construct callerInfo from cursor");
-
+
if (cursor != null) {
if (cursor.moveToFirst()) {
@@ -109,7 +109,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) {
@@ -133,7 +133,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);
@@ -146,7 +146,7 @@ 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);
}
cursor.close();
@@ -158,7 +158,7 @@ public class CallerInfo {
return info;
}
-
+
/**
* getCallerInfo given a URI, look up in the call-log database
* for the uri unique key.
@@ -168,11 +168,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.
@@ -188,7 +188,7 @@ 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();
@@ -206,7 +206,7 @@ public class CallerInfo {
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;
@@ -214,16 +214,16 @@ public class CallerInfo {
}
}
- Uri contactUri = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, number);
-
+ Uri contactUri = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, 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;
}
@@ -235,9 +235,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()
@@ -267,5 +267,5 @@ 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 6cb829d0d0b4..98ef4dd443a0 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 = "CallerInfoAsyncQuery";
-
+
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,11 +216,11 @@ 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();
@@ -238,80 +238,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 {
@@ -320,13 +320,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;
@@ -334,24 +334,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);
}
@@ -377,12 +377,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/gsm/CommandException.java b/telephony/java/com/android/internal/telephony/CommandException.java
index 6c57580b17cd..a5d11cf250d8 100644
--- a/telephony/java/com/android/internal/telephony/gsm/CommandException.java
+++ b/telephony/java/com/android/internal/telephony/CommandException.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
import com.android.internal.telephony.RILConstants;
@@ -48,19 +48,19 @@ public class CommandException extends RuntimeException {
fromRilErrno(int ril_errno) {
switch(ril_errno) {
case RILConstants.SUCCESS: return null;
- case RILConstants.RIL_ERRNO_INVALID_RESPONSE:
+ case RILConstants.RIL_ERRNO_INVALID_RESPONSE:
return new CommandException(Error.INVALID_RESPONSE);
- case RILConstants.RADIO_NOT_AVAILABLE:
+ case RILConstants.RADIO_NOT_AVAILABLE:
return new CommandException(Error.RADIO_NOT_AVAILABLE);
- case RILConstants.GENERIC_FAILURE:
+ case RILConstants.GENERIC_FAILURE:
return new CommandException(Error.GENERIC_FAILURE);
- case RILConstants.PASSWORD_INCORRECT:
+ case RILConstants.PASSWORD_INCORRECT:
return new CommandException(Error.PASSWORD_INCORRECT);
- case RILConstants.SIM_PIN2:
+ case RILConstants.SIM_PIN2:
return new CommandException(Error.SIM_PIN2);
- case RILConstants.SIM_PUK2:
+ case RILConstants.SIM_PUK2:
return new CommandException(Error.SIM_PUK2);
- case RILConstants.REQUEST_NOT_SUPPORTED:
+ case RILConstants.REQUEST_NOT_SUPPORTED:
return new CommandException(Error.REQUEST_NOT_SUPPORTED);
case RILConstants.OP_NOT_ALLOWED_DURING_VOICE_CALL:
return new CommandException(Error.OP_NOT_ALLOWED_DURING_VOICE_CALL);
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 439bcb0fc901..ee743f8b9d99 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -16,10 +16,10 @@
package com.android.internal.telephony;
-//import com.android.internal.telephony.*;
import android.os.Message;
import android.os.Handler;
+
/**
* {@hide}
*/
@@ -28,12 +28,12 @@ public interface CommandsInterface {
RADIO_OFF, /* Radio explictly powered off (eg CFUN=0) */
RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */
SIM_NOT_READY, /* Radio is on, but the SIM interface is not ready */
- SIM_LOCKED_OR_ABSENT, /* SIM PIN locked, PUK required, network
+ SIM_LOCKED_OR_ABSENT, /* SIM PIN locked, PUK required, network
personalization, or SIM absent */
SIM_READY, /* Radio is on and SIM interface is available */
RUIM_NOT_READY, /* Radio is on, but the RUIM interface is not ready */
RUIM_READY, /* Radio is on and the RUIM interface is available */
- RUIM_LOCKED_OR_ABSENT, /* RUIM PIN locked, PUK required, network
+ RUIM_LOCKED_OR_ABSENT, /* RUIM PIN locked, PUK required, network
personalization locked, or RUIM absent */
NV_NOT_READY, /* Radio is on, but the NV interface is not available */
NV_READY; /* Radio is on and the NV interface is available */
@@ -49,32 +49,30 @@ public interface CommandsInterface {
|| this == NV_READY;
}
- boolean isAvailable() {
+ public boolean isAvailable() {
return this != RADIO_UNAVAILABLE;
}
- boolean isSIMReady() {
+ public boolean isSIMReady() {
return this == SIM_READY;
}
-
- boolean isRUIMReady() {
+
+ public boolean isRUIMReady() {
return this == RUIM_READY;
}
-
- boolean isNVReady() {
+
+ public boolean isNVReady() {
return this == NV_READY;
}
- boolean isGsm() {
- return this == RADIO_OFF
- || this == RADIO_UNAVAILABLE
- || this == SIM_NOT_READY
+
+ public boolean isGsm() {
+ return this == SIM_NOT_READY
|| this == SIM_LOCKED_OR_ABSENT
|| this == SIM_READY;
}
- boolean isCdma() {
- return this == RADIO_OFF
- || this == RADIO_UNAVAILABLE
- || this == RUIM_NOT_READY
+
+ public boolean isCdma() {
+ return this == RUIM_NOT_READY
|| this == RUIM_READY
|| this == RUIM_LOCKED_OR_ABSENT
|| this == NV_NOT_READY
@@ -124,7 +122,7 @@ public interface CommandsInterface {
static final String CB_FACILITY_BA_MT = "AC";
static final String CB_FACILITY_BA_SIM = "SC";
static final String CB_FACILITY_BA_FD = "FD";
-
+
// Used for various supp services apis
// See 27.007 +CCFC or +CLCK
@@ -133,7 +131,7 @@ public interface CommandsInterface {
static final int SERVICE_CLASS_DATA = (1 << 1); //synoym for 16+32+64+128
static final int SERVICE_CLASS_FAX = (1 << 2);
static final int SERVICE_CLASS_SMS = (1 << 3);
- static final int SERVICE_CLASS_DATA_SYNC = (1 << 4);
+ static final int SERVICE_CLASS_DATA_SYNC = (1 << 4);
static final int SERVICE_CLASS_DATA_ASYNC = (1 << 5);
static final int SERVICE_CLASS_PACKET = (1 << 6);
static final int SERVICE_CLASS_PAD = (1 << 7);
@@ -153,8 +151,8 @@ public interface CommandsInterface {
RadioState getRadioState();
- /**
- * Fires on any RadioState transition
+ /**
+ * Fires on any RadioState transition
* Always fires immediately as well
*
* do not attempt to calculate transitions by storing getRadioState() values
@@ -162,68 +160,86 @@ public interface CommandsInterface {
* registration methods
*/
void registerForRadioStateChanged(Handler h, int what, Object obj);
+ void unregisterForRadioStateChanged(Handler h);
- /**
- * Fires on any transition into RadioState.isOn()
+ /**
+ * Fires on any transition into RadioState.isOn()
* Fires immediately if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForOn(Handler h, int what, Object obj);
+ void unregisterForOn(Handler h);
- /**
- * Fires on any transition out of RadioState.isAvailable()
+ /**
+ * Fires on any transition out of RadioState.isAvailable()
* Fires immediately if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForAvailable(Handler h, int what, Object obj);
- //void unregisterForAvailable(Handler h);
- /**
+ void unregisterForAvailable(Handler h);
+
+ /**
* Fires on any transition into !RadioState.isAvailable()
* Fires immediately if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForNotAvailable(Handler h, int what, Object obj);
- //void unregisterForNotAvailable(Handler h);
- /**
+ void unregisterForNotAvailable(Handler h);
+
+ /**
* Fires on any transition into RADIO_OFF or !RadioState.isAvailable()
* Fires immediately if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForOffOrNotAvailable(Handler h, int what, Object obj);
- //void unregisterForNotAvailable(Handler h);
+ void unregisterForOffOrNotAvailable(Handler h);
- /**
+ /**
* Fires on any transition into SIM_READY
* Fires immediately if if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForSIMReady(Handler h, int what, Object obj);
- //void unregisterForSIMReady(Handler h);
+ void unregisterForSIMReady(Handler h);
+
/** Any transition into SIM_LOCKED_OR_ABSENT */
void registerForSIMLockedOrAbsent(Handler h, int what, Object obj);
- //void unregisterForSIMLockedOrAbsent(Handler h);
+ void unregisterForSIMLockedOrAbsent(Handler h);
void registerForCallStateChanged(Handler h, int what, Object obj);
- //void unregisterForCallStateChanged(Handler h);
+ void unregisterForCallStateChanged(Handler h);
void registerForNetworkStateChanged(Handler h, int what, Object obj);
- //void unregisterForNetworkStateChanged(Handler h);
- void registerForPDPStateChanged(Handler h, int what, Object obj);
- //void unregisterForPDPStateChanged(Handler h);
+ void unregisterForNetworkStateChanged(Handler h);
+ void registerForDataStateChanged(Handler h, int what, Object obj);
+ void unregisterForDataStateChanged(Handler h);
void registerForRadioTechnologyChanged(Handler h, int what, Object obj);
- //void unregisterForRadioTechnologyChanged(Handler h);
+ void unregisterForRadioTechnologyChanged(Handler h);
void registerForNVReady(Handler h, int what, Object obj);
- //void unregisterForNVReady(Handler h, int what, Object obj);
+ void unregisterForNVReady(Handler h);
void registerForRUIMLockedOrAbsent(Handler h, int what, Object obj);
- //void unregisterForRUIMLockedOrAbsent(Handler h, int what, Object obj);
+ void unregisterForRUIMLockedOrAbsent(Handler h);
+
+ /** InCall voice privacy notifications */
+ void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
+ void unregisterForInCallVoicePrivacyOn(Handler h);
+ void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj);
+ void unregisterForInCallVoicePrivacyOff(Handler h);
+
+ /**
+ * Fires on any transition into RUIM_READY
+ * Fires immediately if if currently in that state
+ * In general, actions should be idempotent. State may change
+ * before event is received.
+ */
void registerForRUIMReady(Handler h, int what, Object obj);
- //void unregisterForRUIMReady(Handler h, int what, Object obj);
-
+ void unregisterForRUIMReady(Handler h);
+
/**
* unlike the register* methods, there's only one new SMS handler
* if you need to unregister, you should also tell the radio to stop
@@ -232,27 +248,30 @@ public interface CommandsInterface {
* AsyncResult.result is a String containing the SMS PDU
*/
void setOnNewSMS(Handler h, int what, Object obj);
+ void unSetOnNewSMS(Handler h);
/**
- * Register for NEW_SMS_ON_SIM unsolicited message
+ * Register for NEW_SMS_ON_SIM unsolicited message
*
* AsyncResult.result is an int array containing the index of new SMS
*/
void setOnSmsOnSim(Handler h, int what, Object obj);
+ void unSetOnSmsOnSim(Handler h);
/**
- * Register for NEW_SMS_STATUS_REPORT unsolicited message
+ * Register for NEW_SMS_STATUS_REPORT unsolicited message
*
* AsyncResult.result is a String containing the status report PDU
*/
void setOnSmsStatus(Handler h, int what, Object obj);
-
+ void unSetOnSmsStatus(Handler h);
+
/**
* unlike the register* methods, there's only one NITZ time handler
*
* AsyncResult.result is an Object[]
* ((Object[])AsyncResult.result)[0] is a String containing the NITZ time string
- * ((Object[])AsyncResult.result)[0] is an Integer containing
+ * ((Object[])AsyncResult.result)[0] is an Integer containing
* the UNIX time_t returned by time() when
* this NITZ time was posted.
*
@@ -260,13 +279,14 @@ public interface CommandsInterface {
* seconds on system startup
*/
void setOnNITZTime(Handler h, int what, Object obj);
+ void unSetOnNITZTime(Handler h);
/**
* unlike the register* methods, there's only one USSD notify handler
*
* Represents the arrival of a USSD "notify" message, which may
* or may not have been triggered by a previous USSD send
- *
+ *
* AsyncResult.result is a String[]
* ((String[])(AsyncResult.result))[0] contains status code
* "0" USSD-Notify -- text in ((const char **)data)[1]
@@ -281,26 +301,29 @@ public interface CommandsInterface {
*/
void setOnUSSD(Handler h, int what, Object obj);
+ void unSetOnUSSD(Handler h);
/**
* unlike the register* methods, there's only one signal strength handler
- * AsyncResult.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)
+ * AsyncResult.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)
* as defined in TS 27.007 8.5
*/
void setOnSignalStrengthUpdate(Handler h, int what, Object obj);
+ void unSetOnSignalStrengthUpdate(Handler h);
/**
- * Sets the handler for SIM SMS storage full unsolicited message.
+ * Sets the handler for SIM/RUIM SMS storage full unsolicited message.
* 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 setOnSimSmsFull(Handler h, int what, Object obj);
+ void setOnIccSmsFull(Handler h, int what, Object obj);
+ void unSetOnIccSmsFull(Handler h);
/**
* Sets the handler for SIM Refresh notifications.
@@ -311,7 +334,8 @@ public interface CommandsInterface {
* @param obj User object.
*/
void setOnIccRefresh(Handler h, int what, Object obj);
-
+ void unSetOnIccRefresh(Handler h);
+
/**
* Sets the handler for RING notifications.
* Unlike the register* methods, there's only one notification handler
@@ -321,7 +345,8 @@ public interface CommandsInterface {
* @param obj User object.
*/
void setOnCallRing(Handler h, int what, Object obj);
-
+ void unSetOnCallRing(Handler h);
+
/**
* Sets the handler for Supplementary Service Notifications.
* Unlike the register* methods, there's only one notification handler
@@ -331,6 +356,7 @@ public interface CommandsInterface {
* @param obj User object.
*/
void setOnSuppServiceNotification(Handler h, int what, Object obj);
+ void unSetOnSuppServiceNotification(Handler h);
/**
* Sets the handler for Session End Notifications for STK.
@@ -341,6 +367,7 @@ public interface CommandsInterface {
* @param obj User object.
*/
void setOnStkSessionEnd(Handler h, int what, Object obj);
+ void unSetOnStkSessionEnd(Handler h);
/**
* Sets the handler for Proactive Commands for STK.
@@ -351,6 +378,7 @@ public interface CommandsInterface {
* @param obj User object.
*/
void setOnStkProactiveCmd(Handler h, int what, Object obj);
+ void unSetOnStkProactiveCmd(Handler h);
/**
* Sets the handler for Event Notifications for STK.
@@ -361,6 +389,7 @@ public interface CommandsInterface {
* @param obj User object.
*/
void setOnStkEvent(Handler h, int what, Object obj);
+ void unSetOnStkEvent(Handler h);
/**
* Sets the handler for Call Set Up Notifications for STK.
@@ -371,6 +400,7 @@ public interface CommandsInterface {
* @param obj User object.
*/
void setOnStkCallSetUp(Handler h, int what, Object obj);
+ void unSetOnStkCallSetUp(Handler h);
/**
* Enables/disbables supplementary service related notifications from
@@ -380,19 +410,21 @@ public interface CommandsInterface {
* @param result Message to be posted when command completes.
*/
void setSuppServiceNotifications(boolean enable, Message result);
+ //void unSetSuppServiceNotifications(Handler h);
+
/**
* Returns current ICC status.
*
* AsyncResult.result is IccStatus
- *
+ *
*/
- void getIccStatus(Message result);
+ void getIccStatus(Message result);
/**
* Supply the ICC PIN to the ICC card
- *
+ *
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -406,7 +438,7 @@ public interface CommandsInterface {
/**
* Supply the ICC PUK to the ICC card
- *
+ *
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -422,7 +454,7 @@ public interface CommandsInterface {
* Supply the ICC PIN2 to the ICC card
* Only called following operation where ICC_PIN2 was
* returned as a a failure from a previous operation
- *
+ *
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -438,7 +470,7 @@ public interface CommandsInterface {
* Supply the SIM PUK2 to the SIM card
* Only called following operation where SIM_PUK2 was
* returned as a a failure from a previous operation
- *
+ *
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -457,7 +489,7 @@ public interface CommandsInterface {
void supplyNetworkDepersonalization(String netpin, Message result);
- /**
+ /**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -467,16 +499,26 @@ public interface CommandsInterface {
*/
void getCurrentCalls (Message result);
- /**
+ /**
* returned message
* 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
+ * @deprecated
*/
void getPDPContextList(Message result);
- /**
+ /**
+ * returned message
+ * 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
+ */
+ void getDataCallList(Message result);
+
+ /**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -489,7 +531,7 @@ public interface CommandsInterface {
*/
void dial (String address, int clirMode, Message result);
- /**
+ /**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -498,7 +540,7 @@ public interface CommandsInterface {
*/
void getIMSI(Message result);
- /**
+ /**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -507,7 +549,7 @@ public interface CommandsInterface {
*/
void getIMEI(Message result);
- /**
+ /**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -516,7 +558,7 @@ public interface CommandsInterface {
*/
void getIMEISV(Message result);
- /**
+ /**
* Hang up one individual connection.
* returned message
* retMsg.obj = AsyncResult ar
@@ -541,7 +583,7 @@ public interface CommandsInterface {
/**
* 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
@@ -552,7 +594,7 @@ public interface CommandsInterface {
/**
* 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
@@ -568,7 +610,7 @@ public interface CommandsInterface {
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result is null on success and failure
- */
+ */
void conference (Message result);
/**
@@ -578,7 +620,7 @@ public interface CommandsInterface {
* @param result is a callback message
*/
void setPreferredVoicePrivacy(boolean enable, Message result);
-
+
/**
* Get currently set preferred Voice Privacy (VP) mode.
*
@@ -588,7 +630,7 @@ public interface CommandsInterface {
/**
* 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."
*/
void separateConnection (int gsmIndex, Message result);
@@ -598,15 +640,15 @@ public interface CommandsInterface {
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result is null on success and failure
- */
+ */
void acceptCall (Message result);
- /**
+ /**
* 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
- */
+ */
void rejectCall (Message result);
/**
@@ -630,14 +672,21 @@ public interface CommandsInterface {
void getLastCallFailCause (Message result);
- /**
+ /**
* Reason for last PDP context deactivate or failure to activate
* cause code returned as int[0] in Message.obj.response
* returns an integer cause code defined in TS 24.008
* section 6.1.3.1.3 or close approximation
+ * @deprecated
*/
void getLastPdpFailCause (Message result);
+ /**
+ * The preferred new alternative to getLastPdpFailCause
+ * that is also CDMA-compatible.
+ */
+ void getLastDataCallFailCause (Message result);
+
void setMute (boolean enableMute, Message response);
void getMute (Message response);
@@ -645,8 +694,8 @@ public interface CommandsInterface {
/**
* 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
*/
void getSignalStrength (Message response);
@@ -656,21 +705,21 @@ public interface CommandsInterface {
* response.obj.result is an int[3]
* response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
* response.obj.result[1] is LAC if registered or -1 if not
- * response.obj.result[2] is CID if registered or -1 if not
+ * response.obj.result[2] is CID if registered or -1 if not
* valid LAC and CIDs are 0x0000 - 0xffff
- *
+ *
* Please note that registration state 4 ("unknown") is treated
* as "out of service" above
*/
void getRegistrationState (Message response);
-
+
/**
* response.obj.result is an int[3]
* response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
* response.obj.result[1] is LAC if registered or -1 if not
- * response.obj.result[2] is CID if registered or -1 if not
+ * response.obj.result[2] is CID if registered or -1 if not
* valid LAC and CIDs are 0x0000 - 0xffff
- *
+ *
* Please note that registration state 4 ("unknown") is treated
* as "out of service" above
*/
@@ -681,14 +730,14 @@ public interface CommandsInterface {
* 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
- */
+ */
void getOperator(Message response);
/**
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result is null on success and failure
- */
+ */
void sendDtmf(char c, Message result);
@@ -711,26 +760,40 @@ public interface CommandsInterface {
* 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
*/
void sendSMS (String smscPDU, String pdu, Message response);
/**
+ * @param pdu is CDMA-SMS in internal pseudo-PDU format
+ * @param response sent when operation completes
+ */
+ void sendCdmaSms(byte[] pdu, Message response);
+
+ /**
* Deletes the specified SMS record from SIM memory (EF_SMS).
- *
+ *
* @param index index of the SMS record to delete
* @param response sent when operation completes
*/
void deleteSmsOnSim(int index, Message response);
/**
+ * Deletes the specified SMS record from RUIM memory (EF_SMS in DF_CDMA).
+ *
+ * @param index index of the SMS record to delete
+ * @param response sent when operation completes
+ */
+ void deleteSmsOnRuim(int index, Message response);
+
+ /**
* Writes an SMS message to SIM memory (EF_SMS).
- *
+ *
* @param status status of message on SIM. One of:
- * SmsManger.STATUS_ON_SIM_READ
- * SmsManger.STATUS_ON_SIM_UNREAD
- * SmsManger.STATUS_ON_SIM_SENT
- * SmsManger.STATUS_ON_SIM_UNSENT
+ * SmsManger.STATUS_ON_ICC_READ
+ * SmsManger.STATUS_ON_ICC_UNREAD
+ * SmsManger.STATUS_ON_ICC_SENT
+ * SmsManger.STATUS_ON_ICC_UNSENT
* @param pdu message PDU, as hex string
* @param response sent when operation completes.
* response.obj will be an AsyncResult, and will indicate
@@ -738,89 +801,105 @@ public interface CommandsInterface {
*/
void writeSmsToSim(int status, String smsc, String pdu, Message response);
+ void writeSmsToRuim(int status, String pdu, Message response);
+
+ /**
+ * @deprecated
+ * @param apn
+ * @param user
+ * @param password
+ * @param response
+ */
void setupDefaultPDP(String apn, String user, String password, Message response);
+ /**
+ * @deprecated
+ * @param cid
+ * @param response
+ */
void deactivateDefaultPDP(int cid, Message response);
void setRadioPower(boolean on, Message response);
void acknowledgeLastIncomingSMS(boolean success, Message response);
- /**
- * parameters equivilient to 27.007 AT+CRSM command
+ void acknowledgeLastIncomingCdmaSms(boolean success, Message response);
+
+ /**
+ * parameters equivilient to 27.007 AT+CRSM command
* response.obj will be an AsyncResult
* response.obj.userObj will be a IccIoResult on success
*/
- void iccIO (int command, int fileid, String path, int p1, int p2, int p3,
+ void iccIO (int command, int fileid, String path, int p1, int p2, int p3,
String data, String pin2, Message response);
/**
* (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
*/
-
+
void queryCLIP(Message response);
/**
* 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
*/
void getCLIR(Message response);
-
+
/**
* clirMode is one of the CLIR_* constants above
*
* response.obj is null
*/
-
+
void setCLIR(int clirMode, Message response);
/**
* (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
*/
-
+
void queryCallWaiting(int serviceClass, Message response);
-
+
/**
* @param enable is true to enable, false to disable
* @param serviceClass is a sum of SERVICE_CLASS_*
* @param response is callback message
*/
-
+
void setCallWaiting(boolean enable, int serviceClass, Message response);
/**
* @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_*
*/
- void setCallForward(int action, int cfReason, int serviceClass,
- String number, int timeSeconds, Message response);
+ void setCallForward(int action, int cfReason, int serviceClass,
+ String number, int timeSeconds, Message response);
/**
* cfReason is one of CF_REASON_*
*
* ((AsyncResult)response.obj).result will be an array of
* CallForwardInfo's
- *
+ *
* An array of length 0 means "disabled for all codes"
*/
void queryCallForwardStatus(int cfReason, int serviceClass,
@@ -859,7 +938,7 @@ public interface CommandsInterface {
* @param serviceClass is a sum of SERVICE_CLASS_*
* @param response is callback message
*/
-
+
void queryFacilityLock (String facility, String password, int serviceClass,
Message response);
@@ -872,7 +951,7 @@ public interface CommandsInterface {
*/
void setFacilityLock (String facility, boolean lockState, String password,
int serviceClass, Message response);
-
+
void sendUSSD (String ussdString, Message response);
@@ -894,7 +973,7 @@ public interface CommandsInterface {
/**
* Query the list of band mode supported by RF.
- *
+ *
* @param response is callback message
* ((AsyncResult)response.obj).result is an int[] with every
* element representing one avialable BM_*_BAND
@@ -969,15 +1048,15 @@ public interface CommandsInterface {
public void handleCallSetupRequestFromSim(boolean accept, Message response);
//***** new Methods for CDMA support
-
+
/**
* Request the device ESN / MEID / IMEI / IMEISV.
* "response" is const char **
* [0] is IMEI if GSM subscription is available
* [1] is IMEISV if GSM subscription is available
* [2] is ESN if CDMA subscription is available
- * [3] is MEID if CDMA subscription is available
- */
+ * [3] is MEID if CDMA subscription is available
+ */
public void getDeviceIdentity(Message response);
/**
@@ -988,16 +1067,15 @@ public interface CommandsInterface {
* [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
- */
+ */
public void getCDMASubscription(Message response);
-
- /**
- * Fires on any transition into RUIM_READY
- * Fires immediately if if currently in that state
- * In general, actions should be idempotent. State may change
- * before event is received.
+
+ /**
+ * Send Flash Code.
+ * "response" is is NULL
+ * [0] is a FLASH string
*/
- //void registerForRUIMReady(Handler h, int what, Object obj); //TODO check moved above
+ public void sendCDMAFeatureCode(String FeatureCode, Message response);
/** Set the Phone type created */
void setPhoneType(int phoneType);
@@ -1007,21 +1085,21 @@ public interface CommandsInterface {
* @param response is callback message to report one of CDMA_RM_*
*/
void queryCdmaRoamingPreference(Message response);
-
+
/**
* Requests to set the CDMA roaming preference
* @param cdmaRoamingType one of CDMA_RM_*
* @param response is callback message
*/
void setCdmaRoamingPreference(int cdmaRoamingType, Message response);
-
+
/**
* Requests to set the CDMA subscription mode
* @param cdmaSubscriptionType one of CDMA_SUBSCRIPTION_*
* @param response is callback message
*/
void setCdmaSubscription(int cdmaSubscriptionType, Message response);
-
+
/**
* Set the TTY mode for the CDMA phone
*
@@ -1029,14 +1107,75 @@ public interface CommandsInterface {
* @param response is callback message
*/
void setTTYModeEnabled(boolean enable, Message response);
-
+
/**
* 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 response is callback message
*/
void queryTTYModeEnabled(Message response);
+ /**
+ * Setup a packet data connection On successful completion, the result
+ * message will return the following: [0] indicating PDP CID, which is
+ * generated by RIL. This Connection ID is used in both GSM/UMTS and CDMA
+ * modes [1] indicating the network interface name for GSM/UMTS or CDMA [2]
+ * indicating the IP address for this interface for GSM/UMTS and NULL in the
+ * case of CDMA
+ *
+ * @param radioTechnology
+ * indicates whether to setup connection on radio technology CDMA
+ * (0) or GSM/UMTS (1)
+ * @param profile
+ * Profile Number or NULL to indicate default profile
+ * @param apn
+ * the APN to connect to if radio technology is GSM/UMTS.
+ * Otherwise null for CDMA.
+ * @param user
+ * the username for APN, or NULL
+ * @param password
+ * the password for APN, or NULL
+ * @param result
+ * Callback message
+ */
+ public void setupDataCall(String radioTechnology, String profile, String apn,
+ String user, String password, Message result);
+
+ /**
+ * Deactivate packet data connection
+ *
+ * @param cid
+ * The connection ID
+ * @param result
+ * Callback message is empty on completion
+ */
+ public void deactivateDataCall(int cid, Message result);
+
+ /**
+ * Activate or deactivate cell broadcast SMS.
+ *
+ * @param activate
+ * 0 = activate, 1 = deactivate
+ * @param result
+ * Callback message is empty on completion
+ */
+ public void activateCdmaBroadcastSms(int activate, Message result);
+
+ /**
+ * Configure cdma cell broadcast SMS.
+ *
+ * @param result
+ * Callback message is empty on completion
+ */
+ public void setCdmaBroadcastConfig(int[] configValuesArray, Message result);
+
+ /**
+ * Query the current configuration of cdma cell broadcast SMS.
+ *
+ * @param result
+ * Callback message contains the configuration from the modem on completion
+ */
+ public void getCdmaBroadcastConfig(Message result);
}
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
index 2cc7ee2c17f6..d395a4ae71a6 100644
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ b/telephony/java/com/android/internal/telephony/Connection.java
@@ -34,7 +34,7 @@ public abstract class Connection {
INCOMING_REJECTED, /* an incoming call that was rejected */
POWER_OFF, /* radio is turned off explicitly */
OUT_OF_SERVICE, /* out of service */
- SIM_ERROR, /* No SIM, SIM locked, or other SIM error */
+ 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 */
}
@@ -43,7 +43,7 @@ public abstract class Connection {
/* Instance Methods */
- /**
+ /**
* Gets address (e.g., phone number) associated with connection
* TODO: distinguish reasons for unavailablity
*
@@ -81,7 +81,7 @@ public abstract class Connection {
public abstract long getDisconnectTime();
/**
- * returns the number of milliseconds the call has been connected,
+ * returns the number of milliseconds the call has been connected,
* or 0 if the call has never connected.
* If the call is still connected, then returns the elapsed
* time since connect
@@ -102,8 +102,8 @@ public abstract class Connection {
public abstract DisconnectCause getDisconnectCause();
/**
- * Returns true of this connection originated elsewhere
- * ("MT" or mobile terminated; another party called this terminal)
+ * Returns true of this connection originated elsewhere
+ * ("MT" or mobile terminated; another party called this terminal)
* or false if this call originated here (MO or mobile originated)
*/
public abstract boolean isIncoming();
@@ -111,7 +111,7 @@ public abstract class Connection {
/**
* If this Connection is connected, then it is associated with
* a Call.
- *
+ *
* Returns getCall().getState() or Call.State.IDLE if not
* connected
*/
@@ -120,16 +120,16 @@ public abstract class Connection {
c = getCall();
- if (c == null) {
+ if (c == null) {
return Call.State.IDLE;
} else {
return c.getState();
}
}
-
+
/**
* isAlive()
- *
+ *
* @return true if the connection isn't disconnected
* (could be active, holding, ringing, dialing, etc)
*/
@@ -147,7 +147,7 @@ public abstract class Connection {
}
/**
- *
+ *
* @return the userdata set in setUserData()
*/
public Object getUserData() {
@@ -155,13 +155,13 @@ public abstract class Connection {
}
/**
- *
+ *
* @param userdata user can store an any userdata in the Connection object.
*/
public void setUserData(Object userdata) {
this.userData = userdata;
}
-
+
/**
* Hangup individual Connection
*/
@@ -175,16 +175,16 @@ public abstract class Connection {
public abstract void separate() throws CallStateException;
public enum PostDialState {
- NOT_STARTED, /* The post dial string playback hasn't
- been started, or this call is not yet
+ NOT_STARTED, /* The post dial string playback hasn't
+ been started, or this call is not yet
connected, or this is an incoming call */
STARTED, /* The post dial string playback has begun */
- WAIT, /* The post dial string playback is waiting for a
+ WAIT, /* The post dial string playback is waiting for a
call to proceedAfterWaitChar() */
- WILD, /* The post dial string playback is waiting for a
+ 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() */
}
@@ -199,7 +199,7 @@ public abstract class Connection {
/**
* See Phone.setOnPostDialWaitCharacter()
*/
-
+
public abstract void proceedAfterWaitChar();
/**
@@ -210,6 +210,6 @@ public abstract class Connection {
* Cancel any post
*/
public abstract void cancelPostDial();
-
+
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
new file mode 100644
index 000000000000..0b0dc7a3b744
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -0,0 +1,297 @@
+/*
+ * 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;
+
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+/**
+ * {@hide}
+ */
+public abstract class DataConnection extends Handler {
+
+ // the inherited class
+
+ public enum State {
+ ACTIVE, /* has active data connection */
+ ACTIVATING, /* during connecting process */
+ INACTIVE; /* has empty data connection */
+
+ public String toString() {
+ switch (this) {
+ case ACTIVE:
+ return "active";
+ case ACTIVATING:
+ return "setting up";
+ default:
+ return "inactive";
+ }
+ }
+
+ public boolean isActive() {
+ return this == ACTIVE;
+ }
+
+ public boolean isInactive() {
+ return this == INACTIVE;
+ }
+ }
+
+ public enum FailCause {
+ NONE,
+ BAD_APN,
+ BAD_PAP_SECRET,
+ BARRED,
+ USER_AUTHENTICATION,
+ SERVICE_OPTION_NOT_SUPPORTED,
+ SERVICE_OPTION_NOT_SUBSCRIBED,
+ SIM_LOCKED,
+ RADIO_OFF,
+ NO_SIGNAL,
+ NO_DATA_PLAN,
+ RADIO_NOT_AVAILABLE,
+ SUSPENED_TEMPORARY,
+ RADIO_ERROR_RETRY,
+ UNKNOWN;
+
+ public boolean isPermanentFail() {
+ return (this == RADIO_OFF);
+ }
+
+ 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";
+ case USER_AUTHENTICATION:
+ return "error user autentication";
+ case SERVICE_OPTION_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";
+ case RADIO_NOT_AVAILABLE:
+ return "radio not available";
+ case SUSPENED_TEMPORARY:
+ return "suspend temporary";
+ case RADIO_ERROR_RETRY:
+ return "transient radio error";
+ default:
+ return "unknown data error";
+ }
+ }
+ }
+
+ // ***** Event codes
+ protected static final int EVENT_SETUP_DATA_CONNECTION_DONE = 1;
+ protected static final int EVENT_GET_LAST_FAIL_DONE = 2;
+ protected static final int EVENT_LINK_STATE_CHANGED = 3;
+ protected static final int EVENT_DEACTIVATE_DONE = 4;
+ protected static final int EVENT_FORCE_RETRY = 5;
+
+ //***** Tag IDs for EventLog
+ protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
+
+
+ //***** Member Variables
+ protected PhoneBase phone;
+ protected Message onConnectCompleted;
+ protected Message onDisconnect;
+ protected int cid;
+ protected String interfaceName;
+ protected String ipAddress;
+ protected String gatewayAddress;
+ protected String[] dnsServers;
+ protected State state;
+ protected long createTime;
+ protected long lastFailTime;
+ protected FailCause lastFailCause;
+ protected static final String NULL_IP = "0.0.0.0";
+ Object userData;
+
+ // receivedDisconnectReq is set when disconnect during activation
+ protected boolean receivedDisconnectReq;
+
+ /* Instance Methods */
+ protected abstract void onSetupConnectionCompleted(AsyncResult ar);
+
+ protected abstract void onDeactivated(AsyncResult ar);
+
+ protected abstract void disconnect(Message msg);
+
+ protected abstract void notifyDisconnect(Message msg);
+
+ protected abstract FailCause getFailCauseFromRequest(int rilCause);
+
+ protected abstract void notifyFail(FailCause cause, Message onCompleted);
+
+ protected abstract void onLinkStateChanged(DataLink.LinkState linkState);
+
+ protected abstract void log(String s);
+
+
+ //***** Constructor
+ protected DataConnection(PhoneBase phone) {
+ super();
+ this.phone = phone;
+ onConnectCompleted = null;
+ onDisconnect = null;
+ this.cid = -1;
+ receivedDisconnectReq = false;
+ this.dnsServers = new String[2];
+
+ clearSettings();
+ }
+
+ protected void setHttpProxy(String httpProxy, String httpPort) {
+ if (httpProxy == null || httpProxy.length() == 0) {
+ phone.setSystemProperty("net.gprs.http-proxy", null);
+ return;
+ }
+
+ if (httpPort == null || httpPort.length() == 0) {
+ httpPort = "8080"; // Default to port 8080
+ }
+
+ phone.setSystemProperty("net.gprs.http-proxy",
+ "http://" + httpProxy + ":" + httpPort + "/");
+ }
+
+ public String getInterface() {
+ return interfaceName;
+ }
+
+ public String getIpAddress() {
+ return ipAddress;
+ }
+
+ public String getGatewayAddress() {
+ return gatewayAddress;
+ }
+
+ public String[] getDnsServers() {
+ return dnsServers;
+ }
+
+ public void clearSettings() {
+ log("DataConnection.clearSettings()");
+
+ this.state = State.INACTIVE;
+ this.createTime = -1;
+ this.lastFailTime = -1;
+ this.lastFailCause = FailCause.NONE;
+
+ receivedDisconnectReq = false;
+ onConnectCompleted = null;
+ interfaceName = null;
+ ipAddress = null;
+ gatewayAddress = null;
+ dnsServers[0] = null;
+ dnsServers[1] = null;
+ }
+
+ protected void onGetLastFailCompleted(AsyncResult ar) {
+ if (receivedDisconnectReq) {
+ // Don't bother reporting the error if there's already a
+ // pending disconnect request, since DataConnectionTracker
+ // has already updated its state.
+ notifyDisconnect(onDisconnect);
+ } else {
+ FailCause cause = FailCause.UNKNOWN;
+
+ if (ar.exception == null) {
+ int rilFailCause = ((int[]) (ar.result))[0];
+ cause = getFailCauseFromRequest(rilFailCause);
+ }
+ notifyFail(cause, onConnectCompleted);
+ }
+ }
+
+ protected void onForceRetry() {
+ if (receivedDisconnectReq) {
+ notifyDisconnect(onDisconnect);
+ } else {
+ notifyFail(FailCause.RADIO_ERROR_RETRY, onConnectCompleted);
+ }
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncResult ar;
+
+ log("DataConnection.handleMessage()");
+
+ switch (msg.what) {
+
+ case EVENT_SETUP_DATA_CONNECTION_DONE:
+ onSetupConnectionCompleted((AsyncResult) msg.obj);
+ break;
+
+ case EVENT_FORCE_RETRY:
+ onForceRetry();
+ break;
+
+ case EVENT_GET_LAST_FAIL_DONE:
+ onGetLastFailCompleted((AsyncResult) msg.obj);
+ break;
+
+ case EVENT_LINK_STATE_CHANGED:
+ ar = (AsyncResult) msg.obj;
+ DataLink.LinkState ls = (DataLink.LinkState) ar.result;
+ onLinkStateChanged(ls);
+ break;
+
+ case EVENT_DEACTIVATE_DONE:
+ onDeactivated((AsyncResult) msg.obj);
+ break;
+ }
+ }
+
+ public State getState() {
+ log("DataConnection.getState()");
+ return state;
+ }
+
+ public long getConnectionTime() {
+ log("DataConnection.getConnectionTime()");
+ return createTime;
+ }
+
+ public long getLastFailTime() {
+ log("DataConnection.getLastFailTime()");
+ return lastFailTime;
+ }
+
+ public FailCause getLastFailCause() {
+ log("DataConnection.getLastFailCause()");
+ return lastFailCause;
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
new file mode 100644
index 000000000000..f6469b107416
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -0,0 +1,334 @@
+/*
+ * 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;
+
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.INetStatService;
+import android.os.Message;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.util.Log;
+
+/**
+ * {@hide}
+ *
+ */
+public abstract class DataConnectionTracker extends Handler {
+ private static final boolean DBG = true;
+
+ /**
+ * IDLE: ready to start data connection setup, default state
+ * INITING: state of issued setupDefaultPDP() but not finish yet
+ * CONNECTING: state of issued startPppd() but not finish yet
+ * SCANNING: data connection fails with one apn but other apns are available
+ * ready to start data connection on other apns (before INITING)
+ * CONNECTED: IP connection is setup
+ * FAILED: data connection fail for all apns settings
+ *
+ * getDataConnectionState() maps State to DataState
+ * FAILED or IDLE : DISCONNECTED
+ * INITING or CONNECTING or SCANNING: CONNECTING
+ * CONNECTED : CONNECTED
+ */
+ public enum State {
+ IDLE,
+ INITING,
+ CONNECTING,
+ SCANNING,
+ CONNECTED,
+ FAILED
+ }
+
+ public enum Activity {
+ NONE,
+ DATAIN,
+ DATAOUT,
+ DATAINANDOUT
+ }
+
+ //***** Event Codes
+ protected static final int EVENT_DATA_SETUP_COMPLETE = 1;
+ protected static final int EVENT_RADIO_AVAILABLE = 3;
+ protected static final int EVENT_RECORDS_LOADED = 4;
+ protected static final int EVENT_TRY_SETUP_DATA = 5;
+ protected static final int EVENT_DATA_STATE_CHANGED = 6;
+ protected static final int EVENT_POLL_PDP = 7;
+ protected static final int EVENT_GET_PDP_LIST_COMPLETE = 11;
+ protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 12;
+ protected static final int EVENT_VOICE_CALL_STARTED = 14;
+ protected static final int EVENT_VOICE_CALL_ENDED = 15;
+ protected static final int EVENT_GPRS_DETACHED = 19;
+ protected static final int EVENT_LINK_STATE_CHANGED = 20;
+ protected static final int EVENT_ROAMING_ON = 21;
+ protected static final int EVENT_ROAMING_OFF = 22;
+ protected static final int EVENT_ENABLE_NEW_APN = 23;
+ protected static final int EVENT_RESTORE_DEFAULT_APN = 24;
+ protected static final int EVENT_DISCONNECT_DONE = 25;
+ protected static final int EVENT_GPRS_ATTACHED = 26;
+ protected static final int EVENT_START_NETSTAT_POLL = 27;
+ protected static final int EVENT_START_RECOVERY = 28;
+ protected static final int EVENT_CDMA_DATA_DETACHED = 29;
+ protected static final int EVENT_NV_READY = 30;
+
+ //***** Constants
+ protected static final int RECONNECT_DELAY_INITIAL_MILLIS = 5 * 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;
+ /** Default max failure count before attempting to network re-registration. */
+ protected final int DEFAULT_MAX_PDP_RESET_FAIL = 3;
+
+ /**
+ * After detecting a potential connection problem, this is the max number
+ * of subsequent polls before attempting a radio reset. At this point,
+ * poll interval is 5 seconds (POLL_NETSTAT_SLOW_MILLIS), so set this to
+ * poll for about 2 more minutes.
+ */
+ protected static final int NO_RECV_POLL_LIMIT = 24;
+
+ // 1 sec. default polling interval when screen is on.
+ protected static final int POLL_NETSTAT_MILLIS = 1000;
+ // 10 min. default polling interval when screen is off.
+ protected static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
+ // 2 min for round trip time
+ protected static final int POLL_LONGEST_RTT = 120 * 1000;
+ // 10 for packets without ack
+ protected static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
+ // how long to wait before switching back to default APN
+ protected static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000;
+ // system property that can override the above value
+ protected static final String APN_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore";
+ // represents an invalid IP address
+ protected static final String NULL_IP = "0.0.0.0";
+
+
+ // member variables
+ protected PhoneBase phone;
+ protected Activity activity = Activity.NONE;
+ protected State state = State.IDLE;
+ protected Handler mDataConnectionTracker = null;
+
+
+ protected INetStatService netstat;
+ protected int txPkts, rxPkts, sentSinceLastRecv, netStatPollPeriod;
+ protected int mNoRecvPollCount = 0;
+ protected boolean netStatPollEnabled = false;
+
+ /**
+ * Default constructor
+ */
+ protected DataConnectionTracker(PhoneBase phone) {
+ super();
+ this.phone = phone;
+ }
+
+ public Activity getActivity() {
+ return activity;
+ }
+
+ public State getState() {
+ return state;
+ }
+
+ //The data roaming setting is now located in the shared preferences.
+ // See if the requested preference value is the same as that stored in
+ // the shared values. If it is not, then update it.
+ public void setDataOnRoamingEnabled(boolean enabled) {
+ if (getDataOnRoamingEnabled() != enabled) {
+ Settings.System.putInt(phone.getContext().getContentResolver(),
+ Settings.System.DATA_ROAMING, enabled ? 1 : 0);
+ }
+ Message roamingMsg = phone.getServiceState().getRoaming() ?
+ obtainMessage(EVENT_ROAMING_ON) : obtainMessage(EVENT_ROAMING_OFF);
+ sendMessage(roamingMsg);
+ }
+
+ //Retrieve the data roaming setting from the shared preferences.
+ public boolean getDataOnRoamingEnabled() {
+ try {
+ return Settings.System.getInt(phone.getContext().getContentResolver(),
+ Settings.System.DATA_ROAMING) > 0;
+ } catch (SettingNotFoundException snfe) {
+ return false;
+ }
+ }
+
+ // abstract handler methods
+ protected abstract void onTrySetupData();
+ protected abstract void onRoamingOff();
+ protected abstract void onRoamingOn();
+ protected abstract void onRadioAvailable();
+ protected abstract void onRadioOffOrNotAvailable();
+ protected abstract void onDataSetupComplete(AsyncResult ar);
+ protected abstract void onDisconnectDone();
+ protected abstract void onVoiceCallStarted();
+ protected abstract void onVoiceCallEnded();
+
+ //***** Overridden from Handler
+ public void handleMessage (Message msg) {
+ switch (msg.what) {
+
+ case EVENT_TRY_SETUP_DATA:
+ onTrySetupData();
+ break;
+
+ case EVENT_ROAMING_OFF:
+ onRoamingOff();
+ break;
+
+ case EVENT_ROAMING_ON:
+ onRoamingOn();
+ break;
+
+ case EVENT_RADIO_AVAILABLE:
+ onRadioAvailable();
+ break;
+
+ case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
+ onRadioOffOrNotAvailable();
+ break;
+
+ case EVENT_DATA_SETUP_COMPLETE:
+ onDataSetupComplete((AsyncResult) msg.obj);
+ break;
+
+ case EVENT_DISCONNECT_DONE:
+ onDisconnectDone();
+ break;
+
+ case EVENT_VOICE_CALL_STARTED:
+ onVoiceCallStarted();
+ break;
+
+ case EVENT_VOICE_CALL_ENDED:
+ onVoiceCallEnded();
+ break;
+
+ default:
+ Log.e("DATA", "Unidentified event = " + msg.what);
+ break;
+ }
+ }
+
+ /**
+ * Report the current state of data connectivity (enabled or disabled)
+ * @return {@code false} if data connectivity has been explicitly disabled,
+ * {@code true} otherwise.
+ */
+ public abstract boolean getDataEnabled();
+
+ /**
+ * Prevent mobile data connections from being established,
+ * or once again allow mobile data connections. If the state
+ * toggles, then either tear down or set up data, as
+ * appropriate to match the new state.
+ * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data
+ * @return {@code true} if the operation succeeded
+ */
+ public abstract boolean setDataEnabled(boolean enable);
+
+ protected Runnable mPollNetStat = new Runnable() {
+
+ public void run() {
+ int sent, received;
+ int preTxPkts = -1, preRxPkts = -1;
+
+ Activity newActivity;
+
+ preTxPkts = txPkts;
+ preRxPkts = rxPkts;
+
+ // check if netstat is still valid to avoid NullPointerException after NTC
+ if (netstat != null) {
+ try {
+ txPkts = netstat.getTxPackets();
+ rxPkts = netstat.getRxPackets();
+ } catch (RemoteException e) {
+ txPkts = 0;
+ rxPkts = 0;
+ }
+
+ //Log.d(LOG_TAG, "rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
+
+ if (netStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
+ sent = txPkts - preTxPkts;
+ received = rxPkts - preRxPkts;
+
+ if ( sent > 0 && received > 0 ) {
+ sentSinceLastRecv = 0;
+ newActivity = Activity.DATAINANDOUT;
+ } else if (sent > 0 && received == 0) {
+ if (phone.getState() == Phone.State.IDLE) {
+ sentSinceLastRecv += sent;
+ } else {
+ sentSinceLastRecv = 0;
+ }
+ newActivity = Activity.DATAOUT;
+ } else if (sent == 0 && received > 0) {
+ sentSinceLastRecv = 0;
+ newActivity = Activity.DATAIN;
+ } else if (sent == 0 && received == 0) {
+ newActivity = Activity.NONE;
+ } else {
+ sentSinceLastRecv = 0;
+ newActivity = Activity.NONE;
+ }
+
+ if (activity != newActivity) {
+ activity = newActivity;
+ phone.notifyDataActivity();
+ }
+ }
+
+ if (sentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) {
+ // we already have NUMBER_SENT_PACKETS sent without ack
+ if (mNoRecvPollCount < NO_RECV_POLL_LIMIT) {
+ mNoRecvPollCount++;
+ // Slow down the poll interval to let things happen
+ netStatPollPeriod = POLL_NETSTAT_SLOW_MILLIS;
+ } else {
+ if (DBG) log("Sent " + String.valueOf(sentSinceLastRecv) +
+ " pkts since last received");
+ // We've exceeded the threshold. Restart the radio.
+ netStatPollEnabled = false;
+ stopNetStatPoll();
+ restartRadio();
+ }
+ } else {
+ mNoRecvPollCount = 0;
+ netStatPollPeriod = POLL_NETSTAT_MILLIS;
+ }
+
+ if (netStatPollEnabled) {
+ mDataConnectionTracker.postDelayed(this, netStatPollPeriod);
+ }
+ }
+ }
+ };
+
+ protected abstract void startNetStatPoll();
+
+ protected abstract void stopNetStatPoll();
+
+ protected abstract void restartRadio();
+
+ protected abstract void log(String s);
+}
diff --git a/telephony/java/com/android/internal/telephony/gsm/DataLink.java b/telephony/java/com/android/internal/telephony/DataLink.java
index b822ab45a5e4..8132d9170d06 100644
--- a/telephony/java/com/android/internal/telephony/gsm/DataLink.java
+++ b/telephony/java/com/android/internal/telephony/DataLink.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
import android.os.Handler;
import android.os.Registrant;
@@ -24,14 +24,13 @@ import android.os.Registrant;
*
* {@hide}
*/
-abstract class DataLink extends Handler implements DataLinkInterface {
+public abstract class DataLink extends Handler implements DataLinkInterface {
/** Registrant for link status change notifications. */
- Registrant mLinkChangeRegistrant;
-
+ protected Registrant mLinkChangeRegistrant;
protected DataConnectionTracker dataConnection;
- DataLink(DataConnectionTracker dc) {
+ protected DataLink(DataConnectionTracker dc) {
dataConnection = dc;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/DataLinkInterface.java b/telephony/java/com/android/internal/telephony/DataLinkInterface.java
index bca63f2c7f20..e8148a8945a8 100644
--- a/telephony/java/com/android/internal/telephony/gsm/DataLinkInterface.java
+++ b/telephony/java/com/android/internal/telephony/DataLinkInterface.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
import android.database.Cursor;
import android.os.Handler;
@@ -24,7 +24,7 @@ import android.os.Handler;
*
* {@hide}
*/
-interface DataLinkInterface {
+public interface DataLinkInterface {
/**
* Link state enumeration.
*
@@ -35,21 +35,21 @@ interface DataLinkInterface {
LINK_DOWN,
LINK_EXITED
}
-
+
/** Normal exit */
final static int EXIT_OK = 0;
/** Open failed */
final static int EXIT_OPEN_FAILED = 7;
-
+
/**
* Sets the handler for link state change events.
- *
+ *
* @param h Handler
* @param what User-defined message code
* @param obj User object
*/
void setOnLinkChange(Handler h, int what, Object obj);
-
+
/**
* Sets up the data link.
*/
@@ -59,14 +59,14 @@ interface DataLinkInterface {
* Tears down the data link.
*/
void disconnect();
-
+
/**
- * Returns the exit code for a data link failure.
+ * Returns the exit code for a data link failure.
*
* @return exit code
*/
int getLastLinkExitCode();
-
+
/**
* Sets password information that may be required by the data link
* (eg, PAP secrets).
diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index 81ef623d8f7d..79b4afe86984 100644
--- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -33,7 +33,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
private static final boolean DBG = true;
private ITelephonyRegistry mRegistry;
- /*package*/
+ /*package*/
DefaultPhoneNotifier() {
mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry"));
@@ -94,7 +94,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
public void notifyDataConnection(Phone sender, String reason) {
try {
- mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()),
+ mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()),
sender.isDataConnectivityPossible(), reason, sender.getActiveApn(),
sender.getInterfaceName(null));
} catch (RemoteException ex) {
@@ -119,7 +119,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
// system process is dead
}
}
-
+
private void log(String s) {
Log.d(LOG_TAG, "[PhoneNotifier] " + s);
}
diff --git a/telephony/java/com/android/internal/telephony/DriverCall.java b/telephony/java/com/android/internal/telephony/DriverCall.java
index 515693f5c5a4..00e7d800c83f 100644
--- a/telephony/java/com/android/internal/telephony/DriverCall.java
+++ b/telephony/java/com/android/internal/telephony/DriverCall.java
@@ -25,7 +25,7 @@ import android.telephony.PhoneNumberUtils;
*/
public class DriverCall implements Comparable {
static final String LOG_TAG = "RILB";
-
+
public enum State {
ACTIVE,
HOLDING,
@@ -45,7 +45,7 @@ public class DriverCall implements Comparable {
public int TOA;
public boolean isVoice;
public int als;
-
+
/** returns null on error */
static DriverCall
fromCLCCLine(String line) {
@@ -118,7 +118,7 @@ public class DriverCall implements Comparable {
}
}
- //***** Comparable Implementation
+ //***** Comparable Implementation
/** For sorting by index */
public int
diff --git a/telephony/java/com/android/internal/telephony/gsm/EncodeException.java b/telephony/java/com/android/internal/telephony/EncodeException.java
index d546cefd9491..0436ba0a070b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/EncodeException.java
+++ b/telephony/java/com/android/internal/telephony/EncodeException.java
@@ -14,25 +14,21 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
/**
* {@hide}
*/
-public class EncodeException extends Exception
-{
- public EncodeException()
- {
+public class EncodeException extends Exception {
+ public EncodeException() {
super();
}
-
- public EncodeException(String s)
- {
+
+ public EncodeException(String s) {
super(s);
}
- public EncodeException(char c)
- {
+ public EncodeException(char c) {
super("Unencodable char: '" + c + "'");
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
index 7baaecaa434e..b814088a3201 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmAlphabet.java
+++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
-import android.telephony.gsm.SmsMessage;
+import android.telephony.SmsMessage;
import android.util.SparseIntArray;
import android.util.Log;
@@ -28,16 +28,15 @@ import android.util.Log;
*
* {@hide}
*/
-public class GsmAlphabet
-{
+public class GsmAlphabet {
static final String LOG_TAG = "GSM";
-
+
//***** Constants
/**
- * This escapes extended characters, and when present indicates that the
+ * This escapes extended characters, and when present indicates that the
* following character should
* be looked up in the "extended" table
*
@@ -55,8 +54,7 @@ public class GsmAlphabet
* should follow GSM_EXTENDED_ESCAPE in the GSM alphabet string
*/
public static int
- charToGsm(char c)
- {
+ charToGsm(char c) {
try {
return charToGsm(c, false);
} catch (EncodeException ex) {
@@ -67,7 +65,7 @@ public class GsmAlphabet
/**
* char to GSM alphabet char
- * @param throwException If true, throws EncodeException on invalid char.
+ * @param throwException If true, throws EncodeException on invalid char.
* If false, returns GSM alphabet ' ' char.
*
* Returns GSM_EXTENDED_ESCAPE if this character is in the extended table
@@ -76,10 +74,9 @@ public class GsmAlphabet
*/
public static int
- charToGsm(char c, boolean throwException) throws EncodeException
- {
+ charToGsm(char c, boolean throwException) throws EncodeException {
int ret;
-
+
ret = charToGsm.get(c, -1);
if (ret == -1) {
@@ -99,7 +96,7 @@ public class GsmAlphabet
return ret;
}
-
+
/**
* char to extended GSM alphabet char
@@ -110,10 +107,9 @@ public class GsmAlphabet
*
*/
public static int
- charToGsmExtended(char c)
- {
+ charToGsmExtended(char c) {
int ret;
-
+
ret = charToGsmExtended.get(c, -1);
if (ret == -1) {
@@ -124,34 +120,32 @@ public class GsmAlphabet
}
/**
- * Converts a character in the GSM alphabet into a char
+ * Converts a character in the GSM alphabet into a char
*
* if GSM_EXTENDED_ESCAPE is passed, 0xffff is returned. In this case,
- * the following character in the stream should be decoded with
+ * the following character in the stream should be decoded with
* gsmExtendedToChar()
*
* If an unmappable value is passed (one greater than 127), ' ' is returned
*/
public static char
- gsmToChar(int gsmChar)
- {
+ gsmToChar(int gsmChar) {
return (char)gsmToChar.get(gsmChar, ' ');
}
-
+
/**
- * Converts a character in the extended GSM alphabet into a char
+ * Converts a character in the extended GSM alphabet into a char
*
* if GSM_EXTENDED_ESCAPE is passed, ' ' is returned since no second
* extension page has yet been defined (see Note 1 in table 6.2.1.1 of
* TS 23.038 v7.00)
- *
+ *
* If an unmappable value is passed , ' ' is returned
*/
public static char
- gsmExtendedToChar(int gsmChar)
- {
+ gsmExtendedToChar(int gsmChar) {
int ret;
ret = gsmExtendedToChar.get(gsmChar, -1);
@@ -205,7 +199,7 @@ public class GsmAlphabet
}
/**
- * Converts a String into a byte array containing
+ * Converts a String into a byte array containing
* the 7-bit packed GSM Alphabet representation of the string.
*
* Unencodable chars are encoded as spaces
@@ -224,7 +218,7 @@ public class GsmAlphabet
}
/**
- * Converts a String into a byte array containing
+ * Converts a String into a byte array containing
* the 7-bit packed GSM Alphabet representation of the string.
*
* Byte 0 in the returned byte array is the count of septets used
@@ -238,7 +232,7 @@ public class GsmAlphabet
* enforced maximum.
* @param startingBitOffset the number of padding bits to put before
* the start of the first septet at the begining of the array
- * @param throwException If true, throws EncodeException on invalid char.
+ * @param throwException If true, throws EncodeException on invalid char.
* If false, replaces unencodable char with GSM alphabet space char.
*
* @throws EncodeException if String is too large to encode
@@ -294,27 +288,26 @@ public class GsmAlphabet
* @param bitOffset the bit offset that the septet should be packed at
* (septet index * 7)
*/
- private static void
- packSmsChar(byte[] packedChars, int bitOffset, int value)
- {
+ private static void
+ packSmsChar(byte[] packedChars, int bitOffset, int value) {
int byteOffset = bitOffset / 8;
int shift = bitOffset % 8;
packedChars[++byteOffset] |= value << shift;
if (shift > 1) {
- packedChars[++byteOffset] = (byte)(value >> (8 - shift));
- }
+ packedChars[++byteOffset] = (byte)(value >> (8 - shift));
+ }
}
/**
- * Convert a GSM alphabet 7 bit packed string (SMS string) into a
+ * Convert a GSM alphabet 7 bit packed string (SMS string) into a
* {@link java.lang.String}.
*
* See TS 23.038 6.1.2.1 for SMS Character Packing
*
* @param pdu the raw data from the pdu
- * @param offset the byte offset of
+ * @param offset the byte offset of
* @param lengthSeptets string length in septets, not bytes
* @return String representation or null on decoding exception
*/
@@ -324,27 +317,26 @@ public class GsmAlphabet
}
/**
- * Convert a GSM alphabet 7 bit packed string (SMS string) into a
+ * Convert a GSM alphabet 7 bit packed string (SMS string) into a
* {@link java.lang.String}.
*
* See TS 23.038 6.1.2.1 for SMS Character Packing
*
* @param pdu the raw data from the pdu
- * @param offset the byte offset of
+ * @param offset the byte offset of
* @param lengthSeptets string length in septets, not bytes
* @param numPaddingBits the number of padding bits before the start of the
* string in the first byte
* @return String representation or null on decoding exception
*/
public static String gsm7BitPackedToString(byte[] pdu, int offset,
- int lengthSeptets, int numPaddingBits)
- {
+ int lengthSeptets, int numPaddingBits) {
StringBuilder ret = new StringBuilder(lengthSeptets);
boolean prevCharWasEscape;
-
+
try {
prevCharWasEscape = false;
-
+
for (int i = 0 ; i < lengthSeptets ; i++) {
int bitOffset = (7 * i) + numPaddingBits;
@@ -381,15 +373,14 @@ public class GsmAlphabet
/**
- * Convert a GSM alphabet string that's stored in 8-bit unpacked
+ * Convert a GSM alphabet string that's stored in 8-bit unpacked
* format (as it often appears in SIM records) into a String
*
* Field may be padded with trailing 0xff's. The decode stops
* at the first 0xff encountered.
*/
public static String
- gsm8BitUnpackedToString(byte[] data, int offset, int length)
- {
+ gsm8BitUnpackedToString(byte[] data, int offset, int length) {
boolean prevWasEscape;
StringBuilder ret = new StringBuilder(length);
@@ -420,8 +411,8 @@ public class GsmAlphabet
prevWasEscape = false;
}
}
-
- return ret.toString();
+
+ return ret.toString();
}
/**
@@ -429,8 +420,7 @@ public class GsmAlphabet
* array
*/
public static byte[]
- stringToGsm8BitPacked(String s)
- {
+ stringToGsm8BitPacked(String s) {
byte[] ret;
int septets = 0;
@@ -452,15 +442,14 @@ public class GsmAlphabet
*
* Field is padded with 0xff's, string is truncated if necessary
*/
-
+
public static void
- stringToGsm8BitUnpackedField(String s, byte dest[], int offset, int length)
- {
+ stringToGsm8BitUnpackedField(String s, byte dest[], int offset, int length) {
int outByteIndex = offset;
// Septets are stored in byte-aligned octets
for (int i = 0, sz = s.length()
- ; i < sz && (outByteIndex - offset) < length
+ ; i < sz && (outByteIndex - offset) < length
; i++
) {
char c = s.charAt(i);
@@ -475,7 +464,7 @@ public class GsmAlphabet
dest[outByteIndex++] = GSM_EXTENDED_ESCAPE;
- v = GsmAlphabet.charToGsmExtended(c);
+ v = GsmAlphabet.charToGsmExtended(c);
}
dest[outByteIndex++] = (byte)v;
@@ -492,8 +481,7 @@ public class GsmAlphabet
* needed to represent this character. Counts unencodable char as 1 septet.
*/
public static int
- countGsmSeptets(char c)
- {
+ countGsmSeptets(char c) {
try {
return countGsmSeptets(c, true);
} catch (EncodeException ex) {
@@ -509,21 +497,20 @@ public class GsmAlphabet
* char. Otherwise, counts invalid char as 1 septet
*/
public static int
- countGsmSeptets(char c, boolean throwsException) throws EncodeException
- {
- if (charToGsm.get(c, -1) != -1) {
- return 1;
- }
-
- if (charToGsmExtended.get(c, -1) != -1) {
- return 2;
- }
+ countGsmSeptets(char c, boolean throwsException) throws EncodeException {
+ if (charToGsm.get(c, -1) != -1) {
+ return 1;
+ }
+
+ if (charToGsmExtended.get(c, -1) != -1) {
+ return 2;
+ }
if (throwsException) {
throw new EncodeException(c);
- } else {
- // count as a space char
- return 1;
+ } else {
+ // count as a space char
+ return 1;
}
}
@@ -532,8 +519,7 @@ public class GsmAlphabet
* needed to represent this string. Counts unencodable char as 1 septet.
*/
public static int
- countGsmSeptets(String s)
- {
+ countGsmSeptets(String s) {
try {
return countGsmSeptets(s, true);
} catch (EncodeException ex) {
@@ -549,8 +535,7 @@ public class GsmAlphabet
* char. Otherwise, counts invalid char as 1 septet
*/
public static int
- countGsmSeptets(String s, boolean throwsException) throws EncodeException
- {
+ countGsmSeptets(String s, boolean throwsException) throws EncodeException {
int charIndex = 0;
int sz = s.length();
int count = 0;
@@ -559,9 +544,9 @@ public class GsmAlphabet
count += countGsmSeptets(s.charAt(charIndex), throwsException);
charIndex++;
}
-
+
return count;
- }
+ }
/**
* Returns the index into <code>s</code> of the first character
@@ -623,7 +608,7 @@ public class GsmAlphabet
* @return index of first character that won't fit, or the length
* of the entire string if everything fits
*/
- public static int
+ public static int
findLimitIndex(String s, int start, int limit, int encodingType) throws EncodeException {
if (encodingType == SmsMessage.ENCODING_7BIT) {
return findGsmSeptetLimitIndex(s, start, limit);
@@ -643,10 +628,10 @@ public class GsmAlphabet
private static final SparseIntArray gsmToChar = new SparseIntArray();
private static final SparseIntArray charToGsmExtended = new SparseIntArray();
private static final SparseIntArray gsmExtendedToChar = new SparseIntArray();
-
+
static {
int i = 0;
-
+
charToGsm.put('@', i++);
charToGsm.put('\u00a3', i++);
charToGsm.put('$', i++);
@@ -663,7 +648,7 @@ public class GsmAlphabet
charToGsm.put('\r', i++);
charToGsm.put('\u00c5', i++);
charToGsm.put('\u00e5', i++);
-
+
charToGsm.put('\u0394', i++);
charToGsm.put('_', i++);
charToGsm.put('\u03a6', i++);
@@ -680,7 +665,7 @@ public class GsmAlphabet
charToGsm.put('\u00e6', i++);
charToGsm.put('\u00df', i++);
charToGsm.put('\u00c9', i++);
-
+
charToGsm.put(' ', i++);
charToGsm.put('!', i++);
charToGsm.put('"', i++);
@@ -697,7 +682,7 @@ public class GsmAlphabet
charToGsm.put('-', i++);
charToGsm.put('.', i++);
charToGsm.put('/', i++);
-
+
charToGsm.put('0', i++);
charToGsm.put('1', i++);
charToGsm.put('2', i++);
@@ -714,7 +699,7 @@ public class GsmAlphabet
charToGsm.put('=', i++);
charToGsm.put('>', i++);
charToGsm.put('?', i++);
-
+
charToGsm.put('\u00a1', i++);
charToGsm.put('A', i++);
charToGsm.put('B', i++);
@@ -731,7 +716,7 @@ public class GsmAlphabet
charToGsm.put('M', i++);
charToGsm.put('N', i++);
charToGsm.put('O', i++);
-
+
charToGsm.put('P', i++);
charToGsm.put('Q', i++);
charToGsm.put('R', i++);
@@ -748,7 +733,7 @@ public class GsmAlphabet
charToGsm.put('\u0147', i++);
charToGsm.put('\u00dc', i++);
charToGsm.put('\u00a7', i++);
-
+
charToGsm.put('\u00bf', i++);
charToGsm.put('a', i++);
charToGsm.put('b', i++);
@@ -765,7 +750,7 @@ public class GsmAlphabet
charToGsm.put('m', i++);
charToGsm.put('n', i++);
charToGsm.put('o', i++);
-
+
charToGsm.put('p', i++);
charToGsm.put('q', i++);
charToGsm.put('r', i++);
@@ -782,8 +767,8 @@ public class GsmAlphabet
charToGsm.put('\u00f1', i++);
charToGsm.put('\u00fc', i++);
charToGsm.put('\u00e0', i++);
-
-
+
+
charToGsmExtended.put('\f', 10);
charToGsmExtended.put('^', 20);
charToGsmExtended.put('{', 40);
@@ -794,12 +779,12 @@ public class GsmAlphabet
charToGsmExtended.put(']', 62);
charToGsmExtended.put('|', 64);
charToGsmExtended.put('\u20ac', 101);
-
+
int size = charToGsm.size();
for (int j=0; j<size; j++) {
gsmToChar.put(charToGsm.valueAt(j), charToGsm.keyAt(j));
}
-
+
size = charToGsmExtended.size();
for (int j=0; j<size; j++) {
gsmExtendedToChar.put(charToGsmExtended.valueAt(j), charToGsmExtended.keyAt(j));
@@ -808,6 +793,6 @@ public class GsmAlphabet
sGsmSpaceChar = charToGsm.get(' ');
}
-
+
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 904a54e2f03e..257f1e62b9a7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -14,20 +14,20 @@
** limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
import android.app.PendingIntent;
-import com.android.internal.telephony.gsm.SmsRawData;
+import com.android.internal.telephony.SmsRawData;
-/** Interface for applications to access the SIM phone book.
+/** Interface for applications to access the ICC phone book.
*
* <p>The following code snippet demonstrates a static method to
- * retrieve the ISimSms interface from Android:</p>
- * <pre>private static ISimSms getSimSmsInterface()
+ * retrieve the ISms interface from Android:</p>
+ * <pre>private static ISms getSmsInterface()
throws DeadObjectException {
IServiceManager sm = ServiceManagerNative.getDefault();
- ISimSms ss;
- ss = ISimSms.Stub.asInterface(sm.getService("isms"));
+ ISms ss;
+ ss = ISms.Stub.asInterface(sm.getService("isms"));
return ss;
}
* </pre>
@@ -35,45 +35,45 @@ import com.android.internal.telephony.gsm.SmsRawData;
interface ISms {
/**
- * Retrieves all messages currently stored on SIM.
+ * Retrieves all messages currently stored on ICC.
*
- * @return list of SmsRawData of all sms on SIM
+ * @return list of SmsRawData of all sms on ICC
*/
- List<SmsRawData> getAllMessagesFromSimEf();
+ List<SmsRawData> getAllMessagesFromIccEf();
/**
- * Update the specified message on the SIM.
+ * Update the specified message on the ICC.
*
* @param messageIndex record index of message to update
- * @param newStatus new message status (STATUS_ON_SIM_READ,
- * STATUS_ON_SIM_UNREAD, STATUS_ON_SIM_SENT,
- * STATUS_ON_SIM_UNSENT, STATUS_ON_SIM_FREE)
+ * @param newStatus new message status (STATUS_ON_ICC_READ,
+ * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
+ * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
* @param pdu the raw PDU to store
* @return success or not
*
*/
- boolean updateMessageOnSimEf(int messageIndex, int newStatus,
+ boolean updateMessageOnIccEf(int messageIndex, int newStatus,
in byte[] pdu);
/**
- * Copy a raw SMS PDU to the SIM.
+ * Copy a raw SMS PDU to the ICC.
*
* @param pdu the raw PDU to store
- * @param status message status (STATUS_ON_SIM_READ, STATUS_ON_SIM_UNREAD,
- * STATUS_ON_SIM_SENT, STATUS_ON_SIM_UNSENT)
+ * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
+ * STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
* @return success or not
*
*/
- boolean copyMessageToSimEf(int status, in byte[] pdu, in byte[] smsc);
+ boolean copyMessageToIccEf(int status, in byte[] pdu, in byte[] smsc);
/**
* Send a SMS
*
* @param smsc the SMSC to send the message through, or NULL for the
- * defatult SMSC
+ * default SMSC
* @param pdu the raw PDU to send
* @param sentIntent if not NULL this <code>Intent</code> is
- * broadcast when the message is sucessfully sent, or failed.
+ * broadcast when the message is successfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors:
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
@@ -88,13 +88,13 @@ interface ISms {
/**
* Send a multi-part text based SMS.
- *
+ *
* @param destinationAddress the address to send the message to
* @param scAddress is the service center address or null to use
* the current default SMSC
* @param parts an <code>ArrayList</code> of strings that, in order,
* comprise the original message
- * @param sentIntents if not null, an <code>ArrayList</code> of
+ * @param sentIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been sent.
* The result code will be <code>Activity.RESULT_OK<code> for success,
@@ -102,7 +102,7 @@ interface ISms {
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
- * @param deliveryIntents if not null, an <code>ArrayList</code> of
+ * @param deliveryIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been delivered
* to the recipient. The raw pdu of the status report is in the
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 663fc0380430..83fb8bfc1d5c 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -19,7 +19,7 @@ package com.android.internal.telephony;
import android.os.Bundle;
/**
- * Interface used to interact with the phone. Mostly this is used by the
+ * Interface used to interact with the phone. Mostly this is used by the
* TelephonyManager class. A few places are still using this directly.
* Please clean them up if possible and use TelephonyManager insteadl.
*
@@ -46,7 +46,7 @@ interface ITelephony {
* Returns true if the call screen was shown.
*/
boolean showCallScreen();
-
+
/**
* End call or go to the Home screen
*
@@ -87,7 +87,7 @@ interface ITelephony {
/**
* Cancels the missed calls notification.
*/
- void cancelMissedCallsNotification();
+ void cancelMissedCallsNotification();
/**
* Supply a pin to unlock the SIM. Blocks until a result is determined.
@@ -99,7 +99,7 @@ interface ITelephony {
/**
* Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
* without SEND (so <code>dial</code> is not appropriate).
- *
+ *
* @param dialString the MMI command to be executed.
* @return true if MMI command is executed.
*/
@@ -160,4 +160,12 @@ interface ITelephony {
int getCallState();
int getDataActivity();
int getDataState();
+
+ /**
+ * Returns the current active phone type as integer.
+ * Returns TelephonyManager.PHONE_TYPE_CDMA if RILConstants.CDMA_PHONE
+ * and TelephonyManager.PHONE_TYPE_GSM if RILConstants.GSM_PHONE
+ */
+ int getActivePhoneType();
+
}
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index 614463e6eb29..d7ad492bdd4a 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -23,7 +23,6 @@ import android.os.Handler;
* {@hide}
*/
public interface IccCard {
- // TODO: check intent filters in apps
/* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
static public final String INTENT_KEY_ICC_STATE = "ss";
/* NOT_READY means the ICC interface is not ready (eg, radio is off or powering on) */
@@ -73,7 +72,7 @@ public interface IccCard {
* Notifies handler of any transition into State.ABSENT
*/
void registerForAbsent(Handler h, int what, Object obj);
- void unregisterForAbsent(Handler h);
+ void unregisterForAbsent(Handler h);
/**
* Notifies handler of any transition into State.isPinLocked()
@@ -100,11 +99,11 @@ public interface IccCard {
*
* If the supplied PIN is incorrect:
* ((AsyncResult)onComplete.obj).exception != null
- * && ((AsyncResult)onComplete.obj).exception
+ * && ((AsyncResult)onComplete.obj).exception
* instanceof com.android.internal.telephony.gsm.CommandException)
* && ((CommandException)(((AsyncResult)onComplete.obj).exception))
* .getCommandError() == CommandException.Error.PASSWORD_INCORRECT
- *
+ *
*
*/
diff --git a/telephony/java/com/android/internal/telephony/IccCardApplication.java b/telephony/java/com/android/internal/telephony/IccCardApplication.java
index de7480c51582..9f60a6cffec8 100644
--- a/telephony/java/com/android/internal/telephony/IccCardApplication.java
+++ b/telephony/java/com/android/internal/telephony/IccCardApplication.java
@@ -29,7 +29,7 @@ public class IccCardApplication {
APPTYPE_USIM,
APPTYPE_RUIM,
APPTYPE_CSIM
- };
+ };
public enum AppState{
APPSTATE_UNKNOWN,
@@ -38,15 +38,15 @@ public class IccCardApplication {
APPSTATE_PUK,
APPSTATE_SUBSCRIPTION_PERSO,
APPSTATE_READY;
-
+
boolean isPinRequired() {
return this == APPSTATE_PIN;
}
-
+
boolean isPukRequired() {
return this == APPSTATE_PUK;
}
-
+
boolean isSubscriptionPersoEnabled() {
return this == APPSTATE_SUBSCRIPTION_PERSO;
}
@@ -54,14 +54,14 @@ public class IccCardApplication {
boolean isAppReady() {
return this == APPSTATE_READY;
}
-
+
boolean isAppNotReady() {
return this == APPSTATE_UNKNOWN ||
- this == APPSTATE_DETECTED;
+ this == APPSTATE_DETECTED;
}
};
- public enum PersoSubState{
+ public enum PersoSubState{
PERSOSUBSTATE_UNKNOWN,
PERSOSUBSTATE_IN_PROGRESS,
PERSOSUBSTATE_READY,
@@ -87,25 +87,25 @@ public class IccCardApplication {
PERSOSUBSTATE_RUIM_CORPORATE_PUK,
PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK,
PERSOSUBSTATE_RUIM_RUIM_PUK;
-
+
boolean isPersoSubStateUnknown() {
return this == PERSOSUBSTATE_UNKNOWN;
- }
+ }
};
-
- public AppType app_type;
- public AppState app_state;
+
+ public AppType app_type;
+ public AppState app_state;
// applicable only if app_state == RIL_APPSTATE_SUBSCRIPTION_PERSO
public PersoSubState perso_substate;
- // null terminated string, e.g., from 0xA0, 0x00 -> 0x41, 0x30, 0x30, 0x30 */
+ // null terminated string, e.g., from 0xA0, 0x00 -> 0x41, 0x30, 0x30, 0x30 */
public String aid;
// null terminated string
public String app_label;
// applicable to USIM and CSIM
public int pin1_replaced;
- public int pin1;
- public int pin2;
-
+ public int pin1;
+ public int pin2;
+
AppType AppTypeFromRILInt(int type) {
AppType newType;
/* RIL_AppType ril.h */
@@ -115,13 +115,13 @@ public class IccCardApplication {
case 2: newType = AppType.APPTYPE_USIM; break;
case 3: newType = AppType.APPTYPE_RUIM; break;
case 4: newType = AppType.APPTYPE_CSIM; break;
- default:
+ default:
throw new RuntimeException(
"Unrecognized RIL_AppType: " +type);
- }
+ }
return newType;
}
-
+
AppState AppStateFromRILInt(int state) {
AppState newState;
/* RIL_AppState ril.h */
@@ -132,10 +132,10 @@ public class IccCardApplication {
case 3: newState = AppState.APPSTATE_PUK; break;
case 4: newState = AppState.APPSTATE_SUBSCRIPTION_PERSO; break;
case 5: newState = AppState.APPSTATE_READY; break;
- default:
+ default:
throw new RuntimeException(
"Unrecognized RIL_AppState: " +state);
- }
+ }
return newState;
}
@@ -160,7 +160,7 @@ public class IccCardApplication {
case 14: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK2; break;
case 15: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_HRPD; break;
case 16: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_CORPORATE; break;
- case 17: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_SERVICE_PROVIDER; break;
+ case 17: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_SERVICE_PROVIDER; break;
case 18: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_RUIM; break;
case 19: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK1_PUK; break;
case 20: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK2_PUK; break;
@@ -168,11 +168,11 @@ public class IccCardApplication {
case 22: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_CORPORATE_PUK; break;
case 23: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK; break;
case 24: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_RUIM_PUK; break;
- default:
+ default:
throw new RuntimeException(
"Unrecognized RIL_PersoSubstate: " +substate);
- }
+ }
return newSubState;
}
-
+
}
diff --git a/telephony/java/com/android/internal/telephony/IccCardStatus.java b/telephony/java/com/android/internal/telephony/IccCardStatus.java
index 1ecf59fdb7b9..b602b1c68cc2 100644
--- a/telephony/java/com/android/internal/telephony/IccCardStatus.java
+++ b/telephony/java/com/android/internal/telephony/IccCardStatus.java
@@ -30,7 +30,7 @@ public class IccCardStatus {
CARDSTATE_ABSENT,
CARDSTATE_PRESENT,
CARDSTATE_ERROR;
-
+
boolean isCardPresent() {
return this == CARDSTATE_PRESENT;
}
@@ -44,13 +44,13 @@ public class IccCardStatus {
PINSTATE_ENABLED_BLOCKED,
PINSTATE_ENABLED_PERM_BLOCKED
};
-
- public CardState card_state;
- public PinState universal_pin_state;
- public int gsm_umts_subscription_app_index;
- public int cdma_subscription_app_index;
+
+ public CardState card_state;
+ public PinState universal_pin_state;
+ public int gsm_umts_subscription_app_index;
+ public int cdma_subscription_app_index;
public int num_applications;
-
+
ArrayList<IccCardApplication> application = new ArrayList<IccCardApplication>(CARD_MAX_APPS);
CardState CardStateFromRILInt(int state) {
@@ -60,10 +60,10 @@ public class IccCardStatus {
case 0: newState = CardState.CARDSTATE_ABSENT; break;
case 1: newState = CardState.CARDSTATE_PRESENT; break;
case 2: newState = CardState.CARDSTATE_ERROR; break;
- default:
+ default:
throw new RuntimeException(
"Unrecognized RIL_CardState: " +state);
- }
+ }
return newState;
}
@@ -77,10 +77,10 @@ public class IccCardStatus {
case 3: newState = PinState.PINSTATE_DISABLED; break;
case 4: newState = PinState.PINSTATE_ENABLED_BLOCKED; break;
case 5: newState = PinState.PINSTATE_ENABLED_PERM_BLOCKED; break;
- default:
+ default:
throw new RuntimeException(
"Unrecognized RIL_PinState: " +state);
- }
+ }
return newState;
}
}
diff --git a/telephony/java/com/android/internal/telephony/IccConstants.java b/telephony/java/com/android/internal/telephony/IccConstants.java
index adf4e1e9c2b5..59ce5bbafeba 100644
--- a/telephony/java/com/android/internal/telephony/IccConstants.java
+++ b/telephony/java/com/android/internal/telephony/IccConstants.java
@@ -51,9 +51,9 @@ public interface IccConstants {
public static final int EF_INFO_CPHS = 0x6f16;
// CDMA RUIM file ids from 3GPP2 C.S0023-0
- // TODO: add necessary RUIM file ids here
- public static final int EF_CST = 0x6f32;
-
+ public static final int EF_CST = 0x6f32;
+ public static final int EF_RUIM_SPN =0x6F41;
+
// SMS record length from TS 51.011 10.5.3
static public final int SMS_RECORD_LENGTH = 176;
}
diff --git a/telephony/java/com/android/internal/telephony/IccFileHandler.java b/telephony/java/com/android/internal/telephony/IccFileHandler.java
index e23b9265542a..e751c5eb1bc8 100644
--- a/telephony/java/com/android/internal/telephony/IccFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/IccFileHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package com.android.internal.telephony;
-//import com.android.internal.telephony.*;
import android.os.*;
import android.util.Log;
import java.util.ArrayList;
@@ -25,7 +24,7 @@ import java.util.ArrayList;
* {@hide}
*/
public abstract class IccFileHandler extends Handler {
-
+
//from TS 11.11 9.1 or elsewhere
static protected final int COMMAND_READ_BINARY = 0xb0;
static protected final int COMMAND_UPDATE_BINARY = 0xd6;
@@ -72,7 +71,7 @@ public abstract class IccFileHandler extends Handler {
static protected final int RESPONSE_DATA_STRUCTURE = 13;
static protected final int RESPONSE_DATA_RECORD_LENGTH = 14;
-
+
//***** Events
/** Finished retrieving size of transparent EF; start loading. */
@@ -90,24 +89,425 @@ public abstract class IccFileHandler extends Handler {
/** Finished retrieving icon data; post result. */
static protected final int EVENT_READ_ICON_DONE = 10;
-
+ // member variables
+ protected PhoneBase phone;
+
+ static class LoadLinearFixedContext {
+
+ int efid;
+ int recordNum, recordSize, countRecords;
+ boolean loadAll;
+
+ Message onLoaded;
+
+ ArrayList<byte[]> results;
+
+ LoadLinearFixedContext(int efid, int recordNum, Message onLoaded) {
+ this.efid = efid;
+ this.recordNum = recordNum;
+ this.onLoaded = onLoaded;
+ this.loadAll = false;
+ }
+
+ LoadLinearFixedContext(int efid, Message onLoaded) {
+ this.efid = efid;
+ this.recordNum = 1;
+ this.loadAll = true;
+ this.onLoaded = onLoaded;
+ }
+ }
+
+ /**
+ * Default constructor
+ */
+ protected IccFileHandler(PhoneBase phone) {
+ super();
+ this.phone = phone;
+ }
+
+ public void dispose() {
+ }
+
+ //***** Public Methods
+
+ /**
+ * Load a record from a SIM Linear Fixed EF
+ *
+ * @param fileid EF id
+ * @param recordNum 1-based (not 0-based) record number
+ * @param onLoaded
+ *
+ * ((AsyncResult)(onLoaded.obj)).result is the byte[]
+ *
+ */
+ public void loadEFLinearFixed(int fileid, int recordNum, Message onLoaded) {
+ Message response
+ = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
+ new LoadLinearFixedContext(fileid, recordNum, onLoaded));
+
+ phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
+ 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
+ }
+
+ /**
+ * Load a image instance record from a SIM Linear Fixed EF-IMG
+ *
+ * @param recordNum 1-based (not 0-based) record number
+ * @param onLoaded
+ *
+ * ((AsyncResult)(onLoaded.obj)).result is the byte[]
+ *
+ */
+ public void loadEFImgLinearFixed(int recordNum, Message onLoaded) {
+ Message response = obtainMessage(EVENT_READ_IMG_DONE,
+ new LoadLinearFixedContext(IccConstants.EF_IMG, recordNum,
+ onLoaded));
+
+ phone.mCM.iccIO(COMMAND_GET_RESPONSE, IccConstants.EF_IMG, "img",
+ recordNum, READ_RECORD_MODE_ABSOLUTE,
+ GET_RESPONSE_EF_IMG_SIZE_BYTES, null, null, response);
+ }
+
+ /**
+ * get record size for a linear fixed EF
+ *
+ * @param fileid EF id
+ * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]
+ * int[0] is the record length int[1] is the total length of the EF
+ * file int[3] is the number of records in the EF file So int[0] *
+ * int[3] = int[1]
+ */
+ public void getEFLinearRecordSize(int fileid, Message onLoaded) {
+ Message response
+ = obtainMessage(EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE,
+ new LoadLinearFixedContext(fileid, onLoaded));
+ phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
+ 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
+ }
+
+ /**
+ * Load all records from a SIM Linear Fixed EF
+ *
+ * @param fileid EF id
+ * @param onLoaded
+ *
+ * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
+ *
+ */
+ public void loadEFLinearFixedAll(int fileid, Message onLoaded) {
+ Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
+ new LoadLinearFixedContext(fileid,onLoaded));
+
+ phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
+ 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
+ }
+
+ /**
+ * Load a SIM Transparent EF
+ *
+ * @param fileid EF id
+ * @param onLoaded
+ *
+ * ((AsyncResult)(onLoaded.obj)).result is the byte[]
+ *
+ */
+
+ public void loadEFTransparent(int fileid, Message onLoaded) {
+ Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
+ fileid, 0, onLoaded);
+
+ phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
+ 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
+ }
+
+ /**
+ * Load a SIM Transparent EF-IMG. Used right after loadEFImgLinearFixed to
+ * retrive STK's icon data.
+ *
+ * @param fileid EF id
+ * @param onLoaded
+ *
+ * ((AsyncResult)(onLoaded.obj)).result is the byte[]
+ *
+ */
+ public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset,
+ int length, Message onLoaded) {
+ Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0,
+ onLoaded);
+
+ phone.mCM.iccIO(COMMAND_READ_BINARY, fileid, "img", highOffset, lowOffset,
+ length, null, null, response);
+ }
+
+ /**
+ * Update a record in a linear fixed EF
+ * @param fileid EF id
+ * @param recordNum 1-based (not 0-based) record number
+ * @param data must be exactly as long as the record in the EF
+ * @param pin2 for CHV2 operations, otherwist must be null
+ * @param onComplete onComplete.obj will be an AsyncResult
+ * onComplete.obj.userObj will be a IccIoResult on success
+ */
+ public void updateEFLinearFixed(int fileid, int recordNum, byte[] data,
+ String pin2, Message onComplete) {
+ phone.mCM.iccIO(COMMAND_UPDATE_RECORD, fileid, null,
+ recordNum, READ_RECORD_MODE_ABSOLUTE, data.length,
+ IccUtils.bytesToHexString(data), pin2, onComplete);
+ }
+
+ /**
+ * Update a transparent EF
+ * @param fileid EF id
+ * @param data must be exactly as long as the EF
+ */
+ public void updateEFTransparent(int fileid, byte[] data, Message onComplete) {
+ phone.mCM.iccIO(COMMAND_UPDATE_BINARY, fileid, null,
+ 0, 0, data.length,
+ IccUtils.bytesToHexString(data), null, onComplete);
+ }
+
+
//***** Abstract Methods
-
- protected abstract void loadEFLinearFixed(int fileid, int recordNum, Message onLoaded);
-
- protected abstract void loadEFImgLinearFixed(int recordNum, Message onLoaded);
-
- protected abstract void getEFLinearRecordSize(int fileid, Message onLoaded);
-
- protected abstract void loadEFLinearFixedAll(int fileid, Message onLoaded);
-
- protected abstract void loadEFTransparent(int fileid, Message onLoaded);
-
- protected abstract void loadEFImgTransparent(int fileid, int highOffset, int lowOffset,
- int length, Message onLoaded);
-
- protected abstract void updateEFLinearFixed(int fileid, int recordNum, byte[] data,
- String pin2, Message onComplete);
-
- protected abstract void updateEFTransparent(int fileid, byte[] data, Message onComplete);
+
+
+ //***** Private Methods
+
+ private void sendResult(Message response, Object result, Throwable ex) {
+ if (response == null) {
+ return;
+ }
+
+ AsyncResult.forMessage(response, result, ex);
+
+ response.sendToTarget();
+ }
+
+ //***** Overridden from Handler
+
+ public void handleMessage(Message msg) {
+ AsyncResult ar;
+ IccIoResult result;
+ Message response = null;
+ String str;
+ LoadLinearFixedContext lc;
+
+ IccException iccException;
+ byte data[];
+ int size;
+ int fileid;
+ int recordNum;
+ int recordSize[];
+
+ try {
+ switch (msg.what) {
+ case EVENT_READ_IMG_DONE:
+ ar = (AsyncResult) msg.obj;
+ lc = (LoadLinearFixedContext) ar.userObj;
+ result = (IccIoResult) ar.result;
+ response = lc.onLoaded;
+
+ iccException = result.getException();
+ if (iccException != null) {
+ sendResult(response, result.payload, ar.exception);
+ }
+ break;
+ case EVENT_READ_ICON_DONE:
+ ar = (AsyncResult) msg.obj;
+ response = (Message) ar.userObj;
+ result = (IccIoResult) ar.result;
+
+ iccException = result.getException();
+ if (iccException != null) {
+ sendResult(response, result.payload, ar.exception);
+ }
+ break;
+ case EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE:
+ ar = (AsyncResult)msg.obj;
+ lc = (LoadLinearFixedContext) ar.userObj;
+ result = (IccIoResult) ar.result;
+ response = lc.onLoaded;
+
+ if (ar.exception != null) {
+ sendResult(response, null, ar.exception);
+ break;
+ }
+
+ iccException = result.getException();
+ if (iccException != null) {
+ sendResult(response, null, iccException);
+ break;
+ }
+
+ data = result.payload;
+
+ if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE] ||
+ EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
+ throw new IccFileTypeMismatch();
+ }
+
+ recordSize = new int[3];
+ recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
+ recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
+ + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
+ recordSize[2] = recordSize[1] / recordSize[0];
+
+ sendResult(response, recordSize, null);
+ break;
+ case EVENT_GET_RECORD_SIZE_DONE:
+ ar = (AsyncResult)msg.obj;
+ lc = (LoadLinearFixedContext) ar.userObj;
+ result = (IccIoResult) ar.result;
+ response = lc.onLoaded;
+
+ if (ar.exception != null) {
+ sendResult(response, null, ar.exception);
+ break;
+ }
+
+ iccException = result.getException();
+
+ if (iccException != null) {
+ sendResult(response, null, iccException);
+ break;
+ }
+
+ data = result.payload;
+ fileid = lc.efid;
+ recordNum = lc.recordNum;
+
+ if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
+ throw new IccFileTypeMismatch();
+ }
+
+ if (EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
+ throw new IccFileTypeMismatch();
+ }
+
+ lc.recordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
+
+ size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
+ + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
+
+ lc.countRecords = size / lc.recordSize;
+
+ if (lc.loadAll) {
+ lc.results = new ArrayList<byte[]>(lc.countRecords);
+ }
+
+ phone.mCM.iccIO(COMMAND_READ_RECORD, lc.efid, null,
+ lc.recordNum,
+ READ_RECORD_MODE_ABSOLUTE,
+ lc.recordSize, null, null,
+ obtainMessage(EVENT_READ_RECORD_DONE, lc));
+ break;
+ case EVENT_GET_BINARY_SIZE_DONE:
+ ar = (AsyncResult)msg.obj;
+ response = (Message) ar.userObj;
+ result = (IccIoResult) ar.result;
+
+ if (ar.exception != null) {
+ sendResult(response, null, ar.exception);
+ break;
+ }
+
+ iccException = result.getException();
+
+ if (iccException != null) {
+ sendResult(response, null, iccException);
+ break;
+ }
+
+ data = result.payload;
+
+ fileid = msg.arg1;
+
+ if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
+ throw new IccFileTypeMismatch();
+ }
+
+ if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) {
+ throw new IccFileTypeMismatch();
+ }
+
+ size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
+ + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
+
+ phone.mCM.iccIO(COMMAND_READ_BINARY, fileid, null,
+ 0, 0, size, null, null,
+ obtainMessage(EVENT_READ_BINARY_DONE,
+ fileid, 0, response));
+ break;
+
+ case EVENT_READ_RECORD_DONE:
+
+ ar = (AsyncResult)msg.obj;
+ lc = (LoadLinearFixedContext) ar.userObj;
+ result = (IccIoResult) ar.result;
+ response = lc.onLoaded;
+
+ if (ar.exception != null) {
+ sendResult(response, null, ar.exception);
+ break;
+ }
+
+ iccException = result.getException();
+
+ if (iccException != null) {
+ sendResult(response, null, iccException);
+ break;
+ }
+
+ if (!lc.loadAll) {
+ sendResult(response, result.payload, null);
+ } else {
+ lc.results.add(result.payload);
+
+ lc.recordNum++;
+
+ if (lc.recordNum > lc.countRecords) {
+ sendResult(response, lc.results, null);
+ } else {
+ phone.mCM.iccIO(COMMAND_READ_RECORD, lc.efid, null,
+ lc.recordNum,
+ READ_RECORD_MODE_ABSOLUTE,
+ lc.recordSize, null, null,
+ obtainMessage(EVENT_READ_RECORD_DONE, lc));
+ }
+ }
+
+ break;
+
+ case EVENT_READ_BINARY_DONE:
+ ar = (AsyncResult)msg.obj;
+ response = (Message) ar.userObj;
+ result = (IccIoResult) ar.result;
+
+ if (ar.exception != null) {
+ sendResult(response, null, ar.exception);
+ break;
+ }
+
+ iccException = result.getException();
+
+ if (iccException != null) {
+ sendResult(response, null, iccException);
+ break;
+ }
+
+ sendResult(response, result.payload, null);
+ break;
+
+ }} catch (Exception exc) {
+ if (response != null) {
+ sendResult(response, null, exc);
+ } else {
+ loge("uncaught exception" + exc);
+ }
+ }
+ }
+
+ protected abstract void logd(String s);
+
+ protected abstract void loge(String s);
+
}
diff --git a/telephony/java/com/android/internal/telephony/IccIoResult.java b/telephony/java/com/android/internal/telephony/IccIoResult.java
index c57cc78fea13..a6e0ec365bb3 100644
--- a/telephony/java/com/android/internal/telephony/IccIoResult.java
+++ b/telephony/java/com/android/internal/telephony/IccIoResult.java
@@ -33,13 +33,11 @@ IccIoResult {
}
public IccIoResult(int sw1, int sw2, String hexString) {
- //TODO T: IccUtils is linked to IccUtils which is stored in telephony package
- //Maybe in a later version all function calls of IccUtils will be renamed to IccUtils.
this(sw1, sw2, IccUtils.hexStringToBytes(hexString));
}
public String toString() {
- return "IccIoResponse sw1:0x" + Integer.toHexString(sw1) + " sw2:0x"
+ return "IccIoResponse sw1:0x" + Integer.toHexString(sw1) + " sw2:0x"
+ Integer.toHexString(sw2);
}
@@ -57,7 +55,7 @@ IccIoResult {
*/
public IccException getException() {
if (success()) return null;
-
+
switch (sw1) {
case 0x94:
if (sw2 == 0x08) {
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 4554aed1e741..0bcaaa684d9b 100644
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -33,4 +33,234 @@ import java.util.List;
* access ADN-like SIM records.
*/
public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
+ protected static final boolean DBG = true;
+
+ protected PhoneBase phone;
+ protected AdnRecordCache adnCache;
+ protected Object mLock = new Object();
+ protected int recordSize[];
+ protected boolean success;
+ protected List<AdnRecord> records;
+
+ protected static final boolean ALLOW_SIM_OP_IN_UI_THREAD = false;
+
+ protected static final int EVENT_GET_SIZE_DONE = 1;
+ protected static final int EVENT_LOAD_DONE = 2;
+ protected static final int EVENT_UPDATE_DONE = 3;
+
+ protected Handler mBaseHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncResult ar;
+
+ switch (msg.what) {
+ case EVENT_GET_SIZE_DONE:
+ ar = (AsyncResult) msg.obj;
+ synchronized (mLock) {
+ if (ar.exception == null) {
+ recordSize = (int[])ar.result;
+ // recordSize[0] is the record length
+ // recordSize[1] is the total length of the EF file
+ // recordSize[2] is the number of records in the EF file
+ logd("GET_RECORD_SIZE Size " + recordSize[0] +
+ " total " + recordSize[1] +
+ " #record " + recordSize[2]);
+ mLock.notifyAll();
+ }
+ }
+ break;
+ case EVENT_UPDATE_DONE:
+ ar = (AsyncResult) msg.obj;
+ synchronized (mLock) {
+ success = (ar.exception == null);
+ mLock.notifyAll();
+ }
+ break;
+ case EVENT_LOAD_DONE:
+ ar = (AsyncResult)msg.obj;
+ synchronized (mLock) {
+ if (ar.exception == null) {
+ records = (List<AdnRecord>)
+ ((ArrayList<AdnRecord>) ar.result);
+ } else {
+ if(DBG) logd("Cannot load ADN records");
+ if (records != null) {
+ records.clear();
+ }
+ }
+ mLock.notifyAll();
+ }
+ break;
+ }
+ }
+ };
+
+ public IccPhoneBookInterfaceManager(PhoneBase phone) {
+ this.phone = phone;
+ }
+
+ public void dispose() {
+ }
+
+ protected void publish() {
+ //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
+ ServiceManager.addService("simphonebook", this);
+ }
+
+ protected abstract void logd(String msg);
+
+ protected abstract void loge(String msg);
+
+ /**
+ * Replace oldAdn with newAdn in ADN-like record in EF
+ *
+ * getAdnRecordsInEf must be called at least once before this function,
+ * otherwise an error will be returned
+ * throws SecurityException if no WRITE_CONTACTS permission
+ *
+ * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
+ * @param oldTag adn tag to be replaced
+ * @param oldPhoneNumber adn number to be replaced
+ * Set both oldTag and oldPhoneNubmer to "" means to replace an
+ * empty record, aka, insert new record
+ * @param newTag adn tag to be stored
+ * @param newPhoneNumber adn number ot be stored
+ * Set both newTag and newPhoneNubmer to "" means to replace the old
+ * record with empty one, aka, delete old record
+ * @param pin2 required to update EF_FDN, otherwise must be null
+ * @return true for success
+ */
+ public boolean
+ updateAdnRecordsInEfBySearch (int efid,
+ String oldTag, String oldPhoneNumber,
+ String newTag, String newPhoneNumber, String pin2) {
+
+
+ if (phone.getContext().checkCallingOrSelfPermission(
+ android.Manifest.permission.WRITE_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Requires android.permission.WRITE_CONTACTS permission");
+ }
+
+
+ if (DBG) logd("updateAdnRecordsInEfBySearch: efid=" + efid +
+ " ("+ oldTag + "," + oldPhoneNumber + ")"+ "==>" +
+ " ("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
+ synchronized(mLock) {
+ checkThread();
+ success = false;
+ Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE);
+ AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
+ AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
+ adnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
+ try {
+ mLock.wait();
+ } catch (InterruptedException e) {
+ logd("interrupted while trying to update by search");
+ }
+ }
+ return success;
+ }
+
+ /**
+ * Update an ADN-like EF record by record index
+ *
+ * This is useful for iteration the whole ADN file, such as write the whole
+ * phone book or erase/format the whole phonebook
+ * throws SecurityException if no WRITE_CONTACTS permission
+ *
+ * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
+ * @param newTag adn tag to be stored
+ * @param newPhoneNumber adn number to be stored
+ * Set both newTag and newPhoneNubmer to "" means to replace the old
+ * record with empty one, aka, delete old record
+ * @param index is 1-based adn record index to be updated
+ * @param pin2 required to update EF_FDN, otherwise must be null
+ * @return true for success
+ */
+ public boolean
+ updateAdnRecordsInEfByIndex(int efid, String newTag,
+ String newPhoneNumber, int index, String pin2) {
+
+ if (phone.getContext().checkCallingOrSelfPermission(
+ android.Manifest.permission.WRITE_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Requires android.permission.WRITE_CONTACTS permission");
+ }
+
+ if (DBG) logd("updateAdnRecordsInEfByIndex: efid=" + efid +
+ " Index=" + index + " ==> " +
+ "("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
+ synchronized(mLock) {
+ checkThread();
+ success = false;
+ Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE);
+ AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
+ adnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
+ try {
+ mLock.wait();
+ } catch (InterruptedException e) {
+ logd("interrupted while trying to update by index");
+ }
+ }
+ return success;
+ }
+
+ /**
+ * Get the capacity of records in efid
+ *
+ * @param efid the EF id of a ADN-like ICC
+ * @return int[3] array
+ * recordSizes[0] is the single record length
+ * recordSizes[1] is the total length of the EF file
+ * recordSizes[2] is the number of records in the EF file
+ */
+ public abstract int[] getAdnRecordsSize(int efid);
+
+ /**
+ * Loads the AdnRecords in efid and returns them as a
+ * List of AdnRecords
+ *
+ * throws SecurityException if no READ_CONTACTS permission
+ *
+ * @param efid the EF id of a ADN-like ICC
+ * @return List of AdnRecord
+ */
+ public List<AdnRecord> getAdnRecordsInEf(int efid) {
+
+ if (phone.getContext().checkCallingOrSelfPermission(
+ android.Manifest.permission.READ_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Requires android.permission.READ_CONTACTS permission");
+ }
+
+ if (DBG) logd("getAdnRecordsInEF: efid=" + efid);
+
+ synchronized(mLock) {
+ checkThread();
+ Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE);
+ adnCache.requestLoadAllAdnLike(efid, response);
+ try {
+ mLock.wait();
+ } catch (InterruptedException e) {
+ logd("interrupted while trying to load from the SIM");
+ }
+ }
+ return records;
+ }
+
+ protected void checkThread() {
+ if (!ALLOW_SIM_OP_IN_UI_THREAD) {
+ // Make sure this isn't the UI thread, since it will block
+ if (mBaseHandler.getLooper().equals(Looper.myLooper())) {
+ loge("query() called on the main UI thread!");
+ throw new IllegalStateException(
+ "You cannot call query on this provder from the main UI thread.");
+ }
+ }
+ }
}
+
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java
index 959e6a33e0fc..1c0fc52e78eb 100644
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java
+++ b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,8 +28,6 @@ import android.util.Log;
import java.util.ArrayList;
import java.util.List;
-//TODO T: remove if AdnRecord is moved to telephony package
-//import com.android.internal.telephony.gsm.*;
/**
* SimPhoneBookInterfaceManager to provide an inter-process communication to
@@ -38,14 +36,20 @@ import java.util.List;
public class IccPhoneBookInterfaceManagerProxy extends IIccPhoneBook.Stub {
private IccPhoneBookInterfaceManager mIccPhoneBookInterfaceManager;
- public IccPhoneBookInterfaceManagerProxy(IccPhoneBookInterfaceManager
+ public IccPhoneBookInterfaceManagerProxy(IccPhoneBookInterfaceManager
iccPhoneBookInterfaceManager) {
mIccPhoneBookInterfaceManager = iccPhoneBookInterfaceManager;
- ServiceManager.addService("simphonebook", this);;
+ if(ServiceManager.getService("simphonebook") == null) {
+ ServiceManager.addService("simphonebook", this);
+ }
+ }
+
+ public void setmIccPhoneBookInterfaceManager(
+ IccPhoneBookInterfaceManager iccPhoneBookInterfaceManager) {
+ this.mIccPhoneBookInterfaceManager = iccPhoneBookInterfaceManager;
}
public boolean
- //TODO Investigate
updateAdnRecordsInEfBySearch (int efid,
String oldTag, String oldPhoneNumber,
String newTag, String newPhoneNumber,
@@ -55,19 +59,16 @@ public class IccPhoneBookInterfaceManagerProxy extends IIccPhoneBook.Stub {
}
public boolean
- //TODO Investigate
updateAdnRecordsInEfByIndex(int efid, String newTag,
String newPhoneNumber, int index, String pin2) throws android.os.RemoteException {
- return mIccPhoneBookInterfaceManager.updateAdnRecordsInEfByIndex(efid,
+ return mIccPhoneBookInterfaceManager.updateAdnRecordsInEfByIndex(efid,
newTag, newPhoneNumber, index, pin2);
}
- //TODO Investigate
public int[] getAdnRecordsSize(int efid) throws android.os.RemoteException {
return mIccPhoneBookInterfaceManager.getAdnRecordsSize(efid);
}
- //TODO Investigate
public List<AdnRecord> getAdnRecordsInEf(int efid) throws android.os.RemoteException {
return mIccPhoneBookInterfaceManager.getAdnRecordsInEf(efid);
}
diff --git a/telephony/java/com/android/internal/telephony/IccProvider.java b/telephony/java/com/android/internal/telephony/IccProvider.java
index fa1ed8b04d59..4cbd779722d4 100644
--- a/telephony/java/com/android/internal/telephony/IccProvider.java
+++ b/telephony/java/com/android/internal/telephony/IccProvider.java
@@ -42,7 +42,7 @@ import com.android.internal.telephony.IIccPhoneBook;
public class IccProvider extends ContentProvider {
private static final String TAG = "IccProvider";
private static final boolean DBG = false;
-
+
private static final String[] ADDRESS_BOOK_COLUMN_NAMES = new String[] {
"name",
@@ -60,7 +60,6 @@ public class IccProvider extends ContentProvider {
private static final UriMatcher URL_MATCHER =
new UriMatcher(UriMatcher.NO_MATCH);
- // TODO T: consider change from "sim" to "icc", also at other locations
static {
URL_MATCHER.addURI("icc", "adn", ADN);
URL_MATCHER.addURI("icc", "fdn", FDN);
@@ -87,21 +86,21 @@ public class IccProvider extends ContentProvider {
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sort) {
ArrayList<ArrayList> results;
-
+
if (!mSimulator) {
switch (URL_MATCHER.match(url)) {
case ADN:
results = loadFromEf(IccConstants.EF_ADN);
break;
-
+
case FDN:
results = loadFromEf(IccConstants.EF_FDN);
break;
-
+
case SDN:
results = loadFromEf(IccConstants.EF_SDN);
break;
-
+
default:
throw new IllegalArgumentException("Unknown URL " + url);
}
@@ -140,8 +139,6 @@ public class IccProvider extends ContentProvider {
case ADN:
case FDN:
case SDN:
- // TODO T: Do we have to change this "link"
- // as well to "icc-contact"?
return "vnd.android.cursor.dir/sim-contact";
default:
@@ -191,7 +188,7 @@ public class IccProvider extends ContentProvider {
buf.append("fdn/");
break;
}
-
+
// TODO: we need to find out the rowId for the newly added record
buf.append(0);
@@ -331,9 +328,6 @@ public class IccProvider extends ContentProvider {
try {
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
- // TODO T: Do we have to change the service
- // as well to "iccphonebook"?
- // defined in: device/commands/binder/Service_info.c
ServiceManager.getService("simphonebook"));
if (iccIpb != null) {
adnRecords = iccIpb.getAdnRecordsInEf(efType);
@@ -374,9 +368,6 @@ public class IccProvider extends ContentProvider {
try {
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
- // TODO T: Do we have to change the service
- // as well to "iccphonebook"?
- // defined in: device/commands/binder/Service_info.c
ServiceManager.getService("simphonebook"));
if (iccIpb != null) {
success = iccIpb.updateAdnRecordsInEfBySearch(efType, "", "",
@@ -401,9 +392,6 @@ public class IccProvider extends ContentProvider {
try {
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
- // TODO T: Do we have to change the service
- // as well to "iccphonebook"?
- // defined in: device/commands/binder/Service_info.c
ServiceManager.getService("simphonebook"));
if (iccIpb != null) {
success = iccIpb.updateAdnRecordsInEfBySearch(efType,
@@ -419,9 +407,7 @@ public class IccProvider extends ContentProvider {
}
- private boolean deleteIccRecordFromEf(int efType,
- String name, String number,
- String pin2) {
+ private boolean deleteIccRecordFromEf(int efType, String name, String number, String pin2) {
if (DBG) log("deleteIccRecordFromEf: efType=" + efType +
", name=" + name + ", number=" + number + ", pin2=" + pin2);
@@ -429,13 +415,10 @@ public class IccProvider extends ContentProvider {
try {
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
- // TODO T: Do we have to change the service
- // as well to "iccphonebook"?
- // defined in: device/commands/binder/Service_info.c
ServiceManager.getService("simphonebook"));
if (iccIpb != null) {
success = iccIpb.updateAdnRecordsInEfBySearch(efType,
- name, number, "", "", pin2);
+ name, number, "", "", pin2);
}
} catch (RemoteException ex) {
// ignore it
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
index 6849fad9d908..114094b74181 100644
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ b/telephony/java/com/android/internal/telephony/IccRecords.java
@@ -16,10 +16,6 @@
package com.android.internal.telephony;
-
-
-import java.util.ArrayList;
-
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
@@ -27,125 +23,66 @@ import android.os.Registrant;
import android.os.RegistrantList;
import android.util.Log;
-import static com.android.internal.telephony.TelephonyProperties.*;
-
-// TODO: move abstract parts to here
+import java.util.ArrayList;
/**
* {@hide}
*/
public abstract class IccRecords extends Handler implements IccConstants {
- static String LOG_TAG = "IccRecords";
-
- protected static final boolean DBG = true;
+
+ protected static final boolean DBG = true;
//***** Instance Variables
- PhoneBase phone;
- RegistrantList recordsLoadedRegistrants = new RegistrantList();
+ protected PhoneBase phone;
+ protected RegistrantList recordsLoadedRegistrants = new RegistrantList();
- int recordsToLoad; // number of pending load requests
+ protected int recordsToLoad; // number of pending load requests
- AdnRecordCache adnCache;
+ protected AdnRecordCache adnCache;
//***** Cached SIM State; cleared on channel close
- boolean recordsRequested = false; // true if we've made requests for the sim records
-
- String imsi;
- String iccid;
- String msisdn = null; // My mobile number
- String msisdnTag = null;
- String voiceMailNum = null;
- String voiceMailTag = null;
- String newVoiceMailNum = null;
- String newVoiceMailTag = null;
- boolean isVoiceMailFixed = false;
- int countVoiceMessages = 0;
- boolean callForwardingEnabled;
- int mncLength = 0; // 0 is used to indicate that the value
- // is not initialized
- int mailboxIndex = 0; // 0 is no mailbox dailing number associated
-
-
- byte[] efMWIS = null;
- byte[] efCPHS_MWI =null;
- byte[] mEfCff = null;
- byte[] mEfCfis = null;
+ protected boolean recordsRequested = false; // true if we've made requests for the sim records
+ public String iccid;
+ protected String msisdn = null; // My mobile number
+ protected String msisdnTag = null;
+ protected String voiceMailNum = null;
+ protected String voiceMailTag = null;
+ protected String newVoiceMailNum = null;
+ protected String newVoiceMailTag = null;
+ protected boolean isVoiceMailFixed = false;
+ protected int countVoiceMessages = 0;
- String spn;
- int spnDisplayCondition;
- // Numeric network codes listed in TS 51.011 EF[SPDI]
- ArrayList<String> spdiNetworks = null;
+ protected int mncLength = 0; // 0 is used to indicate that the value
+ // is not initialized
+ protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated
- String pnnHomeName = null;
+ protected String spn;
+ protected int spnDisplayCondition;
//***** Constants
// Bitmasks for SPN display rules.
- static final int SPN_RULE_SHOW_SPN = 0x01;
- static final int SPN_RULE_SHOW_PLMN = 0x02;
-
- // From TS 51.011 EF[SPDI] section
- static final int TAG_SPDI_PLMN_LIST = 0x80;
-
- // Full Name IEI from TS 24.008
- static final int TAG_FULL_NETWORK_NAME = 0x43;
-
- // Short Name IEI from TS 24.008
- static final int TAG_SHORT_NETWORK_NAME = 0x45;
-
- // active CFF from CPHS 4.2 B.4.5
- static final int CFF_UNCONDITIONAL_ACTIVE = 0x0a;
- static final int CFF_UNCONDITIONAL_DEACTIVE = 0x05;
- static final int CFF_LINE1_MASK = 0x0f;
- static final int CFF_LINE1_RESET = 0xf0;
+ protected static final int SPN_RULE_SHOW_SPN = 0x01;
+ protected static final int SPN_RULE_SHOW_PLMN = 0x02;
//***** Event Constants
- private static final int EVENT_SET_MSISDN_DONE = 30;
-
+ protected static final int EVENT_SET_MSISDN_DONE = 30;
+
//***** Constructor
- public IccRecords(PhoneBase phone) {
- this.phone = phone;
+ public IccRecords(PhoneBase p) {
+ this.phone = p;
}
-// TODO T: check if public can /should be avoided
- protected AdnRecordCache getAdnCache() {
- return adnCache;
- }
+ protected abstract void onRadioOffOrNotAvailable();
- protected void onRadioOffOrNotAvailable() {
- imsi = null;
- msisdn = null;
- voiceMailNum = null;
- countVoiceMessages = 0;
- mncLength = 0;
- iccid = null;
- spn = null;
- // -1 means no EF_SPN found; treat accordingly.
- spnDisplayCondition = -1;
- efMWIS = null;
- efCPHS_MWI = null;
- spn = null;
- spdiNetworks = null;
- pnnHomeName = null;
-
- adnCache.reset();
-
- phone.setSystemProperty(PROPERTY_LINE1_VOICE_MAIL_WAITING, null);
- phone.setSystemProperty(PROPERTY_SIM_OPERATOR_NUMERIC, null);
- phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ALPHA, null);
- phone.setSystemProperty(PROPERTY_SIM_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
- // true only when fresh set of read requests are made.
- recordsRequested = false;
+ //***** Public Methods
+ public AdnRecordCache getAdnCache() {
+ return adnCache;
}
-
- //***** Public Methods
public void registerForRecordsLoaded(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
recordsLoadedRegistrants.add(r);
@@ -155,9 +92,8 @@ public abstract class IccRecords extends Handler implements IccConstants {
}
}
- /** Returns null if SIM is not yet ready */
- public String getIMSI() {
- return imsi;
+ public void unregisterForRecordsLoaded(Handler h) {
+ recordsLoadedRegistrants.remove(h);
}
public String getMsisdnNumber() {
@@ -203,10 +139,10 @@ public abstract class IccRecords extends Handler implements IccConstants {
}
/**
- * Return Service Provider Name stored in SIM
- * @return null if SIM is not yet ready
+ * Return Service Provider Name stored in SIM (EF_SPN=0x6F46) or in RUIM (EF_RUIM_SPN=0x6F41)
+ * @return null if SIM is not yet ready or no RUIM entry
*/
- public String getServiceProvideName() {
+ public String getServiceProviderName() {
return spn;
}
@@ -217,7 +153,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
* EF_MAILBOX_CPHS (CPHS 4.2)
*
* If EF_MBDN is available, store the voice mail number to EF_MBDN
- *
+ *
* If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
*
* So the voice mail number will be stored in both EFs if both are available
@@ -245,7 +181,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
* Sets the SIM voice message waiting indicator records
* @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
* @param countWaiting The number of messages waiting, if known. Use
- * -1 to indicate that an unknown number of
+ * -1 to indicate that an unknown number of
* messages are waiting
*/
public abstract void setVoiceMessageWaiting(int line, int countWaiting);
@@ -257,20 +193,13 @@ public abstract class IccRecords extends Handler implements IccConstants {
/**
* Returns number of voice messages waiting, if available
- * If not available (eg, on an older CPHS SIM) -1 is returned if
+ * If not available (eg, on an older CPHS SIM) -1 is returned if
* getVoiceMessageWaiting() is true
*/
public int getCountVoiceMessages() {
return countVoiceMessages;
}
- public boolean getVoiceCallForwardingFlag() {
- return callForwardingEnabled;
- }
-
- public abstract void setVoiceCallForwardingFlag(int line, boolean enable);
-
-
/**
* Called by STK Service when REFRESH is received.
* @param fileChanged indicates whether any files changed
@@ -279,7 +208,6 @@ public abstract class IccRecords extends Handler implements IccConstants {
public abstract void onRefresh(boolean fileChanged, int[] fileList);
-// TODO T: check if public can /should be avoided
public boolean getRecordsLoaded() {
if (recordsToLoad == 0 && recordsRequested == true) {
return true;
@@ -292,10 +220,9 @@ public abstract class IccRecords extends Handler implements IccConstants {
public abstract void handleMessage(Message msg);
protected abstract void onRecordLoaded();
-
+
protected abstract void onAllRecordsLoaded();
-
-// TODO T: check if public can /should be avoided
+
/**
* Returns the SpnDisplayRule based on settings on the SIM and the
* specified plmn (currently-registered PLMN). See TS 22.101 Annex A
@@ -304,9 +231,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
* If the SPN is not found on the SIM, the rule is always PLMN_ONLY.
*/
protected abstract int getDisplayRule(String plmn);
-
- private void log(String s) {
- Log.d(LOG_TAG, " " + s);
- }
-
+
+ protected abstract void log(String s);
}
+
diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index b2c69b5e95af..620f2deae500 100644
--- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,22 +18,149 @@ package com.android.internal.telephony;
import android.app.PendingIntent;
import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.ServiceManager;
-import android.telephony.gsm.SmsManager;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.gsm.*; //TO BE REMOVED when Isms goes to telephony
+import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
/**
- * SimSmsInterfaceManager to provide an inter-process communication to
- * access Sms in Sim.
+ * IccSmsInterfaceManager to provide an inter-process communication to
+ * access Sms in Icc.
*/
public abstract class IccSmsInterfaceManager extends ISms.Stub {
+ static final boolean DBG = true;
+
+ protected PhoneBase mPhone;
+ protected Context mContext;
+ protected SMSDispatcher mDispatcher;
+
+ protected IccSmsInterfaceManager(PhoneBase phone){
+ mPhone = phone;
+ mContext = phone.getContext();
+ }
+
+ protected void enforceReceiveAndSend(String message) {
+ mContext.enforceCallingPermission(
+ "android.permission.RECEIVE_SMS", message);
+ mContext.enforceCallingPermission(
+ "android.permission.SEND_SMS", message);
+ }
+
+ /**
+ * Send a Raw PDU SMS
+ *
+ * @param smsc the SMSC to send the message through, or NULL for the
+ * defatult SMSC
+ * @param pdu the raw PDU to send
+ * @param sentIntent if not NULL this <code>Intent</code> is
+ * broadcast when the message is sucessfully sent, or failed.
+ * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * or one of these errors:
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code>
+ * <code>RESULT_ERROR_RADIO_OFF</code>
+ * <code>RESULT_ERROR_NULL_PDU</code>.
+ * @param deliveryIntent if not NULL this <code>Intent</code> is
+ * broadcast when the message is delivered to the recipient. The
+ * raw pdu of the status report is in the extended data ("pdu").
+ */
+ public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
+ PendingIntent deliveryIntent) {
+ Context context = mPhone.getContext();
+
+ context.enforceCallingPermission(
+ "android.permission.SEND_SMS",
+ "Sending SMS message");
+ if (DBG) log("sendRawPdu: smsc=" + smsc +
+ " pdu="+ pdu + " sentIntent" + sentIntent +
+ " deliveryIntent" + deliveryIntent);
+ mDispatcher.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
+ }
+
+ /**
+ * Send a multi-part text based SMS.
+ *
+ * @param destinationAddress the address to send the message to
+ * @param scAddress is the service center address or null to use
+ * the current default SMSC
+ * @param parts an <code>ArrayList</code> of strings that, in order,
+ * comprise the original message
+ * @param sentIntents if not null, an <code>ArrayList</code> of
+ * <code>PendingIntent</code>s (one for each message part) that is
+ * broadcast when the corresponding message part has been sent.
+ * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * or one of these errors:
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code>
+ * <code>RESULT_ERROR_RADIO_OFF</code>
+ * <code>RESULT_ERROR_NULL_PDU</code>.
+ * @param deliveryIntents if not null, an <code>ArrayList</code> of
+ * <code>PendingIntent</code>s (one for each message part) that is
+ * broadcast when the corresponding message part has been delivered
+ * to the recipient. The raw pdu of the status report is in the
+ * extended data ("pdu").
+ */
+ public void sendMultipartText(String destinationAddress, String scAddress, List<String> parts,
+ List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
+ Context context = mPhone.getContext();
+
+ context.enforceCallingPermission(
+ "android.permission.SEND_SMS",
+ "Sending SMS message");
+ if (DBG) log("sendMultipartText");
+ mDispatcher.sendMultipartText(destinationAddress, scAddress, (ArrayList<String>) parts,
+ (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents);
+ }
+
+ /**
+ * create SmsRawData lists from all sms record byte[]
+ * Use null to indicate "free" record
+ *
+ * @param messages List of message records from EF_SMS.
+ * @return SmsRawData list of all in-used records
+ */
+ protected ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) {
+ int count = messages.size();
+ ArrayList<SmsRawData> ret;
+
+ ret = new ArrayList<SmsRawData>(count);
+
+ for (int i = 0; i < count; i++) {
+ byte[] ba = messages.get(i);
+ if (ba[0] == STATUS_ON_ICC_FREE) {
+ ret.add(null);
+ } else {
+ ret.add(new SmsRawData(messages.get(i)));
+ }
+ }
+
+ return ret;
+ }
+
+ /**
+ * Generates an EF_SMS record from status and raw PDU.
+ *
+ * @param status Message status. See TS 51.011 10.5.3.
+ * @param pdu Raw message PDU.
+ * @return byte array for the record.
+ */
+ protected byte[] makeSmsRecordData(int status, byte[] pdu) {
+ byte[] data = new byte[IccConstants.SMS_RECORD_LENGTH];
+
+ // Status bits for this record. See TS 51.011 10.5.3
+ data[0] = (byte)(status & 7);
+
+ System.arraycopy(pdu, 0, data, 1, pdu.length);
+
+ // Pad out with 0xFF's.
+ for (int j = pdu.length+1; j < IccConstants.SMS_RECORD_LENGTH; j++) {
+ data[j] = -1;
+ }
+
+ return data;
+ }
+
+ protected abstract void log(String msg);
+
}
+
diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
index 90c0ec098da6..a51d074104c7 100644
--- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
+++ b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,58 +17,49 @@
package com.android.internal.telephony;
import android.app.PendingIntent;
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
import android.os.ServiceManager;
-import android.telephony.gsm.SmsManager;
-import android.util.Log;
-import java.util.ArrayList;
import java.util.List;
-//TODO remove after moving SmsRawData and ISms.Stub to telephony
-import com.android.internal.telephony.gsm.*;
-
public class IccSmsInterfaceManagerProxy extends ISms.Stub {
private IccSmsInterfaceManager mIccSmsInterfaceManager;
- public IccSmsInterfaceManagerProxy(IccSmsInterfaceManager
+ public IccSmsInterfaceManagerProxy(IccSmsInterfaceManager
iccSmsInterfaceManager) {
this.mIccSmsInterfaceManager = iccSmsInterfaceManager;
- ServiceManager.addService("isms", this);
+ if(ServiceManager.getService("isms") == null) {
+ ServiceManager.addService("isms", this);
+ }
+ }
+
+ public void setmIccSmsInterfaceManager(IccSmsInterfaceManager iccSmsInterfaceManager) {
+ this.mIccSmsInterfaceManager = iccSmsInterfaceManager;
}
public boolean
- //TODO Investigate
- updateMessageOnSimEf(int index, int status, byte[] pdu) throws android.os.RemoteException {
- return mIccSmsInterfaceManager.updateMessageOnSimEf(index, status, pdu);
+ updateMessageOnIccEf(int index, int status, byte[] pdu) throws android.os.RemoteException {
+ return mIccSmsInterfaceManager.updateMessageOnIccEf(index, status, pdu);
}
- //TODO Investigate
- public boolean copyMessageToSimEf(int status, byte[] pdu,
+ public boolean copyMessageToIccEf(int status, byte[] pdu,
byte[] smsc) throws android.os.RemoteException {
- return mIccSmsInterfaceManager.copyMessageToSimEf(status, pdu, smsc);
+ return mIccSmsInterfaceManager.copyMessageToIccEf(status, pdu, smsc);
}
- //TODO Investigate
- public List<SmsRawData> getAllMessagesFromSimEf() throws android.os.RemoteException {
- return mIccSmsInterfaceManager.getAllMessagesFromSimEf();
+ public List<SmsRawData> getAllMessagesFromIccEf() throws android.os.RemoteException {
+ return mIccSmsInterfaceManager.getAllMessagesFromIccEf();
}
- //TODO Investigate
public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
PendingIntent deliveryIntent) throws android.os.RemoteException {
- mIccSmsInterfaceManager.sendRawPdu(smsc, pdu, sentIntent,
+ mIccSmsInterfaceManager.sendRawPdu(smsc, pdu, sentIntent,
deliveryIntent);
}
- //TODO Investigate
- public void sendMultipartText(String destinationAddress, String scAddress,
- List<String> parts, List<PendingIntent> sentIntents,
+ public void sendMultipartText(String destinationAddress, String scAddress,
+ List<String> parts, List<PendingIntent> sentIntents,
List<PendingIntent> deliveryIntents) throws android.os.RemoteException {
- mIccSmsInterfaceManager.sendMultipartText(destinationAddress, scAddress,
+ mIccSmsInterfaceManager.sendMultipartText(destinationAddress, scAddress,
parts, sentIntents, deliveryIntents);
}
diff --git a/telephony/java/com/android/internal/telephony/IccUtils.java b/telephony/java/com/android/internal/telephony/IccUtils.java
index ea544ab1eaa0..917be43989e7 100644
--- a/telephony/java/com/android/internal/telephony/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/IccUtils.java
@@ -16,12 +16,13 @@
package com.android.internal.telephony;
-import java.io.UnsupportedEncodingException;
-
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.Log;
-import com.android.internal.telephony.gsm.GsmAlphabet;
+
+import com.android.internal.telephony.GsmAlphabet;
+
+import java.io.UnsupportedEncodingException;
/**
* Various methods, useful for dealing with SIM data.
@@ -32,7 +33,7 @@ public class IccUtils {
/**
* Many fields in GSM SIM's are stored as nibble-swizzled BCD
*
- * Assumes left-justified field that may be padded right with 0xf
+ * Assumes left-justified field that may be padded right with 0xf
* values.
*
* Stops on invalid BCD value, returning string so far
@@ -40,21 +41,21 @@ public class IccUtils {
public static String
bcdToString(byte[] data, int offset, int length) {
StringBuilder ret = new StringBuilder(length*2);
-
+
for (int i = offset ; i < offset + length ; i++) {
byte b;
int v;
-
+
v = data[i] & 0xf;
if (v > 9) break;
ret.append((char)('0' + v));
v = (data[i] >> 4) & 0xf;
if (v > 9) break;
- ret.append((char)('0' + v));
+ ret.append((char)('0' + v));
}
-
- return ret.toString();
+
+ return ret.toString();
}
@@ -65,7 +66,7 @@ public class IccUtils {
* significant nibble.
*
* Out-of-range digits are treated as 0 for the sake of the time stamp,
- * because of this:
+ * because of this:
*
* TS 23.040 section 9.2.3.11
* "if the MS receives a non-integer value in the SCTS, it shall
@@ -78,7 +79,7 @@ public class IccUtils {
// treat out-of-range BCD values as 0
if ((b & 0xf0) <= 0x90) {
- ret = (b >> 4) & 0xf;
+ ret = (b >> 4) & 0xf;
}
if ((b & 0x0f) <= 0x09) {
@@ -88,6 +89,24 @@ public class IccUtils {
return ret;
}
+ /** Decodes BCD byte like {@link bcdByteToInt}, but the most significant BCD
+ * digit is expected in the most significant nibble.
+ */
+ public static int
+ beBcdByteToInt(byte b) {
+ int ret = 0;
+
+ // treat out-of-range BCD values as 0
+ if ((b & 0xf0) <= 0x90) {
+ ret = ((b >> 4) & 0xf) * 10;
+ }
+
+ if ((b & 0x0f) <= 0x09) {
+ ret += (b & 0xf);
+ }
+
+ return ret;
+ }
/**
* Decodes a string field that's formatted like the EF[ADN] alpha
@@ -96,8 +115,8 @@ public class IccUtils {
* From TS 51.011 10.5.1:
* Coding:
* this alpha tagging shall use either
- * - the SMS default 7 bit coded alphabet as defined in
- * TS 23.038 [12] with bit 8 set to 0. The alpha identifier
+ * - the SMS default 7 bit coded alphabet as defined in
+ * TS 23.038 [12] with bit 8 set to 0. The alpha identifier
* shall be left justified. Unused bytes shall be set to 'FF'; or
* - one of the UCS2 coded options as defined in annex B.
*
@@ -107,7 +126,7 @@ public class IccUtils {
* 2) if the first octet in the alpha string is '81', then the
* second octet contains a value indicating the number of
* characters in the string, and the third octet contains an
- * 8 bit number which defines bits 15 to 8 of a 16 bit
+ * 8 bit number which defines bits 15 to 8 of a 16 bit
* base pointer, where bit 16 is set to zero and bits 7 to 1
* are also set to zero. These sixteen bits constitute a
* base pointer to a "half page" in the UCS2 code space, to be
@@ -215,12 +234,12 @@ public class IccUtils {
/**
* Converts a hex String to a byte array.
- *
+ *
* @param s A string of hexadecimal characters, must be an even number of
* chars long
*
* @return byte array representation
- *
+ *
* @throws RuntimeException on invalid format
*/
public static byte[]
@@ -234,10 +253,10 @@ public class IccUtils {
ret = new byte[sz/2];
for (int i=0 ; i <sz ; i+=2) {
- ret[i/2] = (byte) ((hexCharToInt(s.charAt(i)) << 4)
+ ret[i/2] = (byte) ((hexCharToInt(s.charAt(i)) << 4)
| hexCharToInt(s.charAt(i+1)));
}
-
+
return ret;
}
@@ -250,7 +269,7 @@ public class IccUtils {
public static String
bytesToHexString(byte[] bytes) {
if (bytes == null) return null;
-
+
StringBuilder ret = new StringBuilder(2*bytes.length);
for (int i = 0 ; i < bytes.length ; i++) {
@@ -277,7 +296,7 @@ public class IccUtils {
public static String
networkNameToString(byte[] data, int offset, int length) {
String ret;
-
+
if ((data[offset] & 0x80) != 0x80 || length < 1) {
return "";
}
@@ -288,13 +307,12 @@ public class IccUtils {
int countSeptets;
int unusedBits = data[offset] & 7;
countSeptets = (((length - 1) * 8) - unusedBits) / 7 ;
- ret = GsmAlphabet.gsm7BitPackedToString(
- data, offset + 1, countSeptets);
+ ret = GsmAlphabet.gsm7BitPackedToString(data, offset + 1, countSeptets);
break;
case 1:
// UCS2
try {
- ret = new String(data,
+ ret = new String(data,
offset + 1, length - 1, "utf-16");
} catch (UnsupportedEncodingException ex) {
ret = "";
@@ -325,7 +343,7 @@ public class IccUtils {
* @param data The raw data
* @param length The length of image body
* @return The bitmap
- */
+ */
public static Bitmap parseToBnW(byte[] data, int length){
int valueIndex = 0;
int width = data[valueIndex++] & 0xFF;
@@ -362,7 +380,7 @@ public class IccUtils {
/**
* a TS 131.102 image instance of code scheme '11' into color Bitmap
- *
+ *
* @param data The raw data
* @param length the length of image body
* @param transparency with or without transparency
diff --git a/telephony/java/com/android/internal/telephony/MmiCode.java b/telephony/java/com/android/internal/telephony/MmiCode.java
index 925b06fb926c..c71ff778d859 100644
--- a/telephony/java/com/android/internal/telephony/MmiCode.java
+++ b/telephony/java/com/android/internal/telephony/MmiCode.java
@@ -41,14 +41,14 @@ public interface MmiCode
* @return Localized message for UI display, valid only in COMPLETE
* or FAILED states. null otherwise
*/
-
+
public CharSequence getMessage();
/**
* Cancels pending MMI request.
* State becomes CANCELLED unless already COMPLETE or FAILED
*/
- public void cancel();
+ public void cancel();
/**
* @return true if the network response is a REQUEST for more user input.
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index d178c37309a3..398f9d316f8a 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -21,6 +21,8 @@ import android.os.Handler;
import android.os.Message;
import android.telephony.CellLocation;
import android.telephony.ServiceState;
+
+import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.gsm.NetworkInfo;
import com.android.internal.telephony.gsm.PdpConnection;
import com.android.internal.telephony.test.SimulatedRadioControl;
@@ -38,13 +40,13 @@ public interface Phone {
/** used to enable additional debug messages */
static final boolean DEBUG_PHONE = true;
-
- /**
+
+ /**
* The phone state. One of the following:<p>
* <ul>
* <li>IDLE = no phone activity</li>
- * <li>RINGING = a phone call is ringing or call waiting.
+ * <li>RINGING = a phone call is ringing or call waiting.
* In the latter case, another call is active as well</li>
* <li>OFFHOOK = The phone is off hook. At least one call
* exists that is dialing, active or holding and no calls are
@@ -70,7 +72,7 @@ public interface Phone {
CONNECTED, CONNECTING, DISCONNECTED, SUSPENDED;
};
- enum DataActivityState {
+ public enum DataActivityState {
/**
* The state of a data activity.
* <ul>
@@ -131,6 +133,7 @@ public interface Phone {
static final String REASON_DATA_ENABLED = "dataEnabled";
static final String REASON_GPRS_ATTACHED = "gprsAttached";
static final String REASON_GPRS_DETACHED = "gprsDetached";
+ static final String REASON_CDMA_DATA_DETACHED = "cdmaDataDetached";
static final String REASON_APN_CHANGED = "apnChanged";
static final String REASON_APN_SWITCHED = "apnSwitched";
static final String REASON_RESTORE_DEFAULT_APN = "restoreDefaultApn";
@@ -149,26 +152,32 @@ public interface Phone {
static final int BM_BOUNDARY = 6; // upper band boundary
// Used for preferred network type
- static final int NT_AUTO_TYPE = 0; // GSM/WCDMA (WCDMA preferred)
- static final int NT_GSM_TYPE = 1; // GSM only
- static final int NT_WCDMA_TYPE = 2; // WCDMA only
- static final int NT_GSM_UMTS_AUTO_TYPE = 3; // GSM/WCDMA (auto mode)
- static final int NT_CDMA_EVDO_AUTO_TYPE = 4; // CDMA and EvDo (auto mode, according to PRL)
- static final int NT_CDMA_TYPE = 5; // CDMA only
- static final int NT_EVDO_TYPE = 6; // EvDo only
- static final int NT_GLOBAL_AUTO_TYPE = 7; // GSM/WCDMA, CDMA, EvDo (auto mode, according to PRL)
+ // 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_GLOBAL;
+
// 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
-
+
// 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
/**
- * Get the current ServiceState. Use
+ * Get the current ServiceState. Use
* <code>registerForServiceStateChanged</code> to be informed of
* updates.
*/
@@ -178,11 +187,12 @@ public interface Phone {
* Get the current CellLocation.
*/
CellLocation getCellLocation();
-
+
/**
* Get the current DataState. No change notification exists at this
- * interface -- use
- * {@link com.android.internal.telephony.PhoneStateIntentReceiver PhoneStateIntentReceiver} instead.
+ * interface -- use
+ * {@link com.android.internal.telephony.PhoneStateIntentReceiver PhoneStateIntentReceiver}
+ * instead.
*/
DataState getDataConnectionState();
@@ -192,58 +202,58 @@ public interface Phone {
* {@link TelephonyManager} instead.
*/
DataActivityState getDataActivityState();
-
+
/**
* Gets the context for the phone, as set at initialization time.
*/
Context getContext();
- /**
+ /**
* Get current coarse-grained voice call state.
- * Use {@link #registerForPhoneStateChanged(Handler, int, Object)
+ * Use {@link #registerForPhoneStateChanged(Handler, int, Object)
* registerForPhoneStateChanged()} for change notification. <p>
* If the phone has an active call and call waiting occurs,
* then the phone state is RINGING not OFFHOOK
- * <strong>Note:</strong>
+ * <strong>Note:</strong>
* This registration point provides notification of finer-grained
* changes.<p>
*
*/
State getState();
- /**
+ /**
* Returns a string identifier for this phone interface for parties
* outside the phone app process.
* @return The string name.
*/
String getPhoneName();
- /**
+ /**
* Returns an array of string identifiers for the APN types serviced by the
* currently active or last connected APN.
* @return The string array.
*/
String[] getActiveApnTypes();
-
- /**
+
+ /**
* Returns a string identifier for currently active or last connected APN.
* @return The string name.
*/
String getActiveApn();
-
- /**
+
+ /**
* Get current signal strength. No change notification available on this
* interface. Use <code>PhoneStateNotifier</code> or an equivalent.
- * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu).
+ * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu).
* The following special values are defined:</p>
* <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.
*/
int getSignalStrengthASU();
-
- /**
+
+ /**
* Notifies when a previously untracked non-ringing/waiting connection has appeared.
* This is likely due to some other entity (eg, SIM card application) initiating a call.
*/
@@ -254,7 +264,7 @@ public interface Phone {
*/
void unregisterForUnknownConnection(Handler h);
- /**
+ /**
* Notifies when any aspect of the voice call state changes.
* Resulting events will have an AsyncResult in <code>Message.obj</code>.
* AsyncResult.userData will be set to the obj argument here.
@@ -263,13 +273,13 @@ public interface Phone {
void registerForPhoneStateChanged(Handler h, int what, Object obj);
/**
- * Unregisters for voice call state change notifications.
+ * Unregisters for voice call state change notifications.
* Extraneous calls are tolerated silently.
*/
void unregisterForPhoneStateChanged(Handler h);
- /**
+ /**
* Notifies when a new ringing or waiting connection has appeared.<p>
*
* Messages received from this:
@@ -278,19 +288,19 @@ public interface Phone {
* AsyncResult.result = a Connection. <p>
* Please check Connection.isRinging() to make sure the Connection
* has not dropped since this message was posted.
- * If Connection.isRinging() is true, then
+ * If Connection.isRinging() is true, then
* Connection.getCall() == Phone.getRingingCall()
*/
void registerForNewRingingConnection(Handler h, int what, Object obj);
/**
- * Unregisters for new ringing connection notification.
+ * Unregisters for new ringing connection notification.
* Extraneous calls are tolerated silently
*/
void unregisterForNewRingingConnection(Handler h);
- /**
+ /**
* Notifies when an incoming call rings.<p>
*
* Messages received from this:
@@ -299,29 +309,29 @@ public interface Phone {
* AsyncResult.result = a Connection. <p>
*/
void registerForIncomingRing(Handler h, int what, Object obj);
-
+
/**
- * Unregisters for ring notification.
+ * Unregisters for ring notification.
* Extraneous calls are tolerated silently
*/
-
+
void unregisterForIncomingRing(Handler h);
-
-
- /**
+
+
+ /**
* Notifies when a voice connection has disconnected, either due to local
* or remote hangup or error.
- *
+ *
* Messages received from this will have the following members:<p>
* <ul><li>Message.obj will be an AsyncResult</li>
* <li>AsyncResult.userObj = obj</li>
- * <li>AsyncResult.result = a Connection object that is
+ * <li>AsyncResult.result = a Connection object that is
* no longer connected.</li></ul>
*/
void registerForDisconnect(Handler h, int what, Object obj);
/**
- * Unregisters for voice disconnection notification.
+ * Unregisters for voice disconnection notification.
* Extraneous calls are tolerated silently
*/
void unregisterForDisconnect(Handler h);
@@ -341,7 +351,7 @@ public interface Phone {
void registerForMmiInitiate(Handler h, int what, Object obj);
/**
- * Unregisters for new MMI initiate notification.
+ * Unregisters for new MMI initiate notification.
* Extraneous calls are tolerated silently
*/
void unregisterForMmiInitiate(Handler h);
@@ -357,7 +367,7 @@ public interface Phone {
void registerForMmiComplete(Handler h, int what, Object obj);
/**
- * Unregisters for MMI complete notification.
+ * Unregisters for MMI complete notification.
* Extraneous calls are tolerated silently
*/
void unregisterForMmiComplete(Handler h);
@@ -366,7 +376,7 @@ public interface Phone {
* Returns a list of MMI codes that are pending. (They have initiated
* but have not yet completed).
* Presently there is only ever one.
- * Use <code>registerForMmiInitiate</code>
+ * Use <code>registerForMmiInitiate</code>
* and <code>registerForMmiComplete</code> for change notification.
*/
public List<? extends MmiCode> getPendingMmiCodes();
@@ -381,14 +391,14 @@ public interface Phone {
public void sendUssdResponse(String ussdMessge);
/**
- * Register for ServiceState changed.
+ * Register for ServiceState changed.
* Message.obj will contain an AsyncResult.
* AsyncResult.result will be a ServiceState instance
*/
void registerForServiceStateChanged(Handler h, int what, Object obj);
/**
- * Unregisters for ServiceStateChange notification.
+ * Unregisters for ServiceStateChange notification.
* Extraneous calls are tolerated silently
*/
void unregisterForServiceStateChanged(Handler h);
@@ -405,9 +415,9 @@ public interface Phone {
void registerForSuppServiceNotification(Handler h, int what, Object obj);
/**
- * Unregisters for Supplementary Service notifications.
+ * Unregisters for Supplementary Service notifications.
* Extraneous calls are tolerated silently
- *
+ *
* @param h Handler to be removed from the registrant list.
*/
void unregisterForSuppServiceNotification(Handler h);
@@ -425,20 +435,52 @@ public interface Phone {
/**
* Unregister for notifications when a supplementary service attempt fails.
* Extraneous calls are tolerated silently
- *
+ *
* @param h Handler to be removed from the registrant list.
*/
void unregisterForSuppServiceFailed(Handler h);
- /**
- * Returns SIM record load state. Use
+ /**
+ * Register for notifications when a sInCall VoicePrivacy is enabled
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
+
+ /**
+ * Unegister for notifications when a sInCall VoicePrivacy is enabled
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForInCallVoicePrivacyOn(Handler h);
+
+ /**
+ * Register for notifications when a sInCall VoicePrivacy is disabled
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj);
+
+ /**
+ * Unegister for notifications when a sInCall VoicePrivacy is disabled
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForInCallVoicePrivacyOff(Handler h);
+
+ /**
+ * Returns SIM record load state. Use
* <code>getSimCard().registerForReady()</code> for change notification.
*
- * @return true if records from the SIM have been loaded and are
+ * @return true if records from the SIM have been loaded and are
* available (if applicable). If not applicable to the underlying
* technology, returns true as well.
*/
- boolean getSimRecordsLoaded();
+ boolean getIccRecordsLoaded();
/**
* Returns the ICC card interface for this phone, or null
@@ -447,31 +489,31 @@ public interface Phone {
IccCard getIccCard();
/**
- * Answers a ringing or waiting call. Active calls, if any, go on hold.
+ * Answers a ringing or waiting call. Active calls, if any, go on hold.
* Answering occurs asynchronously, and final notification occurs via
- * {@link #registerForPhoneStateChanged(android.os.Handler, int,
+ * {@link #registerForPhoneStateChanged(android.os.Handler, int,
* java.lang.Object) registerForPhoneStateChanged()}.
*
* @exception CallStateException when no call is ringing or waiting
*/
void acceptCall() throws CallStateException;
- /**
- * Reject (ignore) a ringing call. In GSM, this means UDUB
- * (User Determined User Busy). Reject occurs asynchronously,
- * and final notification occurs via
- * {@link #registerForPhoneStateChanged(android.os.Handler, int,
+ /**
+ * Reject (ignore) a ringing call. In GSM, this means UDUB
+ * (User Determined User Busy). Reject occurs asynchronously,
+ * and final notification occurs via
+ * {@link #registerForPhoneStateChanged(android.os.Handler, int,
* java.lang.Object) registerForPhoneStateChanged()}.
*
* @exception CallStateException when no call is ringing or waiting
*/
void rejectCall() throws CallStateException;
- /**
+ /**
* Places any active calls on hold, and makes any held calls
* active. Switch occurs asynchronously and may fail.
- * Final notification occurs via
- * {@link #registerForPhoneStateChanged(android.os.Handler, int,
+ * Final notification occurs via
+ * {@link #registerForPhoneStateChanged(android.os.Handler, int,
* java.lang.Object) registerForPhoneStateChanged()}.
*
* @exception CallStateException if a call is ringing, waiting, or
@@ -480,18 +522,18 @@ public interface Phone {
void switchHoldingAndActive() throws CallStateException;
/**
- * Whether or not the phone can conference in the current phone
+ * Whether or not the phone can conference in the current phone
* state--that is, one call holding and one call active.
- * @return true if the phone can conference; false otherwise.
+ * @return true if the phone can conference; false otherwise.
*/
boolean canConference();
/**
- * Conferences holding and active. Conference occurs asynchronously
- * and may fail. Final notification occurs via
- * {@link #registerForPhoneStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPhoneStateChanged()}.
- *
+ * Conferences holding and active. Conference occurs asynchronously
+ * and may fail. Final notification occurs via
+ * {@link #registerForPhoneStateChanged(android.os.Handler, int,
+ * java.lang.Object) registerForPhoneStateChanged()}.
+ *
* @exception CallStateException if canConference() would return false.
* In these cases, this operation may not be performed.
*/
@@ -500,15 +542,15 @@ public interface Phone {
/**
* Enable or disable enhanced Voice Privacy (VP). If enhanced VP is
* disabled, normal VP is enabled.
- *
+ *
* @param enable whether true or false to enable or disable.
* @param onComplete a callback message when the action is completed.
*/
void enableEnhancedVoicePrivacy(boolean enable, Message onComplete);
-
+
/**
* Get the currently set Voice Privacy (VP) mode.
- *
+ *
* @param onComplete a callback message when the action is completed.
*/
void getEnhancedVoicePrivacy(Message onComplete);
@@ -540,65 +582,65 @@ public interface Phone {
void clearDisconnected();
- /**
- * Gets the foreground call object, which represents all connections that
- * are dialing or active (all connections
+ /**
+ * Gets the foreground call object, which represents all connections that
+ * are dialing or active (all connections
* that have their audio path connected).<p>
*
* The foreground call is a singleton object. It is constant for the life
* of this phone. It is never null.<p>
- *
+ *
* The foreground call will only ever be in one of these states:
- * IDLE, ACTIVE, DIALING, ALERTING, or DISCONNECTED.
+ * IDLE, ACTIVE, DIALING, ALERTING, or DISCONNECTED.
*
* State change notification is available via
- * {@link #registerForPhoneStateChanged(android.os.Handler, int,
+ * {@link #registerForPhoneStateChanged(android.os.Handler, int,
* java.lang.Object) registerForPhoneStateChanged()}.
*/
Call getForegroundCall();
- /**
+ /**
* Gets the background call object, which represents all connections that
* are holding (all connections that have been accepted or connected, but
* do not have their audio path connected). <p>
*
* The background call is a singleton object. It is constant for the life
* of this phone object . It is never null.<p>
- *
+ *
* The background call will only ever be in one of these states:
* IDLE, HOLDING or DISCONNECTED.
*
* State change notification is available via
- * {@link #registerForPhoneStateChanged(android.os.Handler, int,
+ * {@link #registerForPhoneStateChanged(android.os.Handler, int,
* java.lang.Object) registerForPhoneStateChanged()}.
*/
Call getBackgroundCall();
- /**
- * Gets the ringing call object, which represents an incoming
+ /**
+ * Gets the ringing call object, which represents an incoming
* connection (if present) that is pending answer/accept. (This connection
* may be RINGING or WAITING, and there may be only one.)<p>
* The ringing call is a singleton object. It is constant for the life
* of this phone. It is never null.<p>
- *
+ *
* The ringing call will only ever be in one of these states:
* IDLE, INCOMING, WAITING or DISCONNECTED.
*
* State change notification is available via
- * {@link #registerForPhoneStateChanged(android.os.Handler, int,
+ * {@link #registerForPhoneStateChanged(android.os.Handler, int,
* java.lang.Object) registerForPhoneStateChanged()}.
*/
Call getRingingCall();
- /**
+ /**
* Initiate a new voice connection. This happens asynchronously, so you
* cannot assume the audio path is connected (or a call index has been
* assigned) until PhoneStateChanged notification has occurred.
*
* @exception CallStateException if a new outgoing call is not currently
- * possible because no more call slots exist or a call exists that is
- * dialing, alerting, ringing, or waiting. Other errors are
+ * possible because no more call slots exist or a call exists that is
+ * dialing, alerting, ringing, or waiting. Other errors are
* handled asynchronously.
*/
Connection dial(String dialString) throws CallStateException;
@@ -606,7 +648,7 @@ public interface Phone {
/**
* Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
* without SEND (so <code>dial</code> is not appropriate).
- *
+ *
* @param dialString the MMI command to be executed.
* @return true if MMI command is executed.
*/
@@ -624,7 +666,7 @@ public interface Phone {
boolean handleInCallMmiCommands(String command) throws CallStateException;
/**
- * Play a DTMF tone on the active call. Ignored if there is no active call.
+ * Play a DTMF tone on the active call. Ignored if there is no active call.
* @param c should be one of 0-9, '*' or '#'. Other values will be
* silently ignored.
*/
@@ -646,20 +688,20 @@ public interface Phone {
/**
- * Sets the radio power on/off state (off is sometimes
- * called "airplane mode"). Current state can be gotten via
- * {@link #getServiceState()}.{@link
+ * Sets the radio power on/off state (off is sometimes
+ * called "airplane mode"). Current state can be gotten via
+ * {@link #getServiceState()}.{@link
* android.telephony.ServiceState#getState() getState()}.
- * <strong>Note: </strong>This request is asynchronous.
+ * <strong>Note: </strong>This request is asynchronous.
* getServiceState().getState() will not change immediately after this call.
- * registerForServiceStateChanged() to find out when the
+ * registerForServiceStateChanged() to find out when the
* request is complete.
*
- * @param power true means "on", false means "off".
+ * @param power true means "on", false means "off".
*/
void setRadioPower(boolean power);
- /**
+ /**
* Get voice message waiting indicator status. No change notification
* available on this interface. Use PhoneStateNotifier or similar instead.
*
@@ -701,8 +743,8 @@ public interface Phone {
void setLine1Number(String alphaTag, String number, Message onComplete);
/**
- * Get the voice mail access phone number. Typically dialed when the
- * user holds the "1" key in the phone app. May return null if not
+ * Get the voice mail access phone number. Typically dialed when the
+ * user holds the "1" key in the phone app. May return null if not
* available or the SIM is not ready.<p>
*/
String getVoiceMailNumber();
@@ -711,8 +753,8 @@ public interface Phone {
* 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>
- *
- * Please use this value instead of some other localized string when
+ *
+ * Please use this value instead of some other localized string when
* showing a name for this number in the UI. For example, call log
* entries should show this alpha tag. <p>
*
@@ -735,29 +777,29 @@ public interface Phone {
/**
* getCallForwardingOptions
- * gets a call forwarding option. The return value of
- * ((AsyncResult)onComplete.obj) is an array of CallForwardInfo.
- *
- * @param commandInterfaceCFReason is one of the valid call forwarding
- * CF_REASONS, as defined in
- * <code>com.android.internal.telephony.gsm.CommandsInterface</code>
+ * gets a call forwarding option. The return value of
+ * ((AsyncResult)onComplete.obj) is an array of CallForwardInfo.
+ *
+ * @param commandInterfaceCFReason is one of the valid call forwarding
+ * CF_REASONS, as defined in
+ * <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.
*/
void getCallForwardingOption(int commandInterfaceCFReason,
Message onComplete);
-
+
/**
* setCallForwardingOptions
* sets a call forwarding option.
- *
- * @param commandInterfaceCFReason is one of the valid call forwarding
- * CF_REASONS, as defined in
- * <code>com.android.internal.telephony.gsm.CommandsInterface</code>
- * @param commandInterfaceCFAction is one of the valid call forwarding
- * CF_ACTIONS, as defined in
- * <code>com.android.internal.telephony.gsm.CommandsInterface</code>
- * @param dialingNumber is the target phone number to forward calls to
+ *
+ * @param commandInterfaceCFReason is one of the valid call forwarding
+ * CF_REASONS, as defined in
+ * <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>
+ * @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.
* @param onComplete a callback message when the action is completed.
@@ -767,83 +809,83 @@ public interface Phone {
String dialingNumber,
int timerSeconds,
Message onComplete);
-
+
/**
* getOutgoingCallerIdDisplay
- * gets outgoing caller id display. The return value of
+ * gets outgoing caller id display. The return value of
* ((AsyncResult)onComplete.obj) is an array of int, with a length of 2.
- *
+ *
* @param onComplete a callback message when the action is completed.
- * @see com.android.internal.telephony.gsm.CommandsInterface.getCLIR for details.
+ * @see com.android.internal.telephony.CommandsInterface.getCLIR for details.
*/
void getOutgoingCallerIdDisplay(Message onComplete);
-
+
/**
* setOutgoingCallerIdDisplay
- * sets a call forwarding option.
- *
- * @param commandInterfaceCLIRMode is one of the valid call CLIR
- * modes, as defined in
- * <code>com.android.internal.telephony.gsm.CommandsInterface</code>
+ * sets a call forwarding option.
+ *
+ * @param commandInterfaceCLIRMode is one of the valid call CLIR
+ * modes, as defined in
+ * <code>com.android.internal.telephony.CommandsInterface./code>
* @param onComplete a callback message when the action is completed.
*/
void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
Message onComplete);
-
+
/**
* getCallWaiting
- * gets call waiting activation state. The return value of
+ * gets call waiting activation state. The return value of
* ((AsyncResult)onComplete.obj) is an array of int, with a length of 1.
- *
+ *
* @param onComplete a callback message when the action is completed.
- * @see com.android.internal.telephony.gsm.CommandsInterface.queryCallWaiting for details.
+ * @see com.android.internal.telephony.CommandsInterface.queryCallWaiting for details.
*/
void getCallWaiting(Message onComplete);
-
+
/**
* setCallWaiting
- * sets a call forwarding option.
- *
- * @param enable is a boolean representing the state that you are
+ * sets a call forwarding 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 setCallWaiting(boolean enable, Message onComplete);
-
+
/**
* Scan available networks. This method is asynchronous; .
* On completion, <code>response.obj</code> is set to an AsyncResult with
* one of the following members:.<p>
*<ul>
- * <li><code>response.obj.result</code> will be a <code>List</code> of
- * <code>com.android.internal.telephony.gsm.NetworkInfo</code> objects, or</li>
- * <li><code>response.obj.exception</code> will be set with an exception
+ * <li><code>response.obj.result</code> will be a <code>List</code> of
+ * <code>com.android.internal.telephony.gsm.NetworkInfo</code> objects, or</li>
+ * <li><code>response.obj.exception</code> will be set with an exception
* on failure.</li>
* </ul>
*/
- void getAvailableNetworks(Message response);
+ void getAvailableNetworks(Message response);
/**
* Switches network selection mode to "automatic", re-scanning and
* re-selecting a network if appropriate.
- *
- * @param response The message to dispatch when the network selection
+ *
+ * @param response The message to dispatch when the network selection
* is complete.
- *
- * @see #selectNetworkManually(com.android.internal.telephony.gsm.NetworkInfo,
+ *
+ * @see #selectNetworkManually(com.android.internal.telephony.gsm.NetworkInfo,
* android.os.Message )
*/
void setNetworkSelectionModeAutomatic(Message response);
/**
- * Manually selects a network. <code>response</code> is
+ * Manually selects a network. <code>response</code> is
* dispatched when this is complete. <code>response.obj</code> will be
* an AsyncResult, and <code>response.obj.exception</code> will be non-null
* on failure.
- *
+ *
* @see #setNetworkSelectionModeAutomatic(Message)
*/
- void selectNetworkManually(NetworkInfo network,
+ void selectNetworkManually(NetworkInfo network,
Message response);
/**
@@ -870,7 +912,7 @@ public interface Phone {
* of available cell IDs. Cell IDs are in hexadecimal format.
*
* @param response callback message that is dispatched when the query
- * completes.
+ * completes.
*/
void getNeighboringCids(Message response);
@@ -883,28 +925,28 @@ public interface Phone {
* <code>AsyncResult</code>. <code>Message.obj.result</code> will be
* a Connection object.<p>
*
- * Message.arg1 will be the post dial character being processed,
+ * Message.arg1 will be the post dial character being processed,
* or 0 ('\0') if end of string.<p>
*
- * If Connection.getPostDialState() == WAIT,
- * the application must call
- * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
- * Connection.proceedAfterWaitChar()} or
- * {@link com.android.internal.telephony.Connection#cancelPostDial()
+ * If Connection.getPostDialState() == WAIT,
+ * the application must call
+ * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
+ * Connection.proceedAfterWaitChar()} or
+ * {@link com.android.internal.telephony.Connection#cancelPostDial()
* Connection.cancelPostDial()}
- * for the telephony system to continue playing the post-dial
+ * for the telephony system to continue playing the post-dial
* DTMF sequence.<p>
*
- * If Connection.getPostDialState() == WILD,
- * the application must call
+ * If Connection.getPostDialState() == WILD,
+ * the application must call
* {@link com.android.internal.telephony.Connection#proceedAfterWildChar
* Connection.proceedAfterWildChar()}
- * or
- * {@link com.android.internal.telephony.Connection#cancelPostDial()
+ * or
+ * {@link com.android.internal.telephony.Connection#cancelPostDial()
* Connection.cancelPostDial()}
- * for the telephony system to continue playing the
+ * for the telephony system to continue playing the
* post-dial DTMF sequence.<p>
- *
+ *
* Only one post dial character handler may be set. <p>
* Calling this method with "h" equal to null unsets this handler.<p>
*/
@@ -912,19 +954,19 @@ public interface Phone {
/**
- * Mutes or unmutes the microphone for the active call. The microphone
- * is automatically unmuted if a call is answered, dialed, or resumed
+ * Mutes or unmutes the microphone for the active call. The microphone
+ * is automatically unmuted if a call is answered, dialed, or resumed
* from a holding state.
- *
- * @param muted true to mute the microphone,
+ *
+ * @param muted true to mute the microphone,
* false to activate the microphone.
*/
void setMute(boolean muted);
/**
- * Gets current mute status. Use
- * {@link #registerForPhoneStateChanged(android.os.Handler, int,
+ * Gets current mute status. Use
+ * {@link #registerForPhoneStateChanged(android.os.Handler, int,
* java.lang.Object) registerForPhoneStateChanged()}
* as a change notifcation, although presently phone state changed is not
* fired when setMute() is called.
@@ -935,12 +977,12 @@ public interface Phone {
/**
* Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation.
- *
+ *
* @param data The data for the request.
- * @param response <strong>On success</strong>,
+ * @param response <strong>On success</strong>,
* (byte[])(((AsyncResult)response.obj).result)
- * <strong>On failure</strong>,
- * (((AsyncResult)response.obj).result) == null and
+ * <strong>On failure</strong>,
+ * (((AsyncResult)response.obj).result) == null and
* (((AsyncResult)response.obj).exception) being an instance of
* com.android.internal.telephony.gsm.CommandException
*
@@ -950,13 +992,13 @@ public interface Phone {
/**
* Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation.
- *
+ *
* @param strings The strings to make available as the request data.
- * @param response <strong>On success</strong>, "response" bytes is
+ * @param response <strong>On success</strong>, "response" bytes is
* made available as:
* (String[])(((AsyncResult)response.obj).result).
- * <strong>On failure</strong>,
- * (((AsyncResult)response.obj).result) == null and
+ * <strong>On failure</strong>,
+ * (((AsyncResult)response.obj).result) == null and
* (((AsyncResult)response.obj).exception) being an instance of
* com.android.internal.telephony.gsm.CommandException
*
@@ -967,6 +1009,7 @@ public interface Phone {
/**
* Get the current active PDP context list
*
+ * @deprecated
* @param response <strong>On success</strong>, "response" bytes is
* made available as:
* (String[])(((AsyncResult)response.obj).result).
@@ -978,13 +1021,34 @@ public interface Phone {
void getPdpContextList(Message response);
/**
+ * Get the current active Data Call list, substitutes getPdpContextList
+ *
+ * @param response <strong>On success</strong>, "response" bytes is
+ * made available as:
+ * (String[])(((AsyncResult)response.obj).result).
+ * <strong>On failure</strong>,
+ * (((AsyncResult)response.obj).result) == null and
+ * (((AsyncResult)response.obj).exception) being an instance of
+ * com.android.internal.telephony.gsm.CommandException
+ */
+ void getDataCallList(Message response);
+
+ /**
* Get current mutiple PDP link status
- *
+ *
+ * @deprecated
* @return list of pdp link connections
*/
List<PdpConnection> getCurrentPdpList ();
/**
+ * Get current mutiple data connection status
+ *
+ * @return list of data connections
+ */
+ List<DataConnection> getCurrentDataConnectionList ();
+
+ /**
* Udpate LAC and CID in service state for currnet GSM netowrk registration
*
* If get different LAC and/or CID, notifyServiceState will be sent
@@ -1008,11 +1072,11 @@ public interface Phone {
void disableLocationUpdates();
/**
- * For unit tests; don't send notifications to "Phone"
+ * For unit tests; don't send notifications to "Phone"
* mailbox registrants if true.
*/
void setUnitTestMode(boolean f);
-
+
/**
* @return true If unit test mode is enabled
*/
@@ -1051,7 +1115,7 @@ public interface Phone {
* @param response is callback message to report one of CDMA_RM_*
*/
void queryCdmaRoamingPreference(Message response);
-
+
/**
* Requests to set the CDMA roaming preference
* @param cdmaRoamingType one of CDMA_RM_*
@@ -1065,10 +1129,10 @@ public interface Phone {
* @param response is callback message
*/
void setCdmaSubscription(int cdmaSubscriptionType, Message response);
-
+
/**
* If this is a simulated phone interface, returns a SimulatedRadioControl.
- * @ return A SimulatedRadioControl if this is a simulated interface;
+ * @ return A SimulatedRadioControl if this is a simulated interface;
* otherwise, null.
*/
SimulatedRadioControl getSimulatedRadioControl();
@@ -1157,7 +1221,7 @@ public interface Phone {
public String[] getDnsServers(String apnType);
/**
- * Retrieves the unique device ID, e.g., IMEI for GSM phones.
+ * Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones.
*/
String getDeviceId();
@@ -1176,9 +1240,9 @@ public interface Phone {
* Retrieves the serial number of the ICC, if applicable.
*/
String getIccSerialNumber();
-
+
//***** CDMA support methods
-
+
/**
* Retrieves the ESN for CDMA phones.
@@ -1189,11 +1253,11 @@ public interface Phone {
* Retrieves MEID for CDMA phones.
*/
String getMeid();
-
+
/**
* Retrieves the PhoneSubInfo of the Phone
*/
- public PhoneSubInfo getPhoneSubInfo();
+ public PhoneSubInfo getPhoneSubInfo();
/**
* Retrieves the IccSmsInterfaceManager of the Phone
@@ -1208,19 +1272,46 @@ public interface Phone {
/**
* setTTYModeEnabled
* sets a TTY mode option.
- *
- * @param enable is a boolean representing the state that you are
+ *
+ * @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 setTTYModeEnabled(boolean enable, Message onComplete);
+
/**
* queryTTYModeEnabled
- * query the status of the TTY mode
- *
+ * query the status of the TTY mode
+ *
* @param onComplete a callback message when the action is completed.
*/
void queryTTYModeEnabled(Message onComplete);
-
+
+ /**
+ * Activate or deactivate cell broadcast SMS.
+ *
+ * @param activate
+ * 0 = activate, 1 = deactivate
+ * @param response
+ * Callback message is empty on completion
+ */
+ void activateCellBroadcastSms(int activate, Message response);
+
+ /**
+ * Query the current configuration of cdma cell broadcast SMS.
+ *
+ * @param response
+ * Callback message is empty on completion
+ */
+ void getCellBroadcastSmsConfig(Message response);
+
+ /**
+ * Configure cell broadcast SMS.
+ *
+ * @param response
+ * Callback message is empty on completion
+ */
+ public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response);
+
+ public void notifyDataActivity();
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 2693e3a946bb..446053ae4de7 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -16,16 +16,6 @@
package com.android.internal.telephony;
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE;
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE;
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL_CONDITIONAL;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncResult;
@@ -39,12 +29,16 @@ import android.telephony.ServiceState;
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.telephony.gsm.PdpConnection;
import com.android.internal.telephony.test.SimulatedRadioControl;
+import java.util.List;
+
+
/**
- * (<em>Not for SDK use</em>)
+ * (<em>Not for SDK use</em>)
* A base implementation for the com.android.internal.telephony.Phone interface.
- *
+ *
* Note that implementations of Phone.java are expected to be used
* from a single application thread. This should be the same thread that
* originally called PhoneFactory to obtain the interface.
@@ -54,13 +48,15 @@ import com.android.internal.telephony.test.SimulatedRadioControl;
*/
public abstract class PhoneBase implements Phone {
- private static final String LOG_TAG = "PhoneBase";
- private static final boolean LOCAL_DEBUG = false;
-
+ private static final String LOG_TAG = "PHONE";
+ private static final boolean LOCAL_DEBUG = true;
+
// Key used to read and write the saved network selection value
public static final String NETWORK_SELECTION_KEY = "network_selection_key";
-
+ // Key used to read/write "disable data connection on boot" pref (used for testing)
+ public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
+
//***** Event Constants
protected static final int EVENT_RADIO_AVAILABLE = 1;
/** Supplementary Service Notification received. */
@@ -77,74 +73,72 @@ public abstract class PhoneBase implements Phone {
protected static final int EVENT_SET_CALL_FORWARD_DONE = 12;
protected static final int EVENT_GET_CALL_FORWARD_DONE = 13;
protected static final int EVENT_CALL_RING = 14;
- // Used to intercept the carrier selection calls so that
+ // Used to intercept the carrier selection calls so that
// we can save the values.
protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE = 15;
protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 16;
protected static final int EVENT_SET_CLIR_COMPLETE = 17;
protected static final int EVENT_REGISTERED_TO_NETWORK = 18;
// Events for CDMA support
- protected static final int EVENT_GET_DEVICE_IDENTITY_DONE = 19;
- protected static final int EVENT_RUIM_RECORDS_LOADED = 3;
- protected static final int EVENT_NV_READY = 20;
+ protected static final int EVENT_GET_DEVICE_IDENTITY_DONE = 19;
+ protected static final int EVENT_RUIM_RECORDS_LOADED = 3;
+ protected static final int EVENT_NV_READY = 20;
protected static final int EVENT_SET_ENHANCED_VP = 21;
-
+
// Key used to read/write current CLIR setting
public static final String CLIR_KEY = "clir_key";
-
- //***** Instance Variables
+
+ //***** Instance Variables
public CommandsInterface mCM;
protected IccFileHandler mIccFileHandler;
- // TODO T: should be protected but GsmMmiCode and DataConnectionTracker still refer to it directly
- public Handler h;
-
+
/**
* Set a system property, unless we're in unit test mode
*/
- protected void
+ public void
setSystemProperty(String property, String value) {
if(getUnitTestMode()) {
return;
}
SystemProperties.set(property, value);
}
-
- protected final RegistrantList mPhoneStateRegistrants
+
+ protected final RegistrantList mPhoneStateRegistrants
= new RegistrantList();
- protected final RegistrantList mNewRingingConnectionRegistrants
+ protected final RegistrantList mNewRingingConnectionRegistrants
= new RegistrantList();
- protected final RegistrantList mIncomingRingRegistrants
+ protected final RegistrantList mIncomingRingRegistrants
= new RegistrantList();
-
- protected final RegistrantList mDisconnectRegistrants
+
+ protected final RegistrantList mDisconnectRegistrants
= new RegistrantList();
- protected final RegistrantList mServiceStateRegistrants
+ protected final RegistrantList mServiceStateRegistrants
= new RegistrantList();
-
- protected final RegistrantList mMmiCompleteRegistrants
+
+ protected final RegistrantList mMmiCompleteRegistrants
= new RegistrantList();
- protected final RegistrantList mMmiRegistrants
+ protected final RegistrantList mMmiRegistrants
= new RegistrantList();
- protected final RegistrantList mUnknownConnectionRegistrants
+ protected final RegistrantList mUnknownConnectionRegistrants
= new RegistrantList();
-
- protected final RegistrantList mSuppServiceFailedRegistrants
+
+ protected final RegistrantList mSuppServiceFailedRegistrants
= new RegistrantList();
-
+
protected Looper mLooper; /* to insure registrants are in correct thread*/
protected Context mContext;
- /**
- * PhoneNotifier is an abstraction for all system-wide
- * state change notification. DefaultPhoneNotifier is
+ /**
+ * PhoneNotifier is an abstraction for all system-wide
+ * state change notification. DefaultPhoneNotifier is
* used here unless running we're inside a unit test.
*/
protected PhoneNotifier mNotifier;
@@ -157,7 +151,7 @@ public abstract class PhoneBase implements Phone {
* Constructs a PhoneBase in normal (non-unit test) mode.
*
* @param context Context object from hosting application
- * @param notifier An instance of DefaultPhoneNotifier,
+ * @param notifier An instance of DefaultPhoneNotifier,
* unless unit testing.
*/
protected PhoneBase(PhoneNotifier notifier, Context context) {
@@ -168,13 +162,13 @@ public abstract class PhoneBase implements Phone {
* Constructs a PhoneBase in normal (non-unit test) mode.
*
* @param context Context object from hosting application
- * @param notifier An instance of DefaultPhoneNotifier,
+ * @param notifier An instance of DefaultPhoneNotifier,
* unless unit testing.
- * @param unitTestMode when true, prevents notifications
+ * @param unitTestMode when true, prevents notifications
* of state change events
*/
- protected PhoneBase(PhoneNotifier notifier, Context context,
- boolean unitTestMode) {
+ protected PhoneBase(PhoneNotifier notifier, Context context,
+ boolean unitTestMode) {
this.mNotifier = notifier;
this.mContext = context;
mLooper = Looper.myLooper();
@@ -198,29 +192,29 @@ public abstract class PhoneBase implements Phone {
public void unregisterForPhoneStateChanged(Handler h) {
mPhoneStateRegistrants.remove(h);
}
-
+
/**
* Notify registrants of a PhoneStateChanged.
- * Subclasses of Phone probably want to replace this with a
+ * Subclasses of Phone probably want to replace this with a
* version scoped to their packages
*/
protected void notifyCallStateChangedP() {
AsyncResult ar = new AsyncResult(null, this, null);
mPhoneStateRegistrants.notifyRegistrants(ar);
}
-
+
// Inherited documentation suffices.
public void registerForUnknownConnection(Handler h, int what, Object obj) {
checkCorrectThread(h);
-
+
mUnknownConnectionRegistrants.addUnique(h, what, obj);
}
-
+
// Inherited documentation suffices.
public void unregisterForUnknownConnection(Handler h) {
mUnknownConnectionRegistrants.remove(h);
}
-
+
// Inherited documentation suffices.
public void registerForNewRingingConnection(
Handler h, int what, Object obj) {
@@ -234,12 +228,33 @@ public abstract class PhoneBase implements Phone {
mNewRingingConnectionRegistrants.remove(h);
}
+ // Inherited documentation suffices.
+ public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
+ mCM.registerForInCallVoicePrivacyOn(h,what,obj);
+ }
+
+ // Inherited documentation suffices.
+ public void unregisterForInCallVoicePrivacyOn(Handler h){
+ mCM.unregisterForInCallVoicePrivacyOn(h);
+ }
+
+ // Inherited documentation suffices.
+ public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
+ mCM.registerForInCallVoicePrivacyOff(h,what,obj);
+ }
+
+ // Inherited documentation suffices.
+ public void unregisterForInCallVoicePrivacyOff(Handler h){
+ mCM.unregisterForInCallVoicePrivacyOff(h);
+ }
+
+
/**
* Notifiy registrants of a new ringing Connection.
- * Subclasses of Phone probably want to replace this with a
+ * Subclasses of Phone probably want to replace this with a
* version scoped to their packages
*/
- protected void notifyNewRingingConnectionP(Connection cn) {
+ protected void notifyNewRingingConnectionP(Connection cn) {
AsyncResult ar = new AsyncResult(null, cn, null);
mNewRingingConnectionRegistrants.notifyRegistrants(ar);
}
@@ -248,15 +263,15 @@ public abstract class PhoneBase implements Phone {
public void registerForIncomingRing(
Handler h, int what, Object obj) {
checkCorrectThread(h);
-
+
mIncomingRingRegistrants.addUnique(h, what, obj);
}
-
+
// Inherited documentation suffices.
public void unregisterForIncomingRing(Handler h) {
mIncomingRingRegistrants.remove(h);
}
-
+
// Inherited documentation suffices.
public void registerForDisconnect(Handler h, int what, Object obj) {
checkCorrectThread(h);
@@ -272,15 +287,15 @@ public abstract class PhoneBase implements Phone {
// Inherited documentation suffices.
public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
checkCorrectThread(h);
-
+
mSuppServiceFailedRegistrants.addUnique(h, what, obj);
}
-
+
// Inherited documentation suffices.
public void unregisterForSuppServiceFailed(Handler h) {
mSuppServiceFailedRegistrants.remove(h);
}
-
+
// Inherited documentation suffices.
public void registerForMmiInitiate(Handler h, int what, Object obj) {
checkCorrectThread(h);
@@ -292,7 +307,7 @@ public abstract class PhoneBase implements Phone {
public void unregisterForMmiInitiate(Handler h) {
mMmiRegistrants.remove(h);
}
-
+
// Inherited documentation suffices.
public void registerForMmiComplete(Handler h, int what, Object obj) {
checkCorrectThread(h);
@@ -311,7 +326,7 @@ public abstract class PhoneBase implements Phone {
* Method to retrieve the saved operator id from the Shared Preferences
*/
private String getSavedNetworkSelection() {
- // open the shared preferences and search with our key.
+ // open the shared preferences and search with our key.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
return sp.getString(NETWORK_SELECTION_KEY, "");
}
@@ -324,7 +339,7 @@ public abstract class PhoneBase implements Phone {
public void restoreSavedNetworkSelection(Message response) {
// retrieve the operator id
String networkSelection = getSavedNetworkSelection();
-
+
// set to auto if the id is empty, otherwise select the network.
if (TextUtils.isEmpty(networkSelection)) {
mCM.setNetworkSelectionModeAutomatic(response);
@@ -333,10 +348,6 @@ public abstract class PhoneBase implements Phone {
}
}
-
- /**
- * Subclasses should override this. See documentation in superclass.
- */
// Inherited documentation suffices.
public void setUnitTestMode(boolean f) {
mUnitTestMode = f;
@@ -346,11 +357,11 @@ public abstract class PhoneBase implements Phone {
public boolean getUnitTestMode() {
return mUnitTestMode;
}
-
+
/**
* To be invoked when a voice call Connection disconnects.
*
- * Subclasses of Phone probably want to replace this with a
+ * Subclasses of Phone probably want to replace this with a
* version scoped to their packages
*/
protected void notifyDisconnectP(Connection cn) {
@@ -372,7 +383,7 @@ public abstract class PhoneBase implements Phone {
}
/**
- * Subclasses of Phone probably want to replace this with a
+ * Subclasses of Phone probably want to replace this with a
* version scoped to their packages
*/
protected void notifyServiceStateChangedP(ServiceState ss) {
@@ -398,42 +409,42 @@ public abstract class PhoneBase implements Phone {
private void checkCorrectThread(Handler h) {
if (h.getLooper() != mLooper) {
throw new RuntimeException(
- "com.android.internal.telephony.Phone must be used from within one thread");
+ "com.android.internal.telephony.Phone must be used from within one thread");
}
}
/**
* Retrieves the Handler of the Phone instance
- */
- protected abstract Handler getHandler();
+ */
+ public abstract Handler getHandler();
/**
* Retrieves the IccFileHandler of the Phone instance
- */
- protected abstract IccFileHandler getIccFileHandler();
+ */
+ public abstract IccFileHandler getIccFileHandler();
+
-
/**
* Query the status of the CDMA roaming preference
*/
public void queryCdmaRoamingPreference(Message response) {
mCM.queryCdmaRoamingPreference(response);
}
-
+
/**
* Set the status of the CDMA roaming preference
*/
public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
mCM.setCdmaRoamingPreference(cdmaRoamingType, response);
}
-
+
/**
* Set the status of the CDMA subscription mode
*/
public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
mCM.setCdmaSubscription(cdmaSubscriptionType, response);
}
-
+
/**
* Set the preferred Network Type: Global, CDMA only or GSM/UMTS only
*/
@@ -447,134 +458,61 @@ public abstract class PhoneBase implements Phone {
public void getPreferredNetworkType(Message response) {
mCM.getPreferredNetworkType(response);
}
-
+
public void setTTYModeEnabled(boolean enable, Message onComplete) {
- // This function should be overridden by the class CDMAPhone.
- // It is not implemented in the class GSMPhone.
- Log.e(LOG_TAG, "Error! This function should never be executed, because we have an " +
- "inactive CDMAPhone then.");
+ // 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) {
- // This function should be overridden by the class CDMAPhone.
- // It is not implemented in the class GSMPhone.
- Log.e(LOG_TAG, "Error! This function should never be executed, because we have an " +
- "inactive CDMAPhone then.");
- }
-
- // TODO: might not be used in CDMA any longer, move this to GSMPhone
- protected boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) {
- switch (commandInterfaceCFReason) {
- case CF_REASON_UNCONDITIONAL:
- case CF_REASON_BUSY:
- case CF_REASON_NO_REPLY:
- case CF_REASON_NOT_REACHABLE:
- case CF_REASON_ALL:
- case CF_REASON_ALL_CONDITIONAL:
- return true;
- default:
- return false;
- }
+ // 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.");
}
- // TODO: might not be used in CDMA any longer, move this to GSMPhone
- protected boolean isValidCommandInterfaceCFAction (int commandInterfaceCFAction) {
- switch (commandInterfaceCFAction) {
- case CF_ACTION_DISABLE:
- case CF_ACTION_ENABLE:
- case CF_ACTION_REGISTRATION:
- case CF_ACTION_ERASURE:
- return true;
- default:
- return false;
- }
+ /**
+ * This should only be called in GSM mode.
+ * Only here for some backward compatibility
+ * issues concerning the GSMPhone class.
+ * @deprecated
+ */
+ public List<PdpConnection> getCurrentPdpList() {
+ return null;
}
- // TODO: might not be used in CDMA any longer, move this to GSMPhone
- protected boolean isCfEnable(int action) {
- return (action == CF_ACTION_ENABLE) || (action == CF_ACTION_REGISTRATION);
+ public void enableEnhancedVoicePrivacy(boolean enable, 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.");
}
-
- /**
- * Make sure the network knows our preferred setting.
- */
- // TODO: might not be used in CDMA any longer, move this to GSMPhone
- protected void syncClirSetting() {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- int clirSetting = sp.getInt(CLIR_KEY, -1);
- if (clirSetting >= 0) {
- mCM.setCLIR(clirSetting, null);
- }
+
+ public void getEnhancedVoicePrivacy(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.");
}
- // TODO: might not be used in CDMA any longer, move this to GSMPhone
- public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
- if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG, "requesting call forwarding query.");
- Message resp;
- if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) {
- resp = h.obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete);
- } else {
- resp = onComplete;
- }
- mCM.queryCallForwardStatus(commandInterfaceCFReason,0,null,resp);
- }
+ public void setBandMode(int bandMode, Message response) {
+ mCM.setBandMode(bandMode, response);
}
-
- /**
- * Saves CLIR setting so that we can re-apply it as necessary
- * (in case the RIL resets it across reboots).
- */
- // TODO: might not be used in CDMA any longer, move this to GSMPhone
- public void saveClirSetting(int commandInterfaceCLIRMode) {
- // open the shared preferences editor, and write the value.
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- SharedPreferences.Editor editor = sp.edit();
- editor.putInt(CLIR_KEY, commandInterfaceCLIRMode);
-
- // commit and log the result.
- if (! editor.commit()) {
- Log.e(LOG_TAG, "failed to commit CLIR preference");
- }
+
+ public void queryAvailableBandMode(Message response) {
+ mCM.queryAvailableBandMode(response);
}
-
- // TODO: might not be used in CDMA any longer, move this to GSMPhone
- public void setCallForwardingOption(int commandInterfaceCFAction,
- int commandInterfaceCFReason,
- String dialingNumber,
- int timerSeconds,
- Message onComplete) {
- if ((isValidCommandInterfaceCFAction(commandInterfaceCFAction)) &&
- (isValidCommandInterfaceCFReason(commandInterfaceCFReason))) {
-
- Message resp;
- if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) {
- resp = h.obtainMessage(EVENT_SET_CALL_FORWARD_DONE,
- isCfEnable(commandInterfaceCFAction) ? 1 : 0, 0, onComplete);
- } else {
- resp = onComplete;
- }
- mCM.setCallForward(commandInterfaceCFAction,
- commandInterfaceCFReason,
- CommandsInterface.SERVICE_CLASS_VOICE,
- dialingNumber,
- timerSeconds,
- resp);
- }
- }
-
- public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
- // This function should be overridden by the class CDMAPhone.
- // It is not implemented in the class GSMPhone.
- Log.e(LOG_TAG, "Error! This function should never be executed, because we have an" +
- "inactive CDMAPhone then.");
+
+ public void invokeOemRilRequestRaw(byte[] data, Message response) {
+ mCM.invokeOemRilRequestRaw(data, response);
}
- public void getEnhancedVoicePrivacy(Message onComplete) {
- // This function should be overridden by the class CDMAPhone.
- // It is not implemented in the class GSMPhone.
- Log.e(LOG_TAG, "Error! This function should never be executed, because we have an " +
- "inactive CDMAPhone then.");
+ public void invokeOemRilRequestStrings(String[] strings, Message response) {
+ mCM.invokeOemRilRequestStrings(strings, response);
}
+ public void notifyDataActivity() {
+ mNotifier.notifyDataActivity(this);
+ }
+
+ public void notifyDataConnection(String reason) {
+ mNotifier.notifyDataConnection(this, reason);
+ }
+
+ public abstract String getPhoneName();
+
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java
index 9a123a41f734..b094478fb57c 100644
--- a/telephony/java/com/android/internal/telephony/PhoneFactory.java
+++ b/telephony/java/com/android/internal/telephony/PhoneFactory.java
@@ -16,27 +16,14 @@
package com.android.internal.telephony;
-import java.util.ArrayList;
-import java.util.List;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-
-import java.util.Collections;
-
-import android.util.Log;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.cdma.CDMAPhone;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.test.SimulatedCommands;
-
-import android.os.Looper;
-import android.os.SystemProperties;
import android.content.Context;
-import android.content.Intent;
import android.net.LocalServerSocket;
-import android.app.ActivityManagerNative;
+import android.os.Looper;
import android.provider.Settings;
-import android.telephony.cdma.TtyIntent;
+import android.util.Log;
+
+import com.android.internal.telephony.cdma.CDMAPhone;
+import com.android.internal.telephony.gsm.GSMPhone;
/**
* {@hide}
@@ -45,35 +32,19 @@ public class PhoneFactory {
static final String LOG_TAG = "PhoneFactory";
static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000;
static final int SOCKET_OPEN_MAX_RETRY = 3;
- //***** Class Variables
+ //***** Class Variables
- static private Phone sPhone = null;
+ static private Phone sProxyPhone = null;
static private CommandsInterface sCommandsInterface = null;
static private boolean sMadeDefaults = false;
static private PhoneNotifier sPhoneNotifier;
static private Looper sLooper;
+ static private Context sContext;
-/* public static final int NETWORK_MODE_GLOBAL = 0;
- public static final int NETWORK_MODE_CDMA = 1;
- public static final int NETWORK_MODE_GSM_UMTS = 2;
-
- public static final int SUBSCRIPTION_FROM_RUIM = 0;
- public static final int SUBSCRIPTION_FROM_NV = 1;*/ //TODO Remove, moved to RILConstants
+ static final int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
- //preferredNetworkMode 7 - Global, CDMA Preferred
- // 4 - CDMA only
- // 3 - GSM/UMTS only
- static final int preferredNetworkMode = RILConstants.NETWORK_MODE_GLOBAL;
-
- //cdmaSubscription 0 - Subscription from RUIM, when available
- // 1 - Subscription from NV
- static final int preferredCdmaSubscription = RILConstants.SUBSCRIPTION_FROM_RUIM;
-
- // preferred TTY mode
- // 0 = disabled
- // 1 = enabled
- static final int preferredTTYMode = RILConstants.CDM_TTY_MODE_DISABLED;
+ static final int preferredCdmaSubscription = RILConstants.PREFERRED_CDMA_SUBSCRIPTION;
//***** Class Methods
@@ -86,9 +57,10 @@ public class PhoneFactory {
* instances
*/
public static void makeDefaultPhone(Context context) {
- synchronized(Phone.class) {
- if (!sMadeDefaults) {
+ synchronized(Phone.class) {
+ if (!sMadeDefaults) {
sLooper = Looper.myLooper();
+ sContext = context;
if (sLooper == null) {
throw new RuntimeException(
@@ -112,7 +84,7 @@ public class PhoneFactory {
break;
} else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
throw new RuntimeException("PhoneFactory probably already running");
- }else {
+ } else {
try {
Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
} catch (InterruptedException er) {
@@ -129,28 +101,32 @@ public class PhoneFactory {
//Get preferredNetworkMode from Settings.System
int cdmaSubscription = Settings.System.getInt(context.getContentResolver(),
- Settings.System.PREFERRED_CDMA_SUBSCRIPTION, preferredCdmaSubscription);
+ Settings.System.PREFERRED_CDMA_SUBSCRIPTION, preferredCdmaSubscription);
Log.i(LOG_TAG, "Cdma Subscription set to " + Integer.toString(cdmaSubscription));
- //reads the system proprieties and makes commandsinterface
- sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
+ //reads the system properties and makes commandsinterface
+ sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
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:
- sPhone = new PhoneProxy(new GSMPhone(context,
+ sProxyPhone = new PhoneProxy(new GSMPhone(context,
sCommandsInterface, sPhoneNotifier));
Log.i(LOG_TAG, "Creating GSMPhone");
break;
- case RILConstants.NETWORK_MODE_GLOBAL:
case RILConstants.NETWORK_MODE_CDMA:
+ case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
+ case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
+ sProxyPhone = new PhoneProxy(new CDMAPhone(context,
+ sCommandsInterface, sPhoneNotifier));
+ Log.i(LOG_TAG, "Creating CDMAPhone");
+ break;
+ case RILConstants.NETWORK_MODE_GLOBAL:
default:
- sPhone = new PhoneProxy(new CDMAPhone(context,
+ sProxyPhone = new PhoneProxy(new CDMAPhone(context,
sCommandsInterface, sPhoneNotifier));
- // Check if the TTY mode is enabled, and enable/disable the icon
- int enabled =
- android.provider.Settings.System.getInt(context.getContentResolver(),
- android.provider.Settings.System.TTY_MODE_ENABLED, preferredTTYMode);
- setTTYStatusBarIcon(context, ((enabled != 0) ? true : false));
Log.i(LOG_TAG, "Creating CDMAPhone");
}
sMadeDefaults = true;
@@ -163,22 +139,26 @@ public class PhoneFactory {
throw new RuntimeException(
"PhoneFactory.getDefaultPhone must be called from Looper thread");
}
-
+
if (!sMadeDefaults) {
throw new IllegalStateException("Default phones haven't been made yet!");
}
- return sPhone;
+ return sProxyPhone;
}
- /**
- * Tells the StatusBar whether the TTY mode is enabled or disabled
- */
- private static void setTTYStatusBarIcon(Context context, boolean enabled) {
- Intent ttyModeChanged = new Intent(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
- ttyModeChanged.putExtra("ttyEnabled", enabled);
- context.sendBroadcast(ttyModeChanged);
+ public static Phone getCdmaPhone() {
+ synchronized(PhoneProxy.lockForRadioTechnologyChange) {
+ Phone phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
+ return phone;
+ }
+ }
+
+ public static Phone getGsmPhone() {
+ synchronized(PhoneProxy.lockForRadioTechnologyChange) {
+ Phone phone = new GSMPhone(sContext, sCommandsInterface, sPhoneNotifier);
+ return phone;
+ }
}
-
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index e86294b44e60..9ddedddeb6e7 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,58 +13,145 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+
package com.android.internal.telephony;
-/*
-import android.util.Log;
-import com.android.internal.telephony.test.ModelInterpreter;
-import com.android.internal.telephony.test.SimulatedCommands;
-import android.os.Looper;
-import android.os.SystemProperties;
+
+import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.Intent;
-import android.net.LocalServerSocket;
-import android.app.ActivityManagerNative;
-*/
-import android.content.*;
-import android.os.*;
+import android.os.Handler;
+import android.os.Message;
+import android.telephony.CellLocation;
+import android.telephony.ServiceState;
+import android.util.Log;
-import com.android.internal.telephony.*;
-import com.android.internal.telephony.test.SimulatedRadioControl;
+import com.android.internal.telephony.cdma.CDMAPhone;
+import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.gsm.NetworkInfo;
import com.android.internal.telephony.gsm.PdpConnection;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.cdma.CDMAPhone;
-import android.telephony.CellLocation;
-import android.telephony.ServiceState;
+import com.android.internal.telephony.test.SimulatedRadioControl;
-/*
-import java.util.ArrayList;
import java.util.List;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.Collections;
-*/
-import java.util.*;
-public class PhoneProxy implements Phone {
+public class PhoneProxy extends Handler implements Phone{
+ public final static Object lockForRadioTechnologyChange = new Object();
+// private static boolean radioTechnologyChangeGsmToCdma = false;
+// private static boolean radioTechnologyChangeCdmaToGsm = false;
+
private Phone mActivePhone;
- private Phone mCdmaPhone;
- private Phone mGsmPhone;
+ private String mOutgoingPhone;
+ private CommandsInterface mCommandsInterface;
private IccSmsInterfaceManagerProxy mIccSmsInterfaceManagerProxy;
private IccPhoneBookInterfaceManagerProxy mIccPhoneBookInterfaceManagerProxy;
private PhoneSubInfoProxy mPhoneSubInfoProxy;
+ private static final int EVENT_RADIO_TECHNOLOGY_CHANGED = 1;
+ private static final String LOG_TAG = "PHONE";
+
//***** Class Methods
public PhoneProxy(Phone phone) {
mActivePhone = phone;
- mIccSmsInterfaceManagerProxy = new IccSmsInterfaceManagerProxy(phone.getIccSmsInterfaceManager());
- mIccPhoneBookInterfaceManagerProxy =
- new IccPhoneBookInterfaceManagerProxy(phone.getIccPhoneBookInterfaceManager());
+ mIccSmsInterfaceManagerProxy = new IccSmsInterfaceManagerProxy(
+ phone.getIccSmsInterfaceManager());
+ mIccPhoneBookInterfaceManagerProxy = new IccPhoneBookInterfaceManagerProxy(
+ phone.getIccPhoneBookInterfaceManager());
mPhoneSubInfoProxy = new PhoneSubInfoProxy(phone.getPhoneSubInfo());
+ mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
+ mCommandsInterface.registerForRadioTechnologyChanged(
+ this, EVENT_RADIO_TECHNOLOGY_CHANGED, null);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ case EVENT_RADIO_TECHNOLOGY_CHANGED:
+ //switch Phone from CDMA to GSM or vice versa
+ mOutgoingPhone = ((PhoneBase)mActivePhone).getPhoneName();
+ logd("Switching phone from " + mOutgoingPhone + "Phone to " +
+ (mOutgoingPhone.equals("GSM") ? "CDMAPhone" : "GSMPhone") );
+ boolean oldPowerState = false; //old power state to off
+ if (mCommandsInterface.getRadioState().isOn()) {
+ oldPowerState = true;
+ logd("Setting Radio Power to Off");
+ mCommandsInterface.setRadioPower(false, null);
+ }
+ if(mOutgoingPhone.equals("GSM")) {
+ logd("Make a new CDMAPhone and destroy the old GSMPhone.");
+
+ ((GSMPhone)mActivePhone).dispose();
+ Phone oldPhone = mActivePhone;
+
+ //Give the garbage collector a hint to start the garbage collection asap
+ // NOTE this has been disabled since radio technology change could happen during
+ // e.g. a multimedia playing and could slow the system. Tests needs to be done
+ // to see the effects of the GC call here when system is busy.
+ //System.gc();
+
+ mActivePhone = PhoneFactory.getCdmaPhone();
+ logd("Resetting Radio");
+ mCommandsInterface.setRadioPower(oldPowerState, null);
+ ((GSMPhone)oldPhone).removeReferences();
+ oldPhone = null;
+ } else {
+ logd("Make a new GSMPhone and destroy the old CDMAPhone.");
+
+ ((CDMAPhone)mActivePhone).dispose();
+ //mActivePhone = null;
+ Phone oldPhone = mActivePhone;
+
+ // Give the GC a hint to start the garbage collection asap
+ // NOTE this has been disabled since radio technology change could happen during
+ // e.g. a multimedia playing and could slow the system. Tests needs to be done
+ // to see the effects of the GC call here when system is busy.
+ //System.gc();
+
+ mActivePhone = PhoneFactory.getGsmPhone();
+ logd("Resetting Radio:");
+ mCommandsInterface.setRadioPower(oldPowerState, null);
+ ((CDMAPhone)oldPhone).removeReferences();
+ oldPhone = null;
+ }
+
+ //Set the new interfaces in the proxy's
+ mIccSmsInterfaceManagerProxy.setmIccSmsInterfaceManager(
+ mActivePhone.getIccSmsInterfaceManager());
+ mIccPhoneBookInterfaceManagerProxy.setmIccPhoneBookInterfaceManager(
+ mActivePhone.getIccPhoneBookInterfaceManager());
+ mPhoneSubInfoProxy.setmPhoneSubInfo(this.mActivePhone.getPhoneSubInfo());
+ mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
+
+ //Send an Intent to the PhoneApp that we had a radio technology change
+ 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: "
+ + msg.what);
+ break;
+ }
+ super.handleMessage(msg);
+ }
+
+ private void logv(String msg) {
+ Log.v(LOG_TAG, "[PhoneProxy] " + msg);
+ }
+
+ private void logd(String msg) {
+ Log.d(LOG_TAG, "[PhoneProxy] " + msg);
+ }
+
+ private void logw(String msg) {
+ Log.w(LOG_TAG, "[PhoneProxy] " + msg);
+ }
+
+ private void loge(String msg) {
+ Log.e(LOG_TAG, "[PhoneProxy] " + msg);
}
+
public ServiceState getServiceState() {
return mActivePhone.getServiceState();
}
@@ -74,18 +161,18 @@ public class PhoneProxy implements Phone {
}
public DataState getDataConnectionState() {
- return mActivePhone.getDataConnectionState();
+ return mActivePhone.getDataConnectionState();
}
- public DataActivityState getDataActivityState() {
- return mActivePhone.getDataActivityState();
+ public DataActivityState getDataActivityState() {
+ return mActivePhone.getDataActivityState();
}
public Context getContext() {
- return mActivePhone.getContext();
+ return mActivePhone.getContext();
}
- public State getState() {
+ public State getState() {
return mActivePhone.getState();
}
@@ -93,55 +180,55 @@ public class PhoneProxy implements Phone {
return mActivePhone.getPhoneName();
}
- public String[] getActiveApnTypes() {
- return mActivePhone.getActiveApnTypes();
+ public String[] getActiveApnTypes() {
+ return mActivePhone.getActiveApnTypes();
}
- public String getActiveApn() {
- return mActivePhone.getActiveApn();
+ public String getActiveApn() {
+ return mActivePhone.getActiveApn();
}
- public int getSignalStrengthASU() {
+ public int getSignalStrengthASU() {
return mActivePhone.getSignalStrengthASU();
}
- public void registerForUnknownConnection(Handler h, int what, Object obj) {
+ public void registerForUnknownConnection(Handler h, int what, Object obj) {
mActivePhone.registerForUnknownConnection(h, what, obj);
}
- public void unregisterForUnknownConnection(Handler h) {
+ public void unregisterForUnknownConnection(Handler h) {
mActivePhone.unregisterForUnknownConnection(h);
}
- public void registerForPhoneStateChanged(Handler h, int what, Object obj) {
+ public void registerForPhoneStateChanged(Handler h, int what, Object obj) {
mActivePhone.registerForPhoneStateChanged(h, what, obj);
}
- public void unregisterForPhoneStateChanged(Handler h) {
+ public void unregisterForPhoneStateChanged(Handler h) {
mActivePhone.unregisterForPhoneStateChanged(h);
}
- public void registerForNewRingingConnection(Handler h, int what, Object obj) {
+ public void registerForNewRingingConnection(Handler h, int what, Object obj) {
mActivePhone.registerForNewRingingConnection(h, what, obj);
}
- public void unregisterForNewRingingConnection(Handler h) {
+ public void unregisterForNewRingingConnection(Handler h) {
mActivePhone.unregisterForNewRingingConnection(h);
}
- public void registerForIncomingRing(Handler h, int what, Object obj) {
+ public void registerForIncomingRing(Handler h, int what, Object obj) {
mActivePhone.registerForIncomingRing(h, what, obj);
}
- public void unregisterForIncomingRing(Handler h) {
+ public void unregisterForIncomingRing(Handler h) {
mActivePhone.unregisterForIncomingRing(h);
}
- public void registerForDisconnect(Handler h, int what, Object obj) {
+ public void registerForDisconnect(Handler h, int what, Object obj) {
mActivePhone.registerForDisconnect(h, what, obj);
}
- public void unregisterForDisconnect(Handler h) {
+ public void unregisterForDisconnect(Handler h) {
mActivePhone.unregisterForDisconnect(h);
}
@@ -193,23 +280,39 @@ public class PhoneProxy implements Phone {
mActivePhone.unregisterForSuppServiceFailed(h);
}
- public boolean getSimRecordsLoaded() {
- return mActivePhone.getSimRecordsLoaded();
+ public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
+ mActivePhone.registerForInCallVoicePrivacyOn(h,what,obj);
+ }
+
+ public void unregisterForInCallVoicePrivacyOn(Handler h){
+ mActivePhone.unregisterForInCallVoicePrivacyOn(h);
+ }
+
+ public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
+ mActivePhone.registerForInCallVoicePrivacyOff(h,what,obj);
+ }
+
+ public void unregisterForInCallVoicePrivacyOff(Handler h){
+ mActivePhone.unregisterForInCallVoicePrivacyOff(h);
+ }
+
+ public boolean getIccRecordsLoaded() {
+ return mActivePhone.getIccRecordsLoaded();
}
public IccCard getIccCard() {
return mActivePhone.getIccCard();
}
- public void acceptCall() throws CallStateException {
+ public void acceptCall() throws CallStateException {
mActivePhone.acceptCall();
}
- public void rejectCall() throws CallStateException {
+ public void rejectCall() throws CallStateException {
mActivePhone.rejectCall();
}
- public void switchHoldingAndActive() throws CallStateException {
+ public void switchHoldingAndActive() throws CallStateException {
mActivePhone.switchHoldingAndActive();
}
@@ -217,7 +320,7 @@ public class PhoneProxy implements Phone {
return mActivePhone.canConference();
}
- public void conference() throws CallStateException {
+ public void conference() throws CallStateException {
mActivePhone.conference();
}
@@ -233,7 +336,7 @@ public class PhoneProxy implements Phone {
return mActivePhone.canTransfer();
}
- public void explicitCallTransfer() throws CallStateException {
+ public void explicitCallTransfer() throws CallStateException {
mActivePhone.explicitCallTransfer();
}
@@ -253,7 +356,7 @@ public class PhoneProxy implements Phone {
return mActivePhone.getRingingCall();
}
- public Connection dial(String dialString) throws CallStateException {
+ public Connection dial(String dialString) throws CallStateException {
return mActivePhone.dial(dialString);
}
@@ -261,7 +364,7 @@ public class PhoneProxy implements Phone {
return mActivePhone.handlePinMmi(dialString);
}
- public boolean handleInCallMmiCommands(String command) throws CallStateException {
+ public boolean handleInCallMmiCommands(String command) throws CallStateException {
return mActivePhone.handleInCallMmiCommands(command);
}
@@ -297,7 +400,7 @@ public class PhoneProxy implements Phone {
return mActivePhone.getLine1AlphaTag();
}
- public void setLine1Number(String alphaTag, String number, Message onComplete) {
+ public void setLine1Number(String alphaTag, String number, Message onComplete) {
mActivePhone.setLine1Number(alphaTag, number, onComplete);
}
@@ -316,7 +419,7 @@ public class PhoneProxy implements Phone {
public void getCallForwardingOption(int commandInterfaceCFReason,
Message onComplete) {
- mActivePhone.getCallForwardingOption(commandInterfaceCFReason,
+ mActivePhone.getCallForwardingOption(commandInterfaceCFReason,
onComplete);
}
@@ -331,7 +434,7 @@ public class PhoneProxy implements Phone {
mActivePhone.getOutgoingCallerIdDisplay(onComplete);
}
- public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
+ public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
Message onComplete) {
mActivePhone.setOutgoingCallerIdDisplay(commandInterfaceCLIRMode,
onComplete);
@@ -347,7 +450,7 @@ public class PhoneProxy implements Phone {
public void getAvailableNetworks(Message response) {
mActivePhone.getAvailableNetworks(response);
- }
+ }
public void setNetworkSelectionModeAutomatic(Message response) {
mActivePhone.setNetworkSelectionModeAutomatic(response);
@@ -362,7 +465,7 @@ public class PhoneProxy implements Phone {
}
public void getPreferredNetworkType(Message response) {
- mActivePhone.getPreferredNetworkType(response) ;
+ mActivePhone.getPreferredNetworkType(response);
}
public void getNeighboringCids(Message response) {
@@ -389,12 +492,26 @@ public class PhoneProxy implements Phone {
mActivePhone.invokeOemRilRequestStrings(strings, response);
}
+ /**
+ * @deprecated
+ */
public void getPdpContextList(Message response) {
mActivePhone.getPdpContextList(response);
}
- public List<PdpConnection> getCurrentPdpList () {
- return mActivePhone.getCurrentPdpList ();
+ public void getDataCallList(Message response) {
+ mActivePhone.getDataCallList(response);
+ }
+
+ /**
+ * @deprecated
+ */
+ public List<PdpConnection> getCurrentPdpList() {
+ return mActivePhone.getCurrentPdpList();
+ }
+
+ public List<DataConnection> getCurrentDataConnectionList() {
+ return mActivePhone.getCurrentDataConnectionList();
}
public void updateServiceLocation(Message response) {
@@ -436,11 +553,11 @@ public class PhoneProxy implements Phone {
public void queryCdmaRoamingPreference(Message response) {
mActivePhone.queryCdmaRoamingPreference(response);
}
-
+
public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
mActivePhone.setCdmaRoamingPreference(cdmaRoamingType, response);
}
-
+
public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
mActivePhone.setCdmaSubscription(cdmaSubscriptionType, response);
}
@@ -510,25 +627,39 @@ public class PhoneProxy implements Phone {
}
public PhoneSubInfo getPhoneSubInfo(){
- return null; //mActivePhone.getPhoneSubInfo();
+ return mActivePhone.getPhoneSubInfo();
}
-
public IccSmsInterfaceManager getIccSmsInterfaceManager(){
- return null; //mActivePhone.getIccSmsInterfaceManager();
+ return mActivePhone.getIccSmsInterfaceManager();
}
-
public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
- return null; //mActivePhone.getIccPhoneBookInterfaceManager();
+ return mActivePhone.getIccPhoneBookInterfaceManager();
}
public void setTTYModeEnabled(boolean enable, Message onComplete) {
mActivePhone.setTTYModeEnabled(enable, onComplete);
}
-
+
public void queryTTYModeEnabled(Message onComplete) {
mActivePhone.queryTTYModeEnabled(onComplete);
}
+
+ public void activateCellBroadcastSms(int activate, Message response) {
+ mActivePhone.activateCellBroadcastSms(activate, response);
+ }
+
+ public void getCellBroadcastSmsConfig(Message response) {
+ mActivePhone.getCellBroadcastSmsConfig(response);
+ }
+
+ public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) {
+ mActivePhone.setCellBroadcastSmsConfig(configValuesArray, response);
+ }
+
+ public void notifyDataActivity() {
+ mActivePhone.notifyDataActivity();
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
index c558cd15f1d1..468a1f67e2f5 100644
--- a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
+++ b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
@@ -32,7 +32,7 @@ import android.telephony.ServiceState;
*
* Use android.telephony.TelephonyManager and PhoneStateListener instead.
*
- *
+ *
*/
@Deprecated
public final class PhoneStateIntentReceiver extends BroadcastReceiver {
@@ -184,7 +184,7 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver {
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);
-
+
if (mTarget != null && getNotifySignalStrength()) {
Message message = Message.obtain(mTarget, mAsuEventWhat);
mTarget.sendMessage(message);
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
index 01f34426e747..4d1f7e5f1331 100644
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
+++ b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
@@ -16,9 +16,10 @@
package com.android.internal.telephony;
import android.content.Context;
-
+import android.util.Log;
public class PhoneSubInfo extends IPhoneSubInfo.Stub {
+ static final String LOG_TAG = "PHONE";
private Phone mPhone;
private Context mContext;
private static final String READ_PHONE_STATE =
@@ -28,8 +29,16 @@ public class PhoneSubInfo extends IPhoneSubInfo.Stub {
mPhone = phone;
mContext = phone.getContext();
}
+
+ public void dispose() {
+ }
+
+ protected void finalize() {
+ Log.d(LOG_TAG, "PhoneSubInfo finalized");
+ }
+
/**
- * Retrieves the unique device ID, e.g., IMEI for GSM phones.
+ * Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones.
*/
public String getDeviceId() {
mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
index 87102a92d740..450b3a70d88b 100644
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
@@ -16,16 +16,21 @@
package com.android.internal.telephony;
-import android.content.Context;
import android.os.ServiceManager;
-import com.android.internal.telephony.*;
+
public class PhoneSubInfoProxy extends IPhoneSubInfo.Stub {
private PhoneSubInfo mPhoneSubInfo;
public PhoneSubInfoProxy(PhoneSubInfo phoneSubInfo) {
mPhoneSubInfo = phoneSubInfo;
- ServiceManager.addService("iphonesubinfo", this);
+ if(ServiceManager.getService("iphonesubinfo") == null) {
+ ServiceManager.addService("iphonesubinfo", this);
+ }
+ }
+
+ public void setmPhoneSubInfo(PhoneSubInfo phoneSubInfo) {
+ this.mPhoneSubInfo = phoneSubInfo;
}
public String getDeviceId() {
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 568c86c5fc56..d995075d555e 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -16,43 +16,45 @@
package com.android.internal.telephony;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.BroadcastReceiver;
-import com.android.internal.telephony.CallForwardInfo;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.gsm.CommandException;
-import com.android.internal.telephony.gsm.NetworkInfo;
-import com.android.internal.telephony.gsm.PDPContextState;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.gsm.SmsResponse;
-import com.android.internal.telephony.gsm.SuppServiceNotification;
-
-import android.os.Parcel;
-import java.io.IOException;
-import android.os.Message;
-import android.os.Handler;
-import android.net.LocalSocketAddress;
import android.net.LocalSocket;
-import com.android.internal.os.HandlerThread;
+import android.net.LocalSocketAddress;
+import android.os.AsyncResult;
+import android.os.Handler;
import android.os.HandlerInterface;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.io.InputStream;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
import android.telephony.PhoneNumberUtils;
-import android.telephony.gsm.SmsManager;
-import android.telephony.gsm.SmsMessage;
+import android.telephony.SmsManager;
+import android.telephony.SmsMessage;
import android.util.Log;
import android.util.Config;
-import android.os.AsyncResult;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import com.android.internal.telephony.IccCardStatus;
+import static com.android.internal.telephony.RILConstants.*;
+
+import com.android.internal.os.HandlerThread;
+import com.android.internal.telephony.CallForwardInfo;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.gsm.NetworkInfo;
+import com.android.internal.telephony.gsm.PDPContextState;
+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 static com.android.internal.telephony.RILConstants.*;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
/**
* {@hide}
@@ -77,14 +79,14 @@ class RILRequest {
/**
* Retrieves a new RILRequest instance from the pool.
- *
+ *
* @param request RIL_REQUEST_*
* @param result sent when operation completes
* @return a RILRequest instance from the pool.
*/
static RILRequest obtain(int request, Message result) {
RILRequest rr = null;
-
+
synchronized(sPoolSync) {
if (sPool != null) {
rr = sPool;
@@ -93,7 +95,7 @@ class RILRequest {
sPoolSize--;
}
}
-
+
if (rr == null) {
rr = new RILRequest();
}
@@ -118,7 +120,7 @@ class RILRequest {
/**
* Returns a RILRequest instance to the pool.
- *
+ *
* Note: This should only be called once per use.
*/
void release() {
@@ -167,7 +169,7 @@ class RILRequest {
ex = CommandException.fromRilErrno(error);
if (RIL.RILJ_LOG) Log.d(LOG_TAG, serialString() + "< "
- + RIL.requestToString(mRequest)
+ + RIL.requestToString(mRequest)
+ " error: " + ex);
if (mResult != null) {
@@ -186,7 +188,7 @@ class RILRequest {
/**
* RIL implementation of the CommandsInterface.
* FIXME public only for testing
- *
+ *
* {@hide}
*/
public final class RIL extends BaseCommands implements CommandsInterface {
@@ -212,7 +214,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
//I'd rather this be LinkedList or something
ArrayList<RILRequest> mRequestsList = new ArrayList<RILRequest>();
-
+
Object mLastNITZTimeInfo;
//***** Events
@@ -243,7 +245,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
}
};
-
+
class RILSender implements HandlerInterface,Runnable {
// Only allocated once
byte[] dataLength = new byte[4];
@@ -261,7 +263,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
handleMessage(Message msg) {
RILRequest rr = (RILRequest)(msg.obj);
RILRequest req = null;
-
+
switch (msg.what) {
case EVENT_SEND:
/**
@@ -298,7 +300,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
if (data.length > RIL_MAX_COMMAND_BYTES) {
throw new RuntimeException(
- "Parcel larger than max bytes allowed! "
+ "Parcel larger than max bytes allowed! "
+ data.length);
}
@@ -309,7 +311,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
//Log.v(LOG_TAG, "writing packet: " + data.length + " bytes");
- s.getOutputStream().write(dataLength);
+ s.getOutputStream().write(dataLength);
s.getOutputStream().write(data);
} catch (IOException ex) {
Log.e(LOG_TAG, "IOException", ex);
@@ -349,12 +351,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
" mReqPending=" + mRequestMessagesPending +
" mRequestList=" + count);
-
+
for (int i = 0; i < count; i++) {
rr = mRequestsList.get(i);
Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] " +
requestToString(rr.mRequest));
-
+
}
}
}
@@ -436,7 +438,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
run() {
int retryCount = 0;
-
+
try {for (;;) {
LocalSocket s = null;
LocalSocketAddress l;
@@ -454,23 +456,23 @@ public final class RIL extends BaseCommands implements CommandsInterface {
} catch (IOException ex2) {
//ignore failure to close after failure to connect
}
-
+
// don't print an error message after the the first time
// or after the 8th time
if (retryCount == 8) {
- Log.e (LOG_TAG,
+ Log.e (LOG_TAG,
"Couldn't find '" + SOCKET_NAME_RIL
+ "' socket after " + retryCount
+ " times, continuing to retry silently");
} else if (retryCount > 0 && retryCount < 8) {
- Log.i (LOG_TAG,
+ Log.i (LOG_TAG,
"Couldn't find '" + SOCKET_NAME_RIL
+ "' socket; retrying after timeout");
}
try {
- Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
+ Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
} catch (InterruptedException er) {
}
@@ -486,7 +488,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
int length = 0;
try {
InputStream is = mSocket.getInputStream();
-
+
for (;;) {
Parcel p;
@@ -517,9 +519,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
+ "' socket");
setRadioState (RadioState.RADIO_UNAVAILABLE);
-
+
try {
- mSocket.close();
+ mSocket.close();
} catch (IOException ex) {
}
@@ -545,8 +547,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
//***** Constructors
- public RIL(Context context) {
- this(context, RILConstants.NETWORK_MODE_GLOBAL, RILConstants.SUBSCRIPTION_FROM_RUIM);
+ public
+ RIL(Context context) {
+ this(context, RILConstants.PREFERRED_NETWORK_MODE,
+ RILConstants.PREFERRED_CDMA_SUBSCRIPTION);
}
public RIL(Context context, int networkMode, int cdmaSubscription) {
@@ -554,14 +558,27 @@ public final class RIL extends BaseCommands implements CommandsInterface {
mCdmaSubscription = cdmaSubscription;
mNetworkMode = networkMode;
//At startup mPhoneType is first set from networkMode
- if(networkMode == RILConstants.NETWORK_MODE_GSM_UMTS) {
- mPhoneType = RILConstants.GSM_PHONE;
- } else {
- mPhoneType = RILConstants.CDMA_PHONE;
+ 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;
+ default:
+ mPhoneType = RILConstants.CDMA_PHONE;
}
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
mWakeLock.setReferenceCounted(false);
mRequestMessagesPending = 0;
@@ -581,7 +598,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
//***** CommandsInterface implementation
- @Override public void
+ @Override public void
setOnNITZTime(Handler h, int what, Object obj) {
super.setOnNITZTime(h, what, obj);
@@ -594,10 +611,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
}
- public void
+ public void
getIccStatus(Message result) {
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
+ //Note: This RIL request has not been renamed to ICC,
+ // but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SIM_STATUS, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -605,10 +622,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
supplyIccPin(String pin, Message result) {
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
+ //Note: This RIL request has not been renamed to ICC,
+ // but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -619,10 +636,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
supplyIccPuk(String puk, String newPin, Message result) {
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
+ //Note: This RIL request has not been renamed to ICC,
+ // but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -634,10 +651,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
supplyIccPin2(String pin, Message result) {
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
+ //Note: This RIL request has not been renamed to ICC,
+ // but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN2, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -648,10 +665,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
supplyIccPuk2(String puk, String newPin2, Message result) {
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
+ //Note: This RIL request has not been renamed to ICC,
+ // but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK2, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -665,8 +682,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
changeIccPin(String oldPin, String newPin, Message result) {
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
+ //Note: This RIL request has not been renamed to ICC,
+ // but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -680,8 +697,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
changeIccPin2(String oldPin2, String newPin2, Message result) {
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
+ //Note: This RIL request has not been renamed to ICC,
+ // but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN2, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -707,7 +724,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
supplyNetworkDepersonalization(String netpin, Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result);
@@ -718,8 +735,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
-
- public void
+
+ public void
getCurrentCalls (Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result);
@@ -728,16 +745,21 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
getPDPContextList(Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_PDP_CONTEXT_LIST, result);
+ getDataCallList(result);
+ }
+
+ public void
+ getDataCallList(Message result) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_DATA_CALL_LIST, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
send(rr);
}
- public void
+ public void
dial (String address, int clirMode, Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
@@ -749,7 +771,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
getIMSI(Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result);
@@ -780,13 +802,14 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
- public void
+ public void
hangupConnection (int gsmIndex, Message result) {
if (RILJ_LOG) riljLog("hangupConnection: gsmIndex=" + gsmIndex);
RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP, result);
- if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + gsmIndex);
+ if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " +
+ gsmIndex);
rr.mp.writeInt(1);
rr.mp.writeInt(gsmIndex);
@@ -794,9 +817,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
hangupWaitingOrBackground (Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND,
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND,
result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -806,9 +829,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
hangupForegroundResumeBackground (Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(
- RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND,
+ RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND,
result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -817,9 +840,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
switchWaitingOrHoldingAndActive (Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(
- RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
+ RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -828,7 +851,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
conference (Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_CONFERENCE, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -840,13 +863,13 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void setPreferredVoicePrivacy(boolean enable, Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE,
result);
-
+
rr.mp.writeInt(1);
rr.mp.writeInt(enable ? 1:0);
-
+
send(rr);
}
-
+
public void getPreferredVoicePrivacy(Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE,
result);
@@ -855,7 +878,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
separateConnection (int gsmIndex, Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SEPARATE_CONNECTION, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
@@ -869,7 +892,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
acceptCall (Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_ANSWER, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -877,9 +900,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
rejectCall (Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_UDUB, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -899,7 +922,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
getLastCallFailCause (Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -907,10 +930,21 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ /**
+ * @deprecated
+ */
+ public void
getLastPdpFailCause (Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_LAST_PDP_FAIL_CAUSE, result);
+ getLastDataCallFailCause (result);
+ }
+
+ /**
+ * The preferred new alternative to getLastPdpFailCause
+ */
+ public void
+ getLastDataCallFailCause (Message result) {
+ RILRequest rr
+ = RILRequest.obtain(RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -919,7 +953,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
setMute (boolean enableMute, Message response) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SET_MUTE, response);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
@@ -933,7 +967,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
getMute (Message response) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_GET_MUTE, response);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -943,7 +977,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
getSignalStrength (Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -951,9 +985,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
getRegistrationState (Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_REGISTRATION_STATE, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -961,9 +995,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
getGPRSRegistrationState (Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_GPRS_REGISTRATION_STATE, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -971,9 +1005,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
getOperator(Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_OPERATOR, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -981,13 +1015,13 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
sendDtmf(char c, Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_DTMF, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
+
rr.mp.writeString(Character.toString(c));
send(rr);
@@ -1018,7 +1052,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
sendSMS (String smscPDU, String pdu, Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SEND_SMS, result);
rr.mp.writeInt(2);
@@ -1026,20 +1060,83 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr.mp.writeString(pdu);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
+
+ send(rr);
+ }
+
+ public void
+ sendCdmaSms(byte[] pdu, Message result) {
+ int address_nbr_of_digits;
+ int subaddr_nbr_of_digits;
+ int bearerDataLength;
+ ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
+ DataInputStream dis = new DataInputStream(bais);
+
+ RILRequest rr
+ = RILRequest.obtain(RIL_REQUEST_CDMA_SEND_SMS, result);
+
+ try {
+ rr.mp.writeInt(dis.readInt()); //teleServiceId
+ rr.mp.writeInt(dis.readInt()); //servicePresent
+ rr.mp.writeInt(dis.readInt()); //serviceCategory
+ rr.mp.writeInt(dis.read()); //address_digit_mode
+ rr.mp.writeInt(dis.read()); //address_nbr_mode
+ rr.mp.writeInt(dis.read()); //address_ton
+ rr.mp.writeInt(dis.read()); //address_nbr_plan
+ address_nbr_of_digits = (byte) dis.read();
+ rr.mp.writeInt(address_nbr_of_digits);
+ for(int i=0; i < address_nbr_of_digits; i++){
+ rr.mp.writeInt(dis.readByte()); // address_orig_bytes[i]
+ }
+ rr.mp.writeInt(dis.read()); //subaddressType
+ rr.mp.writeInt(dis.read()); //subaddr_odd
+ subaddr_nbr_of_digits = (byte) dis.read();
+ rr.mp.writeInt(subaddr_nbr_of_digits);
+ for(int i=0; i < subaddr_nbr_of_digits; i++){
+ rr.mp.writeInt(dis.readByte()); //subaddr_orig_bytes[i]
+ }
+
+ bearerDataLength = dis.read();
+ rr.mp.writeInt(bearerDataLength);
+ for(int i=0; i < bearerDataLength; i++){
+ rr.mp.writeInt(dis.readByte()); //bearerData[i]
+ }
+ }catch (IOException ex){
+ if (RILJ_LOG) riljLog("sendSmsCdma: conversion from input stream to object failed: "
+ + ex);
+ }
+
+ if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
send(rr);
}
public void deleteSmsOnSim(int index, Message response) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_DELETE_SMS_ON_SIM,
response);
-
+
rr.mp.writeInt(1);
rr.mp.writeInt(index);
- if (Config.LOGD) {
+ if (Config.LOGD) {
if (RILJ_LOG) riljLog(rr.serialString() + "> "
- + requestToString(rr.mRequest)
+ + requestToString(rr.mRequest)
+ + " " + index);
+ }
+
+ send(rr);
+ }
+
+ public void deleteSmsOnRuim(int index, Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM,
+ response);
+
+ rr.mp.writeInt(1);
+ rr.mp.writeInt(index);
+
+ if (Config.LOGD) {
+ if (RILJ_LOG) riljLog(rr.serialString() + "> "
+ + requestToString(rr.mRequest)
+ " " + index);
}
@@ -1048,17 +1145,35 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
status = translateStatus(status);
-
+
RILRequest rr = RILRequest.obtain(RIL_REQUEST_WRITE_SMS_TO_SIM,
response);
-
+
rr.mp.writeInt(status);
rr.mp.writeString(pdu);
rr.mp.writeString(smsc);
-
- if (Config.LOGD) {
+
+ if (Config.LOGD) {
if (RILJ_LOG) riljLog(rr.serialString() + "> "
- + requestToString(rr.mRequest)
+ + requestToString(rr.mRequest)
+ + " " + status);
+ }
+
+ send(rr);
+ }
+
+ public void writeSmsToRuim(int status, String pdu, Message response) {
+ status = translateStatus(status);
+
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM,
+ response);
+
+ rr.mp.writeInt(status);
+ rr.mp.writeString(pdu);
+
+ if (Config.LOGD) {
+ if (RILJ_LOG) riljLog(rr.serialString() + "> "
+ + requestToString(rr.mRequest)
+ " " + status);
}
@@ -1071,46 +1186,76 @@ public final class RIL extends BaseCommands implements CommandsInterface {
*/
private int translateStatus(int status) {
switch(status & 0x7) {
- case SmsManager.STATUS_ON_SIM_READ:
+ case SmsManager.STATUS_ON_ICC_READ:
return 1;
- case SmsManager.STATUS_ON_SIM_UNREAD:
+ case SmsManager.STATUS_ON_ICC_UNREAD:
return 0;
- case SmsManager.STATUS_ON_SIM_SENT:
+ case SmsManager.STATUS_ON_ICC_SENT:
return 3;
- case SmsManager.STATUS_ON_SIM_UNSENT:
+ case SmsManager.STATUS_ON_ICC_UNSENT:
return 2;
}
-
+
// Default to READ.
return 1;
}
- public void
+ /**
+ * @deprecated
+ */
+ public void
setupDefaultPDP(String apn, String user, String password, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SETUP_DEFAULT_PDP, result);
+ String radioTechnology = "1"; //0 for CDMA, 1 for GSM/UMTS
+ String profile = ""; //profile number, NULL for GSM/UMTS
+ setupDataCall(radioTechnology, profile, apn, user,
+ password, result);
- rr.mp.writeInt(3);
+ }
+
+ /**
+ * @deprecated
+ */
+ public void
+ deactivateDefaultPDP(int cid, Message result) {
+ deactivateDataCall(cid, result);
+ }
+
+ /**
+ * The preferred new alternative to setupDefaultPDP that is
+ * CDMA-compatible.
+ *
+ */
+ public void
+ setupDataCall(String radioTechnology, String profile, String apn,
+ String user, String password, Message result) {
+ RILRequest rr
+ = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
+
+ rr.mp.writeInt(5);
+
+ rr.mp.writeString(radioTechnology);
+ rr.mp.writeString(profile);
rr.mp.writeString(apn);
rr.mp.writeString(user);
rr.mp.writeString(password);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " "
+ apn);
-
+
send(rr);
}
public void
- deactivateDefaultPDP(int cid, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DEFAULT_PDP, result);
+ deactivateDataCall(int cid, Message result) {
+ RILRequest rr
+ = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DATA_CALL, result);
rr.mp.writeInt(1);
rr.mp.writeString(Integer.toString(cid));
- if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + cid);
-
+ if (RILJ_LOG) riljLog(rr.serialString() + "> " +
+ requestToString(rr.mRequest) + " " + cid);
+
send(rr);
}
@@ -1120,25 +1265,13 @@ public final class RIL extends BaseCommands implements CommandsInterface {
if(mInitialRadioStateChange) {
synchronized (mStateMonitor) {
if (!mState.isOn()) {
- int modemNetworkMode;
- switch(mNetworkMode) {
- case RILConstants.NETWORK_MODE_GSM_UMTS:
- modemNetworkMode = Phone.NT_GSM_UMTS_AUTO_TYPE;
- break;
- case RILConstants.NETWORK_MODE_CDMA:
- modemNetworkMode = Phone.NT_CDMA_EVDO_AUTO_TYPE;
- break;
- case RILConstants.NETWORK_MODE_GLOBAL:
- default:
- modemNetworkMode = Phone.NT_GLOBAL_AUTO_TYPE;
- }
RILRequest rrPnt = RILRequest.obtain(
RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, null);
rrPnt.mp.writeInt(1);
- rrPnt.mp.writeInt(modemNetworkMode);
- if (RILJ_LOG) riljLog(rrPnt.serialString() + "> "
- + requestToString(rrPnt.mRequest) + " : " + modemNetworkMode);
+ rrPnt.mp.writeInt(mNetworkMode);
+ if (RILJ_LOG) riljLog(rrPnt.serialString() + "> "
+ + requestToString(rrPnt.mRequest) + " : " + mNetworkMode);
send(rrPnt);
@@ -1146,31 +1279,31 @@ public final class RIL extends BaseCommands implements CommandsInterface {
RIL_REQUEST_CDMA_SET_SUBSCRIPTION, null);
rrCs.mp.writeInt(1);
rrCs.mp.writeInt(mCdmaSubscription);
- if (RILJ_LOG) riljLog(rrCs.serialString() + "> "
- + requestToString(rrCs.mRequest) + " : " + mCdmaSubscription);
- send(rrCs);
+ if (RILJ_LOG) riljLog(rrCs.serialString() + "> "
+ + requestToString(rrCs.mRequest) + " : " + mCdmaSubscription);
+ send(rrCs);
}
}
}
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result);
rr.mp.writeInt(1);
rr.mp.writeInt(on ? 1 : 0);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
+
send(rr);
}
public void
setSuppServiceNotifications(boolean enable, Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result);
rr.mp.writeInt(1);
rr.mp.writeInt(enable ? 1 : 0);
-
+
if (Config.LOGD) {
if (RILJ_LOG) riljLog(rr.serialString() + "> "
+ requestToString(rr.mRequest));
@@ -1179,27 +1312,42 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ public void
acknowledgeLastIncomingSMS(boolean success, Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SMS_ACKNOWLEDGE, result);
rr.mp.writeInt(1);
rr.mp.writeInt(success ? 1 : 0);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
+
send(rr);
}
-
+
public void
- iccIO (int command, int fileid, String path, int p1, int p2, int p3,
+ acknowledgeLastIncomingCdmaSms(boolean success, 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.
+
+ if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+
+ public void
+ iccIO (int command, int fileid, String path, int p1, int p2, int p3,
String data, String pin2, Message result) {
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
- RILRequest rr
+ //Note: This RIL request has not been renamed to ICC,
+ // but this request is also valid for SIM and RUIM
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SIM_IO, result);
-
+
rr.mp.writeInt(command);
rr.mp.writeInt(fileid);
rr.mp.writeString(path);
@@ -1210,47 +1358,47 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr.mp.writeString(pin2);
if (RILJ_LOG) riljLog(rr.serialString() + "> iccIO: " + requestToString(rr.mRequest)
- + " 0x" + Integer.toHexString(command)
- + " 0x" + Integer.toHexString(fileid) + " "
+ + " 0x" + Integer.toHexString(command)
+ + " 0x" + Integer.toHexString(fileid) + " "
+ p1 + "," + p2 + "," + p3);
-
+
send(rr);
}
-
+
public void
getCLIR(Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_GET_CLIR, result);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
+
send(rr);
}
public void
setCLIR(int clirMode, Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SET_CLIR, result);
// count ints
rr.mp.writeInt(1);
rr.mp.writeInt(clirMode);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " " + clirMode);
-
+
send(rr);
}
public void
queryCallWaiting(int serviceClass, Message response) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_QUERY_CALL_WAITING, response);
rr.mp.writeInt(1);
rr.mp.writeInt(serviceClass);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " " + serviceClass);
@@ -1259,70 +1407,70 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
setCallWaiting(boolean enable, int serviceClass, Message response) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SET_CALL_WAITING, response);
-
+
rr.mp.writeInt(2);
rr.mp.writeInt(enable ? 1 : 0);
rr.mp.writeInt(serviceClass);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " " + enable + ", " + serviceClass);
-
+
send(rr);
}
public void
setNetworkSelectionModeAutomatic(Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
+ RILRequest rr
+ = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
response);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
+
send(rr);
}
- public void
+ public void
setNetworkSelectionModeManual(String operatorNumeric, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
+ RILRequest rr
+ = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
response);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " " + operatorNumeric);
rr.mp.writeString(operatorNumeric);
-
+
send(rr);
}
- public void
+ public void
getNetworkSelectionMode(Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE,
+ RILRequest rr
+ = RILRequest.obtain(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE,
response);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
+
send(rr);
}
- public void
+ public void
getAvailableNetworks(Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS,
+ RILRequest rr
+ = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS,
response);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
+
send(rr);
}
public void
- setCallForward(int action, int cfReason, int serviceClass,
+ setCallForward(int action, int cfReason, int serviceClass,
String number, int timeSeconds, Message response) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SET_CALL_FORWARD, response);
rr.mp.writeInt(action);
@@ -1331,18 +1479,18 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr.mp.writeInt(PhoneNumberUtils.toaFromString(number));
rr.mp.writeString(number);
rr.mp.writeInt (timeSeconds);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + action + " " + cfReason + " " + serviceClass
+ + " " + action + " " + cfReason + " " + serviceClass
+ timeSeconds);
-
+
send(rr);
}
public void
queryCallForwardStatus(int cfReason, int serviceClass,
String number, Message response) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, response);
rr.mp.writeInt(2); // 2 is for query action, not in used anyway
@@ -1351,7 +1499,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr.mp.writeInt(PhoneNumberUtils.toaFromString(number));
rr.mp.writeString(number);
rr.mp.writeInt (0);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " " + cfReason + " " + serviceClass);
@@ -1371,9 +1519,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void
getBasebandVersion (Message response) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_BASEBAND_VERSION, response);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
send(rr);
@@ -1387,7 +1535,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
// count strings
- rr.mp.writeInt(3);
+ rr.mp.writeInt(3);
rr.mp.writeString(facility);
rr.mp.writeString(password);
@@ -1418,10 +1566,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
-
+
public void
sendUSSD (String ussdString, Message response) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SEND_USSD, response);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
@@ -1445,7 +1593,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void resetRadio(Message result) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_RESET_RADIO, result);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -1454,7 +1602,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
public void invokeOemRilRequestRaw(byte[] data, Message response) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_OEM_HOOK_RAW, response);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
@@ -1467,7 +1615,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
public void invokeOemRilRequestStrings(String[] strings, Message response) {
- RILRequest rr
+ RILRequest rr
= RILRequest.obtain(RIL_REQUEST_OEM_HOOK_STRINGS, response);
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -1604,10 +1752,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_LOCATION_UPDATES, response);
rr.mp.writeInt(1);
rr.mp.writeInt(enable ? 1 : 0);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> "
+ requestToString(rr.mRequest) + ": " + enable);
-
+
send(rr);
}
@@ -1617,12 +1765,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_SCREEN_STATE, null);
rr.mp.writeInt(1);
rr.mp.writeInt(on ? 1 : 0);
-
+
if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + ": " + on);
-
+
send(rr);
}
-
+
protected void
onRadioAvailable() {
// In case screen state was lost (due to process crash),
@@ -1649,7 +1797,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case 8: newState = RadioState.NV_NOT_READY; break;
case 9: newState = RadioState.NV_READY; break;
- default:
+ default:
throw new RuntimeException(
"Unrecognized RIL_RadioState: " +state);
}
@@ -1666,7 +1814,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
setRadioPower(false, null);
} else {
if (DBG) Log.d(LOG_TAG, "Radio OFF @ init");
- setRadioState(newState);
+ setRadioState(newState);
}
mInitialRadioStateChange = false;
} else {
@@ -1679,7 +1827,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
* a) There is outstanding RIL request sent to RIL deamon and no replied
* b) There is a request waiting to be sent out.
*
- * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
+ * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
* happen often.
*/
@@ -1728,13 +1876,11 @@ public final class RIL extends BaseCommands implements CommandsInterface {
processUnsolicited (p);
} else if (type == RESPONSE_SOLICITED) {
processSolicited (p);
- }
+ }
releaseWakeLockIfDone();
}
-
-
private RILRequest findAndRemoveRequestFromList(int serial) {
synchronized (mRequestsList) {
for (int i = 0, s = mRequestsList.size() ; i < s ; i++) {
@@ -1763,7 +1909,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr = findAndRemoveRequestFromList(serial);
if (rr == null) {
- Log.w(LOG_TAG, "Unexpected solicited response! sn: "
+ Log.w(LOG_TAG, "Unexpected solicited response! sn: "
+ serial + " error: " + error);
return;
}
@@ -1775,16 +1921,13 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
Object ret;
-
+
try {switch (rr.mRequest) {
/*
cat libs/telephony/ril_commands.h \
| egrep "^ *{RIL_" \
| sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/'
*/
- //TODO T: start
- // These RIL requests will not be renamed to ICC,
- // but these requests are also valid for SIM and RUIM
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;
@@ -1792,7 +1935,6 @@ public final class RIL extends BaseCommands implements CommandsInterface {
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;
- //TODO T: end
case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret = responseVoid(p); break;
case RIL_REQUEST_GET_CURRENT_CALLS: ret = responseCallList(p); break;
case RIL_REQUEST_DIAL: ret = responseVoid(p); break;
@@ -1812,9 +1954,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_DTMF: ret = responseVoid(p); break;
case RIL_REQUEST_SEND_SMS: ret = responseSMS(p); break;
case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret = responseSMS(p); break;
- case RIL_REQUEST_SETUP_DEFAULT_PDP: ret = responseStrings(p); break;
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
+ case RIL_REQUEST_SETUP_DATA_CALL: ret = responseStrings(p); break;
case RIL_REQUEST_SIM_IO: ret = responseICC_IO(p); break;
case RIL_REQUEST_SEND_USSD: ret = responseVoid(p); break;
case RIL_REQUEST_CANCEL_USSD: ret = responseVoid(p); break;
@@ -1828,7 +1968,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_GET_IMEI: ret = responseString(p); break;
case RIL_REQUEST_GET_IMEISV: ret = responseString(p); break;
case RIL_REQUEST_ANSWER: ret = responseVoid(p); break;
- case RIL_REQUEST_DEACTIVATE_DEFAULT_PDP: 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_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break;
@@ -1840,30 +1980,30 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_DTMF_STOP: ret = responseVoid(p); break;
case RIL_REQUEST_BASEBAND_VERSION: ret = responseString(p); break;
case RIL_REQUEST_SEPARATE_CONNECTION: ret = responseVoid(p); break;
- case RIL_REQUEST_SET_MUTE: ret =responseVoid(p); break;
- case RIL_REQUEST_GET_MUTE: ret = responseInts(p); break;
- case RIL_REQUEST_QUERY_CLIP: ret = responseInts(p); break;
- case RIL_REQUEST_LAST_PDP_FAIL_CAUSE: ret = responseInts(p); break;
- case RIL_REQUEST_PDP_CONTEXT_LIST: ret = responseContextList(p); break;
- case RIL_REQUEST_RESET_RADIO: ret = responseVoid(p); break;
- case RIL_REQUEST_OEM_HOOK_RAW: ret = responseRaw(p); break;
- case RIL_REQUEST_OEM_HOOK_STRINGS: ret = responseStrings(p); break;
+ case RIL_REQUEST_SET_MUTE: ret = responseVoid(p); break;
+ case RIL_REQUEST_GET_MUTE: ret = responseInts(p); break;
+ case RIL_REQUEST_QUERY_CLIP: ret = responseInts(p); break;
+ case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret = responseInts(p); break;
+ case RIL_REQUEST_DATA_CALL_LIST: ret = responseDataCallList(p); break;
+ case RIL_REQUEST_RESET_RADIO: ret = responseVoid(p); break;
+ case RIL_REQUEST_OEM_HOOK_RAW: ret = responseRaw(p); break;
+ case RIL_REQUEST_OEM_HOOK_STRINGS: ret = responseStrings(p); break;
case RIL_REQUEST_SCREEN_STATE: ret = responseVoid(p); break;
- case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret = responseVoid(p); break;
- case RIL_REQUEST_WRITE_SMS_TO_SIM: ret = responseInts(p); break;
- case RIL_REQUEST_DELETE_SMS_ON_SIM: ret = responseVoid(p); break;
- case RIL_REQUEST_SET_BAND_MODE: ret = responseVoid(p); break;
- case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret = responseInts(p); break;
- case RIL_REQUEST_STK_GET_PROFILE: ret = responseString(p); break;
- case RIL_REQUEST_STK_SET_PROFILE: ret = responseVoid(p); break;
- case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret = responseString(p); break;
- case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret = responseVoid(p); break;
- case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret = responseInts(p); break;
- case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret = responseVoid(p); break;
- case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret = responseVoid(p); break;
- case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseInts(p); break;
- case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseStrings(p); break;
- case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break;
+ case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret = responseVoid(p); break;
+ case RIL_REQUEST_WRITE_SMS_TO_SIM: ret = responseInts(p); break;
+ case RIL_REQUEST_DELETE_SMS_ON_SIM: ret = responseVoid(p); break;
+ case RIL_REQUEST_SET_BAND_MODE: ret = responseVoid(p); break;
+ case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret = responseInts(p); break;
+ case RIL_REQUEST_STK_GET_PROFILE: ret = responseString(p); break;
+ case RIL_REQUEST_STK_SET_PROFILE: ret = responseVoid(p); break;
+ case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret = responseString(p); break;
+ case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret = responseVoid(p); break;
+ case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret = responseInts(p); break;
+ case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret = responseVoid(p); break;
+ case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret = responseVoid(p); break;
+ case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseInts(p); break;
+ case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseStrings(p); break;
+ case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SET_SUBSCRIPTION: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret = responseInts(p); break;
@@ -1880,24 +2020,21 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCDMA_BR_CNF(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_SETUP_DATA_CALL: ret = responseStrings(p); break;
- case RIL_REQUEST_DEACTIVATE_DATA_CALL: 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_ENCODE_SMS: ret = responseRIL_CDMA_Encoded_SMS(p); break;
- case RIL_REQUEST_CDMA_DECODE_SMS: ret = responseRIL_CDMA_SMS_ClientBd(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_DEVICE_IDENTITY: ret = responseStrings(p); break;
default:
- throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
+ throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
}} 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);
@@ -1909,12 +2046,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
if (RILJ_LOG) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
+ " " + retToString(rr.mRequest, ret));
-
+
if (rr.mResult != null) {
AsyncResult.forMessage(rr.mResult, ret, null);
rr.mResult.sendToTarget();
}
-
+
rr.release();
}
@@ -1994,26 +2131,24 @@ public final class RIL extends BaseCommands implements CommandsInterface {
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_PDP_CONTEXT_LIST_CHANGED: ret = responseContextList(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;
case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break;
case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break;
case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
case RIL_UNSOL_SIM_REFRESH: ret = responseInts(p); break;
case RIL_UNSOL_CALL_RING: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break;
- case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCDMA_SMS(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;
- default:
- throw new RuntimeException("Unrecognized unsol response: " + response);
+ default:
+ throw new RuntimeException("Unrecognized unsol response: " + response);
//break; (implied)
}} catch (Throwable tr) {
- Log.e(LOG_TAG, "Exception processing unsol response: "
+ Log.e(LOG_TAG, "Exception processing unsol response: "
+ response, tr);
return;
}
@@ -2022,7 +2157,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
/* has bonus radio state int */
setRadioStateFromRILInt(p.readInt());
-
+
if (RILJ_LOG) riljLog("[UNSL]< RADIO_STATE_CHANGED " +mState);
break;
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
@@ -2047,7 +2182,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
SmsMessage sms;
- sms = SmsMessage.newFromCMT(a);
+ sms = SmsMessage.newFromCMT(a);
if (mSMSRegistrant != null) {
mSMSRegistrant
.notifyRegistrant(new AsyncResult(null, sms, null));
@@ -2081,7 +2216,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
break;
case RIL_UNSOL_ON_USSD:
String[] resp = (String[])ret;
-
+
if (resp.length < 2) {
resp = new String[2];
resp[0] = ((String[])ret)[0];
@@ -2093,7 +2228,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
new AsyncResult (null, resp, null));
}
break;
- case RIL_UNSOL_NITZ_TIME_RECEIVED:
+ case RIL_UNSOL_NITZ_TIME_RECEIVED:
if (RILJ_LOG) riljLog("[UNSL]< NITZ_TIME_RECEIVED " + retToString(response, ret));
// has bonus int containing time_t that the NITZ
@@ -2106,7 +2241,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
result[1] = Integer.valueOf(nitzReceiveTime);
if (mNITZTimeRegistrant != null) {
-
+
mNITZTimeRegistrant
.notifyRegistrant(new AsyncResult (null, result, null));
} else {
@@ -2114,23 +2249,23 @@ public final class RIL extends BaseCommands implements CommandsInterface {
mLastNITZTimeInfo = result;
}
break;
-
+
case RIL_UNSOL_SIGNAL_STRENGTH:
// Note this is set to "verbose" because it happens
// frequently
if (Config.LOGV) Log.v(LOG_TAG, "[UNSL]< SIGNAL_STRENGTH "
+ retToString(response, ret));
-
+
if (mSignalStrengthRegistrant != null) {
mSignalStrengthRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
- case RIL_UNSOL_PDP_CONTEXT_LIST_CHANGED:
- if (RILJ_LOG) riljLog("[UNSL]< PDP_CONTEXT_CHANGED " + retToString(response, ret));
+ case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
+ if (RILJ_LOG) riljLog("[UNSL]< DATA_CALL_LIST_CHANGED "
+ + retToString(response, ret));
- mPDPRegistrants
- .notifyRegistrants(new AsyncResult(null, ret, null));
+ mDataConnectionRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
break;
case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
@@ -2197,14 +2332,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
if (RILJ_LOG) riljLog("[UNSL]< SIM_SMS_STORAGE_FULL");
}
- if (mSimSmsFullRegistrant != null) {
- mSimSmsFullRegistrant.notifyRegistrant();
+ if (mIccSmsFullRegistrant != null) {
+ mIccSmsFullRegistrant.notifyRegistrant();
}
break;
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
- case RIL_UNSOL_SIM_REFRESH:
+ case RIL_UNSOL_SIM_REFRESH:
if (Config.LOGD) {
if (RILJ_LOG) riljLog("[UNSL]< SIM_REFRESH " + retToString(response, ret));
}
@@ -2214,31 +2347,44 @@ public final class RIL extends BaseCommands implements CommandsInterface {
new AsyncResult (null, ret, null));
}
break;
-
- case RIL_UNSOL_CALL_RING:
+
+ case RIL_UNSOL_CALL_RING:
if (Config.LOGD) {
if (RILJ_LOG) riljLog("[UNSL]< CALL_RING ");
}
-
+
if (mRingRegistrant != null) {
mRingRegistrant.notifyRegistrant();
}
break;
- case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
- // TODO
+ case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
+ if (mIccStatusChangedRegistrants != null) {
+ mIccStatusChangedRegistrants.notifyRegistrants();
+ }
break;
-
+
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
- // TODO
+ SmsMessage sms = (SmsMessage) ret;
+
+ if (mSMSRegistrant != null) {
+ mSMSRegistrant
+ .notifyRegistrant(new AsyncResult(null, sms, null));
+ }
break;
-
+
case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
- // TODO
+ // TODO T: waiting for SMS BC feature
break;
-
+
case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
- // TODO
+ if (Config.LOGD) {
+ if (RILJ_LOG) riljLog("[UNSL]< RUIM_SMS_STORAGE_FULL");
+ }
+
+ if (mIccSmsFullRegistrant != null) {
+ mIccSmsFullRegistrant.notifyRegistrant();
+ }
break;
}
}
@@ -2291,22 +2437,24 @@ public final class RIL extends BaseCommands implements CommandsInterface {
private Object
responseSuppServiceNotification(Parcel p) {
SuppServiceNotification notification = new SuppServiceNotification();
-
+
notification.notificationType = p.readInt();
notification.code = p.readInt();
notification.index = p.readInt();
notification.type = p.readInt();
notification.number = p.readString();
-
+
return notification;
}
-
+
private Object
- responseCDMA_SMS(Parcel p) {
- // TODO
- return null;
+ responseCdmaSms(Parcel p) {
+ SmsMessage sms;
+ sms = SmsMessage.newFromParcel(p);
+
+ return sms;
}
-
+
private Object
responseString(Parcel p) {
String response;
@@ -2331,7 +2479,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
response[i] = p.readString();
}
}
-
+
return response;
}
@@ -2364,7 +2512,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
int sw1, sw2;
byte data[] = null;
Message ret;
-
+
sw1 = p.readInt();
sw2 = p.readInt();
@@ -2377,16 +2525,16 @@ public final class RIL extends BaseCommands implements CommandsInterface {
responseIccCardStatus(Parcel p) {
RadioState currentRadioState;
IccCardApplication ca;
-
+
currentRadioState = getRadioState();
-
+
IccCardStatus status = new IccCardStatus();
status.card_state = status.CardStateFromRILInt(p.readInt());
status.universal_pin_state = status.PinStateFromRILInt(p.readInt());
status.gsm_umts_subscription_app_index = p.readInt();
status.cdma_subscription_app_index = p.readInt();
status.num_applications = p.readInt();
-
+
// limit to maximum allowed applications
if (status.num_applications > IccCardStatus.CARD_MAX_APPS) {
status.num_applications = IccCardStatus.CARD_MAX_APPS;
@@ -2398,13 +2546,13 @@ public final class RIL extends BaseCommands implements CommandsInterface {
ca.app_state = ca.AppStateFromRILInt(p.readInt());
ca.perso_substate = ca.PersoSubstateFromRILInt(p.readInt());
ca.aid = p.readString();
- ca.app_label = p.readString();
+ ca.app_label = p.readString();
ca.pin1_replaced = p.readInt();
ca.pin1 = p.readInt();
ca.pin2 = p.readInt();
status.application.add(ca);
}
-
+
// this is common for all radio technologies
if (!status.card_state.isCardPresent()) {
return IccStatus.ICC_ABSENT;
@@ -2412,25 +2560,25 @@ public final class RIL extends BaseCommands implements CommandsInterface {
// check radio technology
if( currentRadioState == RadioState.RADIO_OFF ||
- currentRadioState == RadioState.RADIO_UNAVAILABLE ||
+ currentRadioState == RadioState.RADIO_UNAVAILABLE ||
currentRadioState == RadioState.SIM_NOT_READY ||
currentRadioState == RadioState.RUIM_NOT_READY ||
currentRadioState == RadioState.NV_NOT_READY ||
currentRadioState == RadioState.NV_READY ) {
return IccStatus.ICC_NOT_READY;
}
-
+
if( currentRadioState == RadioState.SIM_LOCKED_OR_ABSENT ||
currentRadioState == RadioState.SIM_READY ||
currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
currentRadioState == RadioState.RUIM_READY) {
-
+
int index;
-
+
// check for CDMA radio technology
if (currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
currentRadioState == RadioState.RUIM_READY) {
- index = status.cdma_subscription_app_index;
+ index = status.cdma_subscription_app_index;
}
else {
index = status.gsm_umts_subscription_app_index;
@@ -2442,7 +2590,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
if (status.application.get(index).app_state.isPukRequired()) {
return IccStatus.ICC_PUK;
- }
+ }
if (status.application.get(index).app_state.isSubscriptionPersoEnabled()) {
return IccStatus.ICC_NETWORK_PERSONALIZATION;
}
@@ -2454,11 +2602,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
return IccStatus.ICC_NOT_READY;
}
-
- // we should never reach this point
- //TODO T: start
- // These RIL requests will not be renamed to ICC,
- // but these requests are also valid for SIM and RUIM
+
throw new RuntimeException ("Invalid RIL_REQUEST_GET_SIM_STATUS result");
}
@@ -2466,6 +2610,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
private Object
responseCallList(Parcel p) {
int num;
+ byte voiceSettings;
ArrayList<DriverCall> response;
DriverCall dc;
@@ -2474,14 +2619,15 @@ public final class RIL extends BaseCommands implements CommandsInterface {
for (int i = 0 ; i < num ; i++) {
dc = new DriverCall();
-
+
dc.state = DriverCall.stateFromCLCC(p.readInt());
dc.index = p.readInt();
dc.TOA = p.readInt();
dc.isMpty = (0 != p.readInt());
dc.isMT = (0 != p.readInt());
dc.als = p.readInt();
- dc.isVoice = (0 == p.readInt()) ? false : true;
+ voiceSettings = p.readByte();
+ dc.isVoice = (0 == voiceSettings) ? false : true;
dc.number = p.readString();
// Make sure there's a leading + on addresses with a TOA
@@ -2491,6 +2637,16 @@ public final class RIL extends BaseCommands implements CommandsInterface {
dc.number, dc.TOA);
response.add(dc);
+
+ if ( RILConstants.CDMA_VOICE_PRIVACY == voiceSettings ) {
+ mVoicePrivacyOnRegistrants.notifyRegistrants();
+ Log.d(LOG_TAG, "InCall VoicePrivacy is enabled: " +
+ Integer.toString(voiceSettings));
+ } else {
+ mVoicePrivacyOffRegistrants.notifyRegistrants();
+ Log.d(LOG_TAG, "InCall VoicePrivacy is disabled: " +
+ Integer.toString(voiceSettings));
+ }
}
Collections.sort(response);
@@ -2499,7 +2655,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
private Object
- responseContextList(Parcel p) {
+ responseDataCallList(Parcel p) {
int num;
ArrayList<PDPContextState> response;
@@ -2528,7 +2684,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
if (strings.length % 4 != 0) {
throw new RuntimeException(
- "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
+ "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
+ strings.length + " strings, expected multible of 4");
}
@@ -2542,7 +2698,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
strings[i+2],
strings[i+3]));
}
-
+
return ret;
}
@@ -2554,20 +2710,19 @@ public final class RIL extends BaseCommands implements CommandsInterface {
private Object
responseCDMA_BR_CNF(Parcel p) {
- // TODO
- return null;
- }
-
- private Object
- responseRIL_CDMA_Encoded_SMS(Parcel p) {
- // TODO
- return null;
- }
+ int numInts;
+ int response[];
- private Object
- responseRIL_CDMA_SMS_ClientBd(Parcel p) {
- // TODO
- return null;
+ numInts = p.readInt();
+
+ response = new int[numInts];
+
+ response[0] = numInts;
+ for (int i = 1 ; i < numInts; i++) {
+ response[i] = p.readInt();
+ }
+
+ return response;
}
static String
@@ -2578,9 +2733,6 @@ public final class RIL extends BaseCommands implements CommandsInterface {
| sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
*/
switch(request) {
- //TODO T: start
- // These RIL requests will not be renamed to ICC,
- // but these requests are also valid for SIM and RUIM
case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
@@ -2588,7 +2740,6 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
- //TODO T: end
case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
case RIL_REQUEST_DIAL: return "DIAL";
@@ -2608,9 +2759,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_DTMF: return "DTMF";
case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
- case RIL_REQUEST_SETUP_DEFAULT_PDP: return "SETUP_DEFAULT_PDP";
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
+ case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
case RIL_REQUEST_SIM_IO: return "SIM_IO";
case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
@@ -2624,7 +2773,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
case RIL_REQUEST_ANSWER: return "ANSWER";
- case RIL_REQUEST_DEACTIVATE_DEFAULT_PDP: return "DEACTIVATE_DEFAULT_PDP";
+ case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
@@ -2639,8 +2788,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
- case RIL_REQUEST_LAST_PDP_FAIL_CAUSE: return "LAST_PDP_FAIL_CAUSE";
- case RIL_REQUEST_PDP_CONTEXT_LIST: return "PDP_CONTEXT_LIST";
+ case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
+ case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
@@ -2676,12 +2825,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
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_SETUP_DATA_CALL: return "RIL_REQUEST_SETUP_DATA_CALL";
- case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "RIL_REQUEST_DEACTIVATE_DATA_CALL";
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_ENCODE_SMS: return "RIL_REQUEST_CDMA_ENCODE_SMS";
- case RIL_REQUEST_CDMA_DECODE_SMS: return "RIL_REQUEST_CDMA_DECODE_SMS";
case RIL_REQUEST_CDMA_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SUBSCRIPTION";
case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
@@ -2693,7 +2838,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
private void riljLog(String msg) {
Log.d(LOG_TAG, msg);
}
-
+
// ***** Methods for CDMA support
public void
getDeviceIdentity(Message response) {
@@ -2728,7 +2873,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
-
+
/**
* {@inheritDoc}
*/
@@ -2744,7 +2889,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
-
+
/**
* {@inheritDoc}
*/
@@ -2767,10 +2912,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void queryTTYModeEnabled(Message response) {
RILRequest rr = RILRequest.obtain(
RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
-
+
send(rr);
- }
-
+ }
+
/**
* {@inheritDoc}
*/
@@ -2780,7 +2925,48 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr.mp.writeInt(1);
rr.mp.writeInt(enable ? 1 : 0);
-
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void
+ sendCDMAFeatureCode(String FeatureCode, Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_FLASH, response);
+
+ rr.mp.writeInt(1);
+ rr.mp.writeString(FeatureCode);
+
+ if (RILJ_LOG) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " : " + FeatureCode);
+
+ send(rr);
+ }
+
+ public void getCdmaBroadcastConfig(Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, response);
+
+ send(rr);
+ }
+
+ public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, response);
+
+ for(int i = 0; i < configValuesArray.length; i++) {
+ rr.mp.writeInt(configValuesArray[i]);
+ }
+
+ send(rr);
+ }
+
+ public void activateCdmaBroadcastSms(int activate, Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, response);
+
+ rr.mp.writeInt(1);
+ rr.mp.writeInt(activate);
+
send(rr);
}
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 3e5818815f81..43fc3b620600 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -26,23 +26,40 @@ public interface RILConstants {
// from RIL_Errno
int SUCCESS = 0;
- int RADIO_NOT_AVAILABLE = 1; /* If radio did not start or is resetting */
+ int RADIO_NOT_AVAILABLE = 1; /* If radio did not start or is resetting */
int GENERIC_FAILURE = 2;
- int PASSWORD_INCORRECT = 3; /* for PIN/PIN2 methods only! */
- int SIM_PIN2 = 4; /* Operation requires SIM PIN2 to be entered */
- int SIM_PUK2 = 5; /* Operation requires SIM PIN2 to be entered */
+ int PASSWORD_INCORRECT = 3; /* for PIN/PIN2 methods only! */
+ int SIM_PIN2 = 4; /* Operation requires SIM PIN2 to be entered */
+ int SIM_PUK2 = 5; /* Operation requires SIM PIN2 to be entered */
int REQUEST_NOT_SUPPORTED = 6;
int REQUEST_CANCELLED = 7;
- int OP_NOT_ALLOWED_DURING_VOICE_CALL = 8; /* data operation is not allowed during voice call in class C */
- int OP_NOT_ALLOWED_BEFORE_REG_NW = 9; /* request is not allowed before device registers to network */
- int SMS_SEND_FAIL_RETRY = 10; /* send sms fail and need retry */
+ int OP_NOT_ALLOWED_DURING_VOICE_CALL = 8; /* data operation is not allowed during voice call in
+ class C */
+ int OP_NOT_ALLOWED_BEFORE_REG_NW = 9; /* request is not allowed before device registers to
+ network */
+ int SMS_SEND_FAIL_RETRY = 10; /* send sms fail and need retry */
- int NETWORK_MODE_GSM_UMTS = 3;
- int NETWORK_MODE_CDMA = 4;
- int NETWORK_MODE_GLOBAL = 7;
+ /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
+ int NETWORK_MODE_WCDMA_PREF = 0; /* GSM/WCDMA (WCDMA preferred) */
+ int NETWORK_MODE_GSM_ONLY = 1; /* GSM only */
+ int NETWORK_MODE_WCDMA_ONLY = 2; /* WCDMA only */
+ int NETWORK_MODE_GSM_UMTS = 3; /* GSM/WCDMA (auto mode, according to PRL)
+ AVAILABLE Application Settings menu*/
+ int NETWORK_MODE_CDMA = 4; /* CDMA and EvDo (auto mode, according to PRL)
+ AVAILABLE Application Settings menu*/
+ int NETWORK_MODE_CDMA_NO_EVDO = 5; /* CDMA only */
+ 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_GLOBAL;
- int SUBSCRIPTION_FROM_RUIM = 0;
- int SUBSCRIPTION_FROM_NV = 1;
+ /* CDMA subscription source. See ril.h RIL_REQUEST_CDMA_SET_SUBSCRIPTION */
+ int SUBSCRIPTION_FROM_RUIM = 0; /* CDMA subscription from RUIM when available */
+ int SUBSCRIPTION_FROM_NV = 1; /* CDMA subscription from NV */
+ int PREFERRED_CDMA_SUBSCRIPTION = SUBSCRIPTION_FROM_NV;
+
+ int CDMA_CELL_BROADCAST_SMS_DISABLED = 1;
+ int CDMA_CELL_BROADCAST_SMS_ENABLED = 0;
int CDMA_PHONE = 0;
int GSM_PHONE = 1;
@@ -50,6 +67,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 */
+
/*
cat include/telephony/ril.h | \
egrep '^#define' | \
@@ -64,9 +84,6 @@ cat include/telephony/ril.h | \
int RIL_SIM_PIN = 3;
int RIL_SIM_PUK = 4;
int RIL_SIM_NETWORK_PERSONALIZATION = 5;
- //TODO T: start
- // These RIL requests will not be renamed to ICC,
- // but these requests are also valid for SIM and RUIM
int RIL_REQUEST_GET_SIM_STATUS = 1;
int RIL_REQUEST_ENTER_SIM_PIN = 2;
int RIL_REQUEST_ENTER_SIM_PUK = 3;
@@ -74,7 +91,6 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_ENTER_SIM_PUK2 = 5;
int RIL_REQUEST_CHANGE_SIM_PIN = 6;
int RIL_REQUEST_CHANGE_SIM_PIN2 = 7;
- //TODO T: end
int RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION = 8;
int RIL_REQUEST_GET_CURRENT_CALLS = 9;
int RIL_REQUEST_DIAL = 10;
@@ -94,9 +110,7 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_DTMF = 24;
int RIL_REQUEST_SEND_SMS = 25;
int RIL_REQUEST_SEND_SMS_EXPECT_MORE = 26;
- int RIL_REQUEST_SETUP_DEFAULT_PDP = 27;
- //TODO T: This RIL request will not be renamed to ICC,
- // but this request is also valid for SIM and RUIM
+ int RIL_REQUEST_SETUP_DATA_CALL = 27;
int RIL_REQUEST_SIM_IO = 28;
int RIL_REQUEST_SEND_USSD = 29;
int RIL_REQUEST_CANCEL_USSD = 30;
@@ -110,7 +124,7 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_GET_IMEI = 38;
int RIL_REQUEST_GET_IMEISV = 39;
int RIL_REQUEST_ANSWER = 40;
- int RIL_REQUEST_DEACTIVATE_DEFAULT_PDP = 41;
+ int RIL_REQUEST_DEACTIVATE_DATA_CALL = 41;
int RIL_REQUEST_QUERY_FACILITY_LOCK = 42;
int RIL_REQUEST_SET_FACILITY_LOCK = 43;
int RIL_REQUEST_CHANGE_BARRING_PASSWORD = 44;
@@ -125,8 +139,8 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_SET_MUTE = 53;
int RIL_REQUEST_GET_MUTE = 54;
int RIL_REQUEST_QUERY_CLIP = 55;
- int RIL_REQUEST_LAST_PDP_FAIL_CAUSE = 56;
- int RIL_REQUEST_PDP_CONTEXT_LIST = 57;
+ int RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE = 56;
+ int RIL_REQUEST_DATA_CALL_LIST = 57;
int RIL_REQUEST_RESET_RADIO = 58;
int RIL_REQUEST_OEM_HOOK_RAW = 59;
int RIL_REQUEST_OEM_HOOK_STRINGS = 60;
@@ -164,14 +178,10 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG = 92;
int RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG = 93;
int RIL_REQUEST_CDMA_BROADCAST_ACTIVATION = 94;
- int RIL_REQUEST_SETUP_DATA_CALL = 95;
- int RIL_REQUEST_DEACTIVATE_DATA_CALL = 96;
- int RIL_REQUEST_CDMA_ENCODE_SMS = 97;
- int RIL_REQUEST_CDMA_DECODE_SMS = 98;
int RIL_REQUEST_CDMA_SUBSCRIPTION = 99;
int RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM = 100;
int RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM = 101;
- int RIL_REQUEST_DEVICE_IDENTITY = 102;
+ int RIL_REQUEST_DEVICE_IDENTITY = 102;
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
@@ -183,7 +193,7 @@ cat include/telephony/ril.h | \
int RIL_UNSOL_ON_USSD_REQUEST = 1007;
int RIL_UNSOL_NITZ_TIME_RECEIVED = 1008;
int RIL_UNSOL_SIGNAL_STRENGTH = 1009;
- int RIL_UNSOL_PDP_CONTEXT_LIST_CHANGED = 1010;
+ int RIL_UNSOL_DATA_CALL_LIST_CHANGED = 1010;
int RIL_UNSOL_SUPP_SVC_NOTIFICATION = 1011;
int RIL_UNSOL_STK_SESSION_END = 1012;
int RIL_UNSOL_STK_PROACTIVE_COMMAND = 1013;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index 9341709c4ee0..9947dc046015 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
import android.app.Activity;
import android.app.PendingIntent;
@@ -34,16 +34,16 @@ import android.os.Handler;
import android.os.Message;
import android.provider.Telephony;
import android.provider.Telephony.Sms.Intents;
-import android.telephony.gsm.SmsMessage;
-import android.telephony.gsm.SmsManager;
+import android.telephony.SmsMessage;
import android.telephony.ServiceState;
import android.util.Config;
+import android.util.Log;
+import android.view.WindowManager;
-import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.SmsMessageBase;
+import com.android.internal.telephony.SmsResponse;
import com.android.internal.util.HexDump;
-import android.util.Log;
-import android.view.WindowManager;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
@@ -52,87 +52,90 @@ import java.util.Random;
import com.android.internal.R;
-final class SMSDispatcher extends Handler {
- private static final String TAG = "GSM";
+import static android.telephony.SmsManager.RESULT_ERROR_GENERIC_FAILURE;
+import static android.telephony.SmsManager.RESULT_ERROR_NO_SERVICE;
+import static android.telephony.SmsManager.RESULT_ERROR_NULL_PDU;
+import static android.telephony.SmsManager.RESULT_ERROR_RADIO_OFF;
+
+
+public abstract class SMSDispatcher extends Handler {
+ private static final String TAG = "SMS";
- /** Default checking period for SMS sent without uesr permit */
+ /** Default checking period for SMS sent without user permit */
private static final int DEFAULT_SMS_CHECK_PERIOD = 3600000;
- /** Default number of SMS sent in checking period without uesr permit */
+ /** Default number of SMS sent in checking period without user permit */
private static final int DEFAULT_SMS_MAX_ALLOWED = 100;
/** Default timeout for SMS sent query */
private static final int DEFAULT_SMS_TIMOUEOUT = 6000;
- private static final int WAP_PDU_TYPE_PUSH = 0x06;
+ protected static final int WAP_PDU_TYPE_PUSH = 0x06;
- private static final int WAP_PDU_TYPE_CONFIRMED_PUSH = 0x07;
+ protected static final int WAP_PDU_TYPE_CONFIRMED_PUSH = 0x07;
- private static final byte DRM_RIGHTS_XML = (byte)0xca;
+ protected static final byte DRM_RIGHTS_XML = (byte)0xca;
- private static final String DRM_RIGHTS_XML_MIME_TYPE = "application/vnd.oma.drm.rights+xml";
+ protected static final String DRM_RIGHTS_XML_MIME_TYPE = "application/vnd.oma.drm.rights+xml";
- private static final byte DRM_RIGHTS_WBXML = (byte)0xcb;
+ protected static final byte DRM_RIGHTS_WBXML = (byte)0xcb;
- private static final String DRM_RIGHTS_WBXML_MIME_TYPE =
+ protected static final String DRM_RIGHTS_WBXML_MIME_TYPE =
"application/vnd.oma.drm.rights+wbxml";
- private static final byte WAP_SI_MIME_PORT = (byte)0xae;
+ protected static final byte WAP_SI_MIME_PORT = (byte)0xae;
- private static final String WAP_SI_MIME_TYPE = "application/vnd.wap.sic";
+ protected static final String WAP_SI_MIME_TYPE = "application/vnd.wap.sic";
- private static final byte WAP_SL_MIME_PORT = (byte)0xb0;
+ protected static final byte WAP_SL_MIME_PORT = (byte)0xb0;
- private static final String WAP_SL_MIME_TYPE = "application/vnd.wap.slc";
+ protected static final String WAP_SL_MIME_TYPE = "application/vnd.wap.slc";
- private static final byte WAP_CO_MIME_PORT = (byte)0xb2;
+ protected static final byte WAP_CO_MIME_PORT = (byte)0xb2;
- private static final String WAP_CO_MIME_TYPE = "application/vnd.wap.coc";
+ protected static final String WAP_CO_MIME_TYPE = "application/vnd.wap.coc";
- private static final int WAP_PDU_SHORT_LENGTH_MAX = 30;
+ protected static final int WAP_PDU_SHORT_LENGTH_MAX = 30;
- private static final int WAP_PDU_LENGTH_QUOTE = 31;
+ protected static final int WAP_PDU_LENGTH_QUOTE = 31;
- private static final String MMS_MIME_TYPE = "application/vnd.wap.mms-message";
+ protected static final String MMS_MIME_TYPE = "application/vnd.wap.mms-message";
- private static final String[] RAW_PROJECTION = new String[] {
+ protected static final String[] RAW_PROJECTION = new String[] {
"pdu",
"sequence",
};
static final int MAIL_SEND_SMS = 1;
- static final int EVENT_NEW_SMS = 1;
+ static final protected int EVENT_NEW_SMS = 1;
- static final int EVENT_SEND_SMS_COMPLETE = 2;
+ static final protected int EVENT_SEND_SMS_COMPLETE = 2;
/** Retry sending a previously failed SMS message */
- static final int EVENT_SEND_RETRY = 3;
+ static final protected int EVENT_SEND_RETRY = 3;
/** Status report received */
- static final int EVENT_NEW_SMS_STATUS_REPORT = 5;
+ static final protected int EVENT_NEW_SMS_STATUS_REPORT = 5;
- /** SIM storage is full */
- static final int EVENT_SIM_FULL = 6;
+ /** SIM/RUIM storage is full */
+ static final protected int EVENT_ICC_FULL = 6;
/** SMS confirm required */
- static final int EVENT_POST_ALERT = 7;
+ static final protected int EVENT_POST_ALERT = 7;
/** Send the user confirmed SMS */
- static final int EVENT_SEND_CONFIRMED_SMS = 8;
+ static final protected int EVENT_SEND_CONFIRMED_SMS = 8;
/** Alert is timeout */
- static final int EVENT_ALERT_TIMEOUT = 9;
+ static final protected int EVENT_ALERT_TIMEOUT = 9;
- private final GSMPhone mPhone;
+ protected Phone mPhone;
+ protected Context mContext;
+ protected ContentResolver mResolver;
+ protected CommandsInterface mCm;
- private final Context mContext;
-
- private final ContentResolver mResolver;
-
- private final CommandsInterface mCm;
-
- private final Uri mRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw");
+ protected final Uri mRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw");
/** Maximum number of times to retry sending a failed SMS. */
private static final int MAX_SEND_RETRIES = 3;
@@ -144,12 +147,16 @@ final class SMSDispatcher extends Handler {
* CONCATENATED_16_BIT_REFERENCE message set. Should be
* incremented for each set of concatenated messages.
*/
- private static int sConcatenatedRef;
+ protected static int sConcatenatedRef;
private SmsCounter mCounter;
private SmsTracker mSTracker;
+ private static SmsMessage mSmsMessage;
+ private static SmsMessageBase mSmsMessageBase;
+ private SmsMessageBase.SubmitPduBase mSubmitPduBase;
+
/**
* Implement the per-application based SMS control, which only allows
* a limit on the number of SMS/MMS messages an app can send in checking
@@ -196,7 +203,7 @@ final class SMSDispatcher extends Handler {
}
}
- SMSDispatcher(GSMPhone phone) {
+ protected SMSDispatcher(PhoneBase phone) {
mPhone = phone;
mContext = phone.getContext();
mResolver = mContext.getContentResolver();
@@ -207,19 +214,30 @@ final class SMSDispatcher extends Handler {
mCm.setOnNewSMS(this, EVENT_NEW_SMS, null);
mCm.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null);
- mCm.setOnSimSmsFull(this, EVENT_SIM_FULL, null);
+ mCm.setOnIccSmsFull(this, EVENT_ICC_FULL, null);
// Don't always start message ref at 0.
sConcatenatedRef = new Random().nextInt(256);
}
+ public void dispose() {
+ mCm.unSetOnNewSMS(this);
+ mCm.unSetOnSmsStatus(this);
+ mCm.unSetOnIccSmsFull(this);
+ }
+
+ protected void finalize() {
+ Log.d(TAG, "SMSDispatcher finalized");
+ }
+
+
/* TODO: Need to figure out how to keep track of status report routing in a
* persistent manner. If the phone process restarts (reboot or crash),
* we will lose this list and any status reports that come in after
* will be dropped.
*/
/** Sent messages awaiting a delivery status report. */
- private final ArrayList<SmsTracker> deliveryPendingList = new ArrayList<SmsTracker>();
+ protected final ArrayList<SmsTracker> deliveryPendingList = new ArrayList<SmsTracker>();
/**
* Handles events coming from the phone stack. Overridden from handler.
@@ -241,11 +259,8 @@ final class SMSDispatcher extends Handler {
ar = (AsyncResult) msg.obj;
- // FIXME unit test leaves cm == null. this should change
- if (mCm != null) {
// FIXME only acknowledge on store
- mCm.acknowledgeLastIncomingSMS(true, null);
- }
+ acknowledgeLastIncomingSms(true, null);
if (ar.exception != null) {
Log.e(TAG, "Exception processing incoming SMS",
@@ -254,12 +269,12 @@ final class SMSDispatcher extends Handler {
}
sms = (SmsMessage) ar.result;
- dispatchMessage(sms);
+ dispatchMessage(sms.mWrappedSmsMessage);
break;
case EVENT_SEND_SMS_COMPLETE:
- // An outbound SMS has been sucessfully transferred, or failed.
+ // An outbound SMS has been successfully transferred, or failed.
handleSendComplete((AsyncResult) msg.obj);
break;
@@ -271,8 +286,8 @@ final class SMSDispatcher extends Handler {
handleStatusReport((AsyncResult)msg.obj);
break;
- case EVENT_SIM_FULL:
- handleSimFull();
+ case EVENT_ICC_FULL:
+ handleIccFull();
break;
case EVENT_POST_ALERT:
@@ -299,7 +314,7 @@ final class SMSDispatcher extends Handler {
* Called when SIM_FULL message is received from the RIL. Notifies interested
* parties that SIM storage for SMS messages is full.
*/
- private void handleSimFull() {
+ private void handleIccFull(){
// broadcast SIM_FULL intent
Intent intent = new Intent(Intents.SIM_FULL_ACTION);
mPhone.getContext().sendBroadcast(intent, "android.permission.RECEIVE_SMS");
@@ -312,34 +327,7 @@ final class SMSDispatcher extends Handler {
* @param ar AsyncResult passed into the message handler. ar.result should
* be a String representing the status report PDU, as ASCII hex.
*/
- private void handleStatusReport(AsyncResult ar) {
- String pduString = (String) ar.result;
- SmsMessage sms = SmsMessage.newFromCDS(pduString);
-
- if (sms != null) {
- int messageRef = sms.messageRef;
- for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
- SmsTracker tracker = deliveryPendingList.get(i);
- if (tracker.mMessageRef == messageRef) {
- // Found it. Remove from list and broadcast.
- deliveryPendingList.remove(i);
- PendingIntent intent = tracker.mDeliveryIntent;
- Intent fillIn = new Intent();
- fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
- try {
- intent.send(mContext, Activity.RESULT_OK, fillIn);
- } catch (CanceledException ex) {}
-
- // Only expect to see one tracker matching this messageref
- break;
- }
- }
- }
-
- if (mCm != null) {
- mCm.acknowledgeLastIncomingSMS(true, null);
- }
- }
+ protected abstract void handleStatusReport(AsyncResult ar);
/**
* Called when SMS send completes. Broadcasts a sentIntent on success.
@@ -350,7 +338,7 @@ final class SMSDispatcher extends Handler {
* an SmsResponse instance if send was successful. ar.userObj
* should be an SmsTracker instance.
*/
- private void handleSendComplete(AsyncResult ar) {
+ protected void handleSendComplete(AsyncResult ar) {
SmsTracker tracker = (SmsTracker) ar.userObj;
PendingIntent sentIntent = tracker.mSentIntent;
@@ -398,7 +386,7 @@ final class SMSDispatcher extends Handler {
} else if (tracker.mSentIntent != null) {
// Done retrying; return an error to the app.
try {
- tracker.mSentIntent.send(SmsManager.RESULT_ERROR_GENERIC_FAILURE);
+ tracker.mSentIntent.send(RESULT_ERROR_GENERIC_FAILURE);
} catch (CanceledException ex) {}
}
}
@@ -413,13 +401,13 @@ final class SMSDispatcher extends Handler {
* POWER_OFF
* @param tracker An SmsTracker for the current message.
*/
- private void handleNotInService(int ss, SmsTracker tracker) {
+ protected void handleNotInService(int ss, SmsTracker tracker) {
if (tracker.mSentIntent != null) {
try {
if (ss == ServiceState.STATE_POWER_OFF) {
- tracker.mSentIntent.send(SmsManager.RESULT_ERROR_RADIO_OFF);
+ tracker.mSentIntent.send(RESULT_ERROR_RADIO_OFF);
} else {
- tracker.mSentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE);
+ tracker.mSentIntent.send(RESULT_ERROR_NO_SERVICE);
}
} catch (CanceledException ex) {}
}
@@ -430,108 +418,14 @@ final class SMSDispatcher extends Handler {
*
* @param sms the incoming message from the phone
*/
- /* package */ void dispatchMessage(SmsMessage sms) {
- boolean handled = false;
-
- // Special case the message waiting indicator messages
- if (sms.isMWISetMessage()) {
- 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()) {
- mPhone.updateMessageWaitingIndicator(false);
-
- if (sms.isMwiDontStore()) {
- handled = true;
- }
-
- if (Config.LOGD) {
- Log.d(TAG,
- "Received voice mail indicator clear SMS shouldStore="
- + !handled);
- }
- }
-
- if (handled) {
- return;
- }
-
- // 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()) {
- 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;
-
- break;
- }
+ protected abstract void dispatchMessage(SmsMessageBase sms);
- 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;
-
- break;
- }
-
- case SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT: {
- byte[] data = element.getData();
-
- destPort = (data[0] & 0xff) << 8;
- destPort |= (data[1] & 0xff);
-
- break;
- }
- }
- }
- }
-
- if (referenceNumber == -1) {
- // notify everyone of the message if it isn't partial
- byte[][] pdus = new byte[1][];
- pdus[0] = sms.getPdu();
-
- if (destPort != -1) {
- if (destPort == SmsHeader.PORT_WAP_PUSH) {
- dispatchWapPdu(sms.getUserData());
- }
- // The message was sent to a port, so concoct a URI for it
- dispatchPortAddressedPdus(pdus, destPort);
- } else {
- // It's a normal message, dispatch it
- dispatchPdus(pdus);
- }
- } else {
- // Process the message part
- processMessagePart(sms, referenceNumber, sequence, count, destPort);
- }
- }
/**
* If this is the last part send the parts out to the application, otherwise
* the part is stored for later processing.
*/
- private void processMessagePart(SmsMessage sms, int referenceNumber,
+ protected void processMessagePart(SmsMessageBase sms, int referenceNumber,
int sequence, int count, int destinationPort) {
// Lookup all other related parts
StringBuilder where = new StringBuilder("reference_number =");
@@ -617,7 +511,7 @@ final class SMSDispatcher extends Handler {
*
* @param pdus The raw PDUs making up the message
*/
- private void dispatchPdus(byte[][] pdus) {
+ protected void dispatchPdus(byte[][] pdus) {
Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);
intent.putExtra("pdus", pdus);
mPhone.getContext().sendBroadcast(
@@ -630,7 +524,7 @@ final class SMSDispatcher extends Handler {
* @param pdus The raw PDUs making up the message
* @param port The destination port of the messages
*/
- private void dispatchPortAddressedPdus(byte[][] pdus, int port) {
+ protected void dispatchPortAddressedPdus(byte[][] pdus, int port) {
Uri uri = Uri.parse("sms://localhost:" + port);
Intent intent = new Intent(Intents.DATA_SMS_RECEIVED_ACTION, uri);
intent.putExtra("pdus", pdus);
@@ -644,7 +538,7 @@ final class SMSDispatcher extends Handler {
*
* @param pdu The WAP PDU, made up of one or more SMS PDUs
*/
- private void dispatchWapPdu(byte[] pdu) {
+ protected void dispatchWapPdu(byte[] pdu) {
int index = 0;
int transactionId = pdu[index++] & 0xFF;
int pduType = pdu[index++] & 0xFF;
@@ -728,7 +622,7 @@ final class SMSDispatcher extends Handler {
int dataIndex = headerStartIndex + headerLength;
byte[] data;
if (pdu[headerStartIndex] == WAP_CO_MIME_PORT) {
- // because SMSDispatcher can't parse push headers "Content-Location" and
+ // because GsmSMSDispatcher can't parse push headers "Content-Location" and
// X-Wap-Content-URI, so pass the whole push to CO application.
data = pdu;
} else {
@@ -777,35 +671,9 @@ final class SMSDispatcher extends Handler {
* to the recipient. The raw pdu of the status report is in the
* extended data ("pdu").
*/
- 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;
-
- if (sentIntents != null && sentIntents.size() > i) {
- sentIntent = sentIntents.get(i);
- }
- if (deliveryIntents != null && deliveryIntents.size() > i) {
- deliveryIntent = deliveryIntents.get(i);
- }
-
- SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
- parts.get(i), deliveryIntent != null, header.toByteArray());
-
- sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
- }
- }
+ protected abstract void sendMultipartText(String destinationAddress, String scAddress,
+ ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
+ ArrayList<PendingIntent> deliveryIntents);
/**
* Send a SMS
@@ -827,12 +695,12 @@ final class SMSDispatcher extends Handler {
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*/
- void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
+ protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
if (pdu == null) {
if (sentIntent != null) {
try {
- sentIntent.send(SmsManager.RESULT_ERROR_NULL_PDU);
+ sentIntent.send(RESULT_ERROR_NULL_PDU);
} catch (CanceledException ex) {}
}
return;
@@ -863,7 +731,7 @@ final class SMSDispatcher extends Handler {
*
* An SmsTracker for the current message.
*/
- private void handleReachSentLimit(SmsTracker tracker) {
+ protected void handleReachSentLimit(SmsTracker tracker) {
Resources r = Resources.getSystem();
@@ -884,7 +752,7 @@ final class SMSDispatcher extends Handler {
DEFAULT_SMS_TIMOUEOUT);
}
- private String getAppNameByIntent(PendingIntent intent) {
+ protected String getAppNameByIntent(PendingIntent intent) {
Resources r = Resources.getSystem();
return (intent != null) ? intent.getTargetPackage()
: r.getString(R.string.sms_control_default_app_name);
@@ -895,29 +763,59 @@ final class SMSDispatcher extends Handler {
*
* @param tracker holds the SMS message to send
*/
- private void sendSms(SmsTracker tracker) {
- HashMap map = tracker.mData;
+ protected abstract void sendSms(SmsTracker tracker);
- byte smsc[] = (byte[]) map.get("smsc");
- byte pdu[] = (byte[]) map.get("pdu");
+ /**
+ * Activate or deactivate cell broadcast SMS.
+ *
+ * @param activate
+ * 0 = activate, 1 = deactivate
+ * @param response
+ * Callback message is empty on completion
+ */
+ protected abstract void activateCellBroadcastSms(int activate, Message response);
- Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
- mCm.sendSMS(IccUtils.bytesToHexString(smsc),
- IccUtils.bytesToHexString(pdu), reply);
- }
+ /**
+ * Query the current configuration of cell broadcast SMS.
+ *
+ * @param response
+ * Callback message contains the configuration from the modem on completion
+ * @see #setCellBroadcastConfig
+ */
+ protected abstract void getCellBroadcastSmsConfig(Message response);
+
+ /**
+ * Configure cell broadcast SMS.
+ *
+ * @param configValuesArray
+ * The first element defines the number of triples that follow.
+ * A triple is made up of the service category, the language identifier
+ * and a boolean that specifies whether the category is set active.
+ * @param response
+ * Callback message is empty on completion
+ */
+ protected abstract void setCellBroadcastConfig(int[] configValuesArray, Message response);
+
+ /**
+ * Send an acknowledge message.
+ * @param success indicates that last message was successfully received.
+ * @param response callback message sent when operation completes.
+ */
+ protected abstract void acknowledgeLastIncomingSms(boolean success, Message response);
/**
* Keeps track of an SMS that has been sent to the RIL, until it it has
* successfully been sent, or we're done trying.
*
*/
- static class SmsTracker {
- HashMap mData;
- int mRetryCount;
- int mMessageRef;
+ static protected class SmsTracker {
+ // fields need to be public for derived SmsDispatchers
+ public HashMap mData;
+ public int mRetryCount;
+ public int mMessageRef;
- PendingIntent mSentIntent;
- PendingIntent mDeliveryIntent;
+ public PendingIntent mSentIntent;
+ public PendingIntent mDeliveryIntent;
SmsTracker(HashMap data, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
@@ -926,17 +824,17 @@ final class SMSDispatcher extends Handler {
mDeliveryIntent = deliveryIntent;
mRetryCount = 0;
}
-
}
private DialogInterface.OnClickListener mListener =
- new DialogInterface.OnClickListener() {
+ new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- if (which == DialogInterface.BUTTON1) {
- Log.d(TAG, "click YES to send out sms");
- sendMessage(obtainMessage(EVENT_SEND_CONFIRMED_SMS));
- }
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == DialogInterface.BUTTON1) {
+ Log.d(TAG, "click YES to send out sms");
+ sendMessage(obtainMessage(EVENT_SEND_CONFIRMED_SMS));
}
- };
+ }
+ };
}
+
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 1d3a44acd100..b71c23134686 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -71,10 +71,7 @@ public abstract class ServiceStateTracker extends Handler {
// signal strength poll rate
protected static final int POLL_PERIOD_MILLIS = 20 * 1000;
-
//*****GSM events
- //TODO Have to be extended with CDMA events
-
protected static final int EVENT_RADIO_STATE_CHANGED = 1;
protected static final int EVENT_NETWORK_STATE_CHANGED = 2;
protected static final int EVENT_GET_SIGNAL_STRENGTH = 3;
@@ -94,20 +91,18 @@ public abstract class ServiceStateTracker extends Handler {
protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE = 20;
protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE = 21;
-
//*****CDMA events:
- protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA = 22;
- protected static final int EVENT_POLL_STATE_OPERATOR_CDMA = 23;
- protected static final int EVENT_RUIM_READY = 24;
- protected static final int EVENT_RUIM_RECORDS_LOADED = 25;
+ protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA = 22;
+ protected static final int EVENT_POLL_STATE_OPERATOR_CDMA = 23;
+ protected static final int EVENT_RUIM_READY = 24;
+ protected static final int EVENT_RUIM_RECORDS_LOADED = 25;
protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE_CDMA = 26;
- protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA = 27;
- protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA = 28;
- protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA = 29;
- protected static final int EVENT_GET_LOC_DONE_CDMA = 30;
- protected static final int EVENT_SIGNAL_STRENGTH_UPDATE_CDMA = 31;
-
- protected static final int EVENT_NV_LOADED = 32;
+ protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA = 27;
+ protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA = 28;
+ protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA = 29;
+ protected static final int EVENT_GET_LOC_DONE_CDMA = 30;
+ protected static final int EVENT_SIGNAL_STRENGTH_UPDATE_CDMA = 31;
+ protected static final int EVENT_NV_LOADED = 32;
//***** Time Zones
protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
@@ -143,7 +138,6 @@ public abstract class ServiceStateTracker extends Handler {
//***** Constructors
public ServiceStateTracker() {
-
}
@@ -164,6 +158,10 @@ public abstract class ServiceStateTracker extends Handler {
}
}
+ public void unregisterForRoamingOn(Handler h) {
+ roamingOnRegistrants.remove(h);
+ }
+
/**
* Registration point for combined roaming off
* combined roaming is true when roaming is true and ONS differs SPN
@@ -180,7 +178,11 @@ public abstract class ServiceStateTracker extends Handler {
r.notifyRegistrant();
}
}
-
+
+ public void unregisterForRoamingOff(Handler h) {
+ roamingOffRegistrants.remove(h);
+ }
+
/**
* Reregister network through toggle perferred network type
* This is a work aorund to deregister and register network since there is
@@ -219,7 +221,7 @@ public abstract class ServiceStateTracker extends Handler {
//***** Protected abstract Methods
protected abstract void handlePollStateResult(int what, AsyncResult ar);
protected abstract void updateSpnDisplay();
-
+
// ***** Private Instance Methods
protected void
setPowerStateToDesired() {
diff --git a/telephony/java/com/android/internal/telephony/SmsAddress.java b/telephony/java/com/android/internal/telephony/SmsAddress.java
new file mode 100644
index 000000000000..b3892cb0b342
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/SmsAddress.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+public abstract class SmsAddress {
+ // From TS 23.040 9.1.2.5 and TS 24.008 table 10.5.118
+ // and C.S0005-D table 2.7.1.3.2.4-2
+ public static final int TON_UNKNOWN = 0;
+ public static final int TON_INTERNATIONAL = 1;
+ public static final int TON_NATIONAL = 2;
+ public static final int TON_NETWORK = 3;
+ public static final int TON_SUBSCRIBER = 4;
+ public static final int TON_ALPHANUMERIC = 5;
+ public static final int TON_ABBREVIATED = 6;
+
+ public int ton;
+ public String address;
+ public byte[] origBytes;
+
+ /**
+ * Returns the address of the SMS message in String form or null if unavailable
+ */
+ public String getAddressString() {
+ return address;
+ }
+
+ /**
+ * Returns true if this is an alphanumeric address
+ */
+ public boolean isAlphanumeric() {
+ return ton == TON_ALPHANUMERIC;
+ }
+
+ /**
+ * Returns true if this is a network address
+ */
+ public boolean isNetworkSpecific() {
+ return ton == TON_NETWORK;
+ }
+
+ public boolean couldBeEmailGateway() {
+ // Some carriers seems to send email gateway messages in this form:
+ // from: an UNKNOWN TON, 3 or 4 digits long, beginning with a 5
+ // PID: 0x00, Data coding scheme 0x03
+ // So we just attempt to treat any message from an address length <= 4
+ // as an email gateway
+
+ return address.length() <= 4;
+ }
+
+}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsHeader.java b/telephony/java/com/android/internal/telephony/SmsHeader.java
index 22366ecdb030..64b884efa0c5 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsHeader.java
+++ b/telephony/java/com/android/internal/telephony/SmsHeader.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
import com.android.internal.util.HexDump;
@@ -24,8 +24,7 @@ import java.util.ArrayList;
* This class represents a SMS user data header.
*
*/
-public class SmsHeader
-{
+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. */
@@ -42,6 +41,7 @@ public class SmsHeader
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.
@@ -49,36 +49,33 @@ public class SmsHeader
* @param data is user data header bytes
* @return an SmsHeader object
*/
- public static SmsHeader parse(byte[] data)
- {
+ public static SmsHeader parse(byte[] data) {
SmsHeader header = new SmsHeader();
header.m_data = data;
int index = 0;
- while (index < data.length)
- {
+ 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++;
}
return header;
}
- public SmsHeader()
- {
- }
+ public SmsHeader() { }
/**
* Returns the list of SmsHeader Elements that make up the header.
*
* @return the list of SmsHeader Elements.
*/
- public ArrayList<Element> getElements()
- {
+ public ArrayList<Element> getElements() {
return m_elements;
}
@@ -87,14 +84,12 @@ public class SmsHeader
*
* @param element to add.
*/
- public void add(Element element)
- {
+ public void add(Element element) {
m_elements.add(element);
}
@Override
- public String toString()
- {
+ public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("UDH LENGTH: " + m_data.length + " octets");
@@ -104,40 +99,56 @@ public class SmsHeader
for (Element e : getElements()) {
builder.append(" 0x" + HexDump.toHexString((byte)e.getID()) + " - ");
- switch (e.getID())
- {
- case CONCATENATED_8_BIT_REFERENCE:
- {
+ 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(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:
- {
+ 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(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_16_BIT:
+ 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");
+ builder.append(HexDump.toHexString((byte)data.length)
+ + ") Bytes - Information Element\n");
int source = (data[0] & 0xff) << 8;
source |= (data[1] & 0xff);
@@ -149,8 +160,7 @@ public class SmsHeader
break;
}
- default:
- {
+ default: {
builder.append("Unknown element\n");
break;
}
@@ -202,13 +212,11 @@ public class SmsHeader
* See TS 23.040 9.2.3.24.
*
*/
- public static class Element
- {
+ public static class Element {
private byte[] m_data;
private int m_id;
- public Element(int id, byte[] data)
- {
+ public Element(int id, byte[] data) {
m_id = id;
m_data = data;
}
@@ -218,8 +226,7 @@ public class SmsHeader
*
* @return the IE identifier.
*/
- public int getID()
- {
+ public int getID() {
return m_id;
}
@@ -228,8 +235,7 @@ public class SmsHeader
*
* @return element data.
*/
- public byte[] getData()
- {
+ public byte[] getData() {
return m_data;
}
}
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
new file mode 100644
index 000000000000..7c324511b2b9
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.util.Log;
+import com.android.internal.telephony.SmsHeader;
+import java.util.Arrays;
+
+import static android.telephony.SmsMessage.ENCODING_7BIT;
+import static android.telephony.SmsMessage.ENCODING_16BIT;
+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;
+import static android.telephony.SmsMessage.MessageClass;
+import static com.android.internal.telephony.SmsAddress.TON_ABBREVIATED;
+import static com.android.internal.telephony.SmsAddress.TON_ALPHANUMERIC;
+import static com.android.internal.telephony.SmsAddress.TON_INTERNATIONAL;
+import static com.android.internal.telephony.SmsAddress.TON_NATIONAL;
+import static com.android.internal.telephony.SmsAddress.TON_NETWORK;
+import static com.android.internal.telephony.SmsAddress.TON_SUBSCRIBER;
+import static com.android.internal.telephony.SmsAddress.TON_UNKNOWN;
+
+/**
+ * Base class declaring the specific methods and members for SmsMessage.
+ * {@hide}
+ */
+public abstract class SmsMessageBase {
+ private static final String LOG_TAG = "SMS";
+
+ /** {@hide} The address of the SMSC. May be null */
+ protected String scAddress;
+
+ /** {@hide} The address of the sender */
+ protected SmsAddress originatingAddress;
+
+ /** {@hide} The message body as a string. May be null if the message isn't text */
+ protected String messageBody;
+
+ /** {@hide} */
+ protected String pseudoSubject;
+
+ /** {@hide} Non-null if this is an email gateway message */
+ protected String emailFrom;
+
+ /** {@hide} Non-null if this is an email gateway message */
+ protected String emailBody;
+
+ /** {@hide} */
+ protected boolean isEmail;
+
+ /** {@hide} */
+ protected long scTimeMillis;
+
+ /** {@hide} The raw PDU of the message */
+ protected byte[] mPdu;
+
+ /** {@hide} The raw bytes for the user data section of the message */
+ protected byte[] userData;
+
+ /** {@hide} */
+ protected SmsHeader userDataHeader;
+
+ // "Message Waiting Indication Group"
+ // 23.038 Section 4
+ /** {@hide} */
+ protected boolean isMwi;
+
+ /** {@hide} */
+ protected boolean mwiSense;
+
+ /** {@hide} */
+ protected boolean mwiDontStore;
+
+ /**
+ * Indicates status for messages stored on the ICC.
+ */
+ protected int statusOnIcc = -1;
+
+ /**
+ * Record index of message in the EF.
+ */
+ protected int indexOnIcc = -1;
+
+ /** TP-Message-Reference - Message Reference of sent message. @hide */
+ public int messageRef;
+
+ public static abstract class SubmitPduBase {
+ public byte[] encodedScAddress; // Null if not applicable.
+ public byte[] encodedMessage;
+
+ public String toString() {
+ return "SubmitPdu: encodedScAddress = "
+ + Arrays.toString(encodedScAddress)
+ + ", encodedMessage = "
+ + Arrays.toString(encodedMessage);
+ }
+ }
+
+ /**
+ * Returns the address of the SMS service center that relayed this message
+ * or null if there is none.
+ */
+ public String getServiceCenterAddress() {
+ return scAddress;
+ }
+
+ /**
+ * Returns the originating address (sender) of this SMS message in String
+ * form or null if unavailable
+ */
+ public String getOriginatingAddress() {
+ if (originatingAddress == null) {
+ return null;
+ }
+
+ return originatingAddress.getAddressString();
+ }
+
+ /**
+ * Returns the originating address, or email from address if this message
+ * was from an email gateway. Returns null if originating address
+ * unavailable.
+ */
+ public String getDisplayOriginatingAddress() {
+ if (isEmail) {
+ return emailFrom;
+ } else {
+ return getOriginatingAddress();
+ }
+ }
+
+ /**
+ * Returns the message body as a String, if it exists and is text based.
+ * @return message body is there is one, otherwise null
+ */
+ public String getMessageBody() {
+ return messageBody;
+ }
+
+ /**
+ * Returns the class of this message.
+ */
+ public abstract MessageClass getMessageClass();
+
+ /**
+ * Returns the message body, or email message body if this message was from
+ * an email gateway. Returns null if message body unavailable.
+ */
+ public String getDisplayMessageBody() {
+ if (isEmail) {
+ return emailBody;
+ } else {
+ return getMessageBody();
+ }
+ }
+
+ /**
+ * Unofficial convention of a subject line enclosed in parens empty string
+ * if not present
+ */
+ public String getPseudoSubject() {
+ return pseudoSubject == null ? "" : pseudoSubject;
+ }
+
+ /**
+ * Returns the service centre timestamp in currentTimeMillis() format
+ */
+ public long getTimestampMillis() {
+ return scTimeMillis;
+ }
+
+ /**
+ * Returns true if message is an email.
+ *
+ * @return true if this message came through an email gateway and email
+ * sender / subject / parsed body are available
+ */
+ public boolean isEmail() {
+ return isEmail;
+ }
+
+ /**
+ * @return if isEmail() is true, body of the email sent through the gateway.
+ * null otherwise
+ */
+ public String getEmailBody() {
+ return emailBody;
+ }
+
+ /**
+ * @return if isEmail() is true, email from address of email sent through
+ * the gateway. null otherwise
+ */
+ public String getEmailFrom() {
+ return emailFrom;
+ }
+
+ /**
+ * Get protocol identifier.
+ */
+ public abstract int getProtocolIdentifier();
+
+ /**
+ * See TS 23.040 9.2.3.9 returns true if this is a "replace short message"
+ * SMS
+ */
+ public abstract boolean isReplace();
+
+ /**
+ * Returns true for CPHS MWI toggle message.
+ *
+ * @return true if this is a CPHS MWI toggle message See CPHS 4.2 section
+ * B.4.2
+ */
+ public abstract boolean isCphsMwiMessage();
+
+ /**
+ * returns true if this message is a CPHS voicemail / message waiting
+ * indicator (MWI) clear message
+ */
+ public abstract boolean isMWIClearMessage();
+
+ /**
+ * returns true if this message is a CPHS voicemail / message waiting
+ * indicator (MWI) set message
+ */
+ public abstract boolean isMWISetMessage();
+
+ /**
+ * returns true if this message is a "Message Waiting Indication Group:
+ * Discard Message" notification and should not be stored.
+ */
+ public abstract boolean isMwiDontStore();
+
+ /**
+ * returns the user data section minus the user data header if one was
+ * present.
+ */
+ public byte[] getUserData() {
+ return userData;
+ }
+
+ /**
+ * Returns an object representing the user data header
+ *
+ * @return an object representing the user data header
+ *
+ * {@hide}
+ */
+ public SmsHeader getUserDataHeader() {
+ return userDataHeader;
+ }
+
+ /**
+ * Returns the raw PDU for the message.
+ *
+ * @return the raw PDU for the message.
+ */
+ public byte[] getPdu() {
+ return mPdu;
+ }
+
+ /**
+ * For an SMS-STATUS-REPORT message, this returns the status field from
+ * the status report. This field indicates the status of a previously
+ * submitted SMS, if requested. See TS 23.040, 9.2.3.15 TP-Status for a
+ * description of values.
+ *
+ * @return 0 indicates the previously sent message was received.
+ * See TS 23.040, 9.9.2.3.15 for a description of other possible
+ * values.
+ */
+ public abstract int getStatus();
+
+ /**
+ * Return true iff the message is a SMS-STATUS-REPORT message.
+ */
+ public abstract boolean isStatusReportMessage();
+
+ /**
+ * Returns true iff the <code>TP-Reply-Path</code> bit is set in
+ * this message.
+ */
+ public abstract boolean isReplyPathPresent();
+
+ /**
+ * Returns the status of the message on the ICC (read, unread, sent, unsent).
+ *
+ * @return the status of the message on the ICC. These are:
+ * SmsManager.STATUS_ON_ICC_FREE
+ * SmsManager.STATUS_ON_ICC_READ
+ * SmsManager.STATUS_ON_ICC_UNREAD
+ * SmsManager.STATUS_ON_ICC_SEND
+ * SmsManager.STATUS_ON_ICC_UNSENT
+ */
+ public int getStatusOnIcc() {
+ return statusOnIcc;
+ }
+
+ /**
+ * Returns the record index of the message on the ICC (1-based index).
+ * @return the record index of the message on the ICC, or -1 if this
+ * SmsMessage was not created from a ICC SMS EF record.
+ */
+ public int getIndexOnIcc() {
+ return indexOnIcc;
+ }
+
+ protected void parseMessageBody() {
+ if (originatingAddress.couldBeEmailGateway()) {
+ extractEmailAddressFromMessageBody();
+ }
+ }
+
+ /**
+ * Try to parse this message as an email gateway message -> Neither
+ * of the standard ways are currently supported: There are two ways
+ * specified in TS 23.040 Section 3.8 (not supported via this mechanism) -
+ * SMS message "may have its TP-PID set for internet electronic mail - MT
+ * SMS format: [<from-address><space>]<message> - "Depending on the
+ * nature of the gateway, the destination/origination address is either
+ * derived from the content of the SMS TP-OA or TP-DA field, or the
+ * TP-OA/TP-DA field contains a generic gateway address and the to/from
+ * address is added at the beginning as shown above." - multiple addreses
+ * separated by commas, no spaces - subject field delimited by '()' or '##'
+ * and '#' Section 9.2.3.24.11
+ */
+ protected void extractEmailAddressFromMessageBody() {
+
+ /*
+ * a little guesswork here. I haven't found doc for this.
+ * the format could be either
+ *
+ * 1. [x@y][ ]/[subject][ ]/[body]
+ * -or-
+ * 2. [x@y][ ]/[body]
+ */
+ int slash = 0, slash2 = 0, atSymbol = 0;
+
+ try {
+ slash = messageBody.indexOf(" /");
+ if (slash == -1) {
+ return;
+ }
+
+ atSymbol = messageBody.indexOf('@');
+ if (atSymbol == -1 || atSymbol > slash) {
+ return;
+ }
+
+ emailFrom = messageBody.substring(0, slash);
+
+ slash2 = messageBody.indexOf(" /", slash + 2);
+
+ if (slash2 == -1) {
+ pseudoSubject = null;
+ emailBody = messageBody.substring(slash + 2);
+ } else {
+ pseudoSubject = messageBody.substring(slash + 2, slash2);
+ emailBody = messageBody.substring(slash2 + 2);
+ }
+
+ isEmail = true;
+ } catch (Exception ex) {
+ Log.w(LOG_TAG,
+ "extractEmailAddressFromMessageBody: exception slash="
+ + slash + ", atSymbol=" + atSymbol + ", slash2="
+ + slash2, ex);
+ }
+ }
+
+}
+
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsRawData.aidl b/telephony/java/com/android/internal/telephony/SmsRawData.aidl
index 6f1a46dc9203..b0b3e4f93f57 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsRawData.aidl
+++ b/telephony/java/com/android/internal/telephony/SmsRawData.aidl
@@ -14,6 +14,6 @@
** limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
parcelable SmsRawData;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsRawData.java b/telephony/java/com/android/internal/telephony/SmsRawData.java
index a029d5ce59f8..891d942b9a13 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsRawData.java
+++ b/telephony/java/com/android/internal/telephony/SmsRawData.java
@@ -15,10 +15,10 @@
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
-import android.os.Parcelable;
import android.os.Parcel;
+import android.os.Parcelable;
/**
* A parcelable holder class of byte[] for ISms aidl implementation
@@ -50,7 +50,7 @@ public class SmsRawData implements Parcelable {
public byte[] getBytes() {
return data;
}
-
+
public int describeContents() {
return 0;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsResponse.java b/telephony/java/com/android/internal/telephony/SmsResponse.java
index 9742b22a974f..3c4df563000e 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsResponse.java
+++ b/telephony/java/com/android/internal/telephony/SmsResponse.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
/**
* Object returned by the RIL upon successful completion of sendSMS.
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 8519796c223f..6b1a5c3a243f 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -16,7 +16,7 @@ public class TelephonyIntents {
* <li><em>phoneName</em> - A string version of the phone name.</li>
* <li><em>state</em> - A string version of the new phone state.</li>
* </ul>
- *
+ *
* <p class="note">
* You can <em>not</em> receive this through components declared
* in manifests, only by exlicitly registering for it with
@@ -28,6 +28,24 @@ public class TelephonyIntents {
*/
public static final String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
+ /**
+ * <p>Broadcast Action: The radio technology has changed. The intent will have the following
+ * extra values:</p>
+ * <ul>
+ * <li><em>phoneName</em> - A string version of the new phone name.</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_RADIO_TECHNOLOGY_CHANGED
+ = "android.intent.action.RADIO_TECHNOLOGY";
/**
* Broadcast Action: The phone service state has changed. The intent will have the following
@@ -67,7 +85,7 @@ public class TelephonyIntents {
* <ul><li>0 means "-113 dBm or less".</li><li>31 means "-51 dBm or greater".</li></ul>
* </li>
* </ul>
- *
+ *
* <p class="note">
* You can <em>not</em> receive this through components declared
* in manifests, only by exlicitly registering for it with
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index c19773433aa7..037dd77c3ddb 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -26,8 +26,11 @@ public interface TelephonyProperties
{
//****** Baseband and Radio Interface version
- /**
- * Baseband version
+ //TODO T: property strings do not have to be gsm specific
+ // change gsm.*operator.*" properties to "operator.*" properties
+
+ /**
+ * Baseband version
* Availability: property is available any time radio is on
*/
static final String PROPERTY_BASEBAND_VERSION = "gsm.version.baseband";
@@ -64,7 +67,7 @@ public interface TelephonyProperties
static final String PROPERTY_OPERATOR_ISO_COUNTRY = "gsm.operator.iso-country";
//****** SIM Card
- /**
+ /**
* One of <code>"UNKNOWN"</code> <code>"ABSENT"</code> <code>"PIN_REQUIRED"</code>
* <code>"PUK_REQUIRED"</code> <code>"NETWORK_LOCKED"</code> or <code>"READY"</code>
*/
@@ -82,15 +85,15 @@ public interface TelephonyProperties
* provider of the SIM. 5 or 6 decimal digits.
* Availablity: SIM state must be "READY"
*/
- static String PROPERTY_SIM_OPERATOR_NUMERIC = "gsm.sim.operator.numeric";
+ static String PROPERTY_ICC_OPERATOR_NUMERIC = "gsm.sim.operator.numeric";
- /** PROPERTY_SIM_OPERATOR_ALPHA is also known as the SPN, or Service Provider Name.
+ /** PROPERTY_ICC_OPERATOR_ALPHA is also known as the SPN, or Service Provider Name.
* Availablity: SIM state must be "READY"
*/
- static String PROPERTY_SIM_OPERATOR_ALPHA = "gsm.sim.operator.alpha";
+ static String PROPERTY_ICC_OPERATOR_ALPHA = "gsm.sim.operator.alpha";
/** ISO country code equivalent for the SIM provider's country code*/
- static String PROPERTY_SIM_OPERATOR_ISO_COUNTRY = "gsm.sim.operator.iso-country";
+ static String PROPERTY_ICC_OPERATOR_ISO_COUNTRY = "gsm.sim.operator.iso-country";
/**
* Indicates the available radio technology. Values include: <code>"unknown"</code>,
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 53ff9d4254c3..7ceba3aa7d7b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -13,13 +13,10 @@
* 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.CommandsInterface.CF_REASON_UNCONDITIONAL;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
import android.content.Context;
-import android.content.SharedPreferences;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
@@ -27,15 +24,19 @@ 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.text.TextUtils;
import android.util.Log;
-import com.android.internal.telephony.CallForwardInfo;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
+
import com.android.internal.telephony.CallStateException;
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.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
@@ -44,13 +45,10 @@ import com.android.internal.telephony.MmiCode;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.PhoneNotifier;
+import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.PhoneSubInfo;
-import com.android.internal.telephony.gsm.GsmMmiCode;
-import com.android.internal.telephony.gsm.PdpConnection;
import com.android.internal.telephony.RILConstants;
-import android.telephony.PhoneNumberUtils;
-
import java.util.ArrayList;
import java.util.List;
@@ -59,16 +57,18 @@ import java.util.List;
*/
public class CDMAPhone extends PhoneBase {
static final String LOG_TAG = "CDMA";
- private static final boolean LOCAL_DEBUG = false;
-
+ private static final boolean LOCAL_DEBUG = true;
+
//***** Instance Variables
CdmaCallTracker mCT;
- SMSDispatcher mSMS;
+ CdmaSMSDispatcher mSMS;
CdmaServiceStateTracker mSST;
-// DataConnectionTracker mDataConnection; //TODO
+ CdmaDataConnectionTracker mDataConnection;
+ RuimFileHandler mRuimFileHandler;
RuimRecords mRuimRecords;
RuimCard mRuimCard;
- //MyHandler h;
+ MyHandler h;
+ ArrayList <FeatureCode> mPendingMMIs = new ArrayList<FeatureCode>();
RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager;
RuimSmsInterfaceManager mRuimSmsInterfaceManager;
PhoneSubInfo mSubInfo;
@@ -79,27 +79,26 @@ public class CDMAPhone extends PhoneBase {
Registrant mPostDialHandler;
-
+
//***** Constructors
public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
this(context,ci,notifier, false);
- //TODO: to be checked if really needed
}
-
- public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) {
+
+ public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
+ boolean unitTestMode) {
super(notifier, context, unitTestMode);
- //TODO: to be checked if really needed
-
+
h = new MyHandler();
mCM = ci;
-
- mCM.setPhoneType(RILConstants.CDMA_PHONE);
- mCT = new CdmaCallTracker(this);
+
+ mCM.setPhoneType(RILConstants.CDMA_PHONE);
+ mCT = new CdmaCallTracker(this);
mSST = new CdmaServiceStateTracker (this);
- mSMS = new SMSDispatcher(this);
+ mSMS = new CdmaSMSDispatcher(this);
mIccFileHandler = new RuimFileHandler(this);
mRuimRecords = new RuimRecords(this);
-// mDataConnection = new DataConnectionTracker (this); //TODO
+ mDataConnection = new CdmaDataConnectionTracker (this);
mRuimCard = new RuimCard(this);
mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this);
mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this);
@@ -107,58 +106,105 @@ public class CDMAPhone extends PhoneBase {
mCM.registerForAvailable(h, EVENT_RADIO_AVAILABLE, null);
mRuimRecords.registerForRecordsLoaded(h, EVENT_RUIM_RECORDS_LOADED, null);
- mCM.registerForOffOrNotAvailable(h, EVENT_RADIO_OFF_OR_NOT_AVAILABLE,
- null);
+ mCM.registerForOffOrNotAvailable(h, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mCM.registerForOn(h, EVENT_RADIO_ON, null);
mCM.setOnSuppServiceNotification(h, EVENT_SSN, null);
mCM.setOnCallRing(h, EVENT_CALL_RING, null);
mSST.registerForNetworkAttach(h, EVENT_REGISTERED_TO_NETWORK, null);
mCM.registerForNVReady(h, EVENT_NV_READY, null);
+
+ //Change the system setting
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.CURRENT_ACTIVE_PHONE, RILConstants.CDMA_PHONE);
+ }
+
+ public void dispose() {
+ synchronized(PhoneProxy.lockForRadioTechnologyChange) {
+
+ //Unregister from all former registered events
+ mRuimRecords.unregisterForRecordsLoaded(h); //EVENT_RUIM_RECORDS_LOADED
+ mCM.unregisterForAvailable(h); //EVENT_RADIO_AVAILABLE
+ mCM.unregisterForOffOrNotAvailable(h); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE
+ mCM.unregisterForOn(h); //EVENT_RADIO_ON
+ mCM.unregisterForNVReady(h); //EVENT_NV_READY
+ mSST.unregisterForNetworkAttach(h); //EVENT_REGISTERED_TO_NETWORK
+ mCM.unSetOnSuppServiceNotification(h);
+ mCM.unSetOnCallRing(h);
+
+ //Force all referenced classes to unregister their former registered events
+ mCT.dispose();
+ mDataConnection.dispose();
+ mSST.dispose();
+ mSMS.dispose();
+ mIccFileHandler.dispose(); // instance of RuimFileHandler
+ mRuimRecords.dispose();
+ mRuimCard.dispose();
+ mRuimPhoneBookInterfaceManager.dispose();
+ mRuimSmsInterfaceManager.dispose();
+ mSubInfo.dispose();
+ }
+ }
+
+ public void removeReferences() {
+ this.mRuimPhoneBookInterfaceManager = null;
+ this.mRuimSmsInterfaceManager = null;
+ this.mSMS = null;
+ this.mSubInfo = null;
+ this.mRuimRecords = null;
+ this.mIccFileHandler = null;
+ this.mRuimCard = null;
+ this.mDataConnection = null;
+ this.mCT = null;
+ this.mSST = null;
}
-
-
+
+ protected void finalize() {
+ if(LOCAL_DEBUG) Log.d(LOG_TAG, "CDMAPhone finalized");
+ }
+
+
//***** Overridden from Phone
public ServiceState getServiceState() {
return mSST.ss;
- }
-
- public Phone.State
+ }
+
+ public Phone.State
getState() {
return mCT.state;
}
-
+
public String
getPhoneName() {
return "CDMA";
}
-
+
public boolean canTransfer() {
- // TODO: to be implemented
- //return mCT.canTransfer();
+ Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
return false;
}
-
- public CdmaCall
+
+ public CdmaCall
getRingingCall() {
return mCT.ringingCall;
}
-
+
public void setMute(boolean muted) {
mCT.setMute(muted);
}
+
public boolean getMute() {
return mCT.getMute();
}
-
- public void conference() { //throws CallStateException
- //TODO: ...
-
+
+ public void conference() throws CallStateException {
+ // three way calls in CDMA will be handled by feature codes
+ Log.e(LOG_TAG, "conference: not possible in CDMA");
}
-
+
public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
this.mCM.setPreferredVoicePrivacy(enable, onComplete);
}
-
+
public void getEnhancedVoicePrivacy(Message onComplete) {
this.mCM.getPreferredVoicePrivacy(onComplete);
}
@@ -166,36 +212,29 @@ public class CDMAPhone extends PhoneBase {
public void clearDisconnected() {
mCT.clearDisconnected();
}
-
+
public DataActivityState getDataActivityState() {
DataActivityState ret = DataActivityState.NONE;
if (mSST.getCurrentCdmaDataConnectionState() != ServiceState.RADIO_TECHNOLOGY_UNKNOWN) {
- // TODO This "switch" has to be implemented, when the CDMAPhone is able to generate a cdma.DataConnectionTracker
- // Until this will happen, we return DataActivityState.DATAIN!!!
-
- ret = DataActivityState.DATAIN; // Remove this, when "switch" is implemented!
-
- /*switch (mDataConnection.activity) {
-
- case DATAIN:
- ret = DataActivityState.DATAIN;
- break;
+ switch (mDataConnection.getActivity()) {
+ case DATAIN:
+ ret = DataActivityState.DATAIN;
+ break;
- case DATAOUT:
- ret = DataActivityState.DATAOUT;
- break;
+ case DATAOUT:
+ ret = DataActivityState.DATAOUT;
+ break;
- case DATAINANDOUT:
- ret = DataActivityState.DATAINANDOUT;
- break;
- }*/
+ case DATAINANDOUT:
+ ret = DataActivityState.DATAINANDOUT;
+ break;
+ }
}
-
return ret;
}
-
+
/*package*/ void
notifySignalStrength() {
mNotifier.notifySignalStrength(this);
@@ -206,75 +245,109 @@ public class CDMAPhone extends PhoneBase {
// Need to make sure dialString gets parsed properly
String newDialString = PhoneNumberUtils.stripSeparators(dialString);
- return mCT.dial(newDialString);
+ FeatureCode fc = FeatureCode.newFromDialString(newDialString, this);
+ if (LOCAL_DEBUG) Log.d(LOG_TAG,
+ "dialing w/ fc '" + fc + "'...");
+ // check for feature code
+ if (fc == null) {
+ // check if call in progress
+ if (!mCT.foregroundCall.isIdle()) {
+ FeatureCode digits = new FeatureCode(this);
+ // use dial number as poundString
+ digits.poundString = newDialString;
+ mPendingMMIs.add(fc);
+ mMmiRegistrants.notifyRegistrants(new AsyncResult(null, fc, null));
+ digits.processCode();
+ return null;
+ } else {
+ return mCT.dial(newDialString);
+ }
+ } else {
+ mPendingMMIs.add(fc);
+ mMmiRegistrants.notifyRegistrants(new AsyncResult(null, fc, null));
+ fc.processCode();
+
+ // FIXME should this return null or something else?
+ return null;
+ }
}
-
+
public int getSignalStrengthASU() {
return mSST.rssi == 99 ? -1 : mSST.rssi;
}
public boolean
getMessageWaitingIndicator() {
- //TODO: ...
-// throw new RuntimeException();
- return false;
+ Log.e(LOG_TAG, "method getMessageWaitingIndicator is NOT supported in CDMA!");
+ return false;
}
+
public List<? extends MmiCode>
getPendingMmiCodes() {
- ArrayList <GsmMmiCode> mPendingMMIs = new ArrayList<GsmMmiCode>();
Log.e(LOG_TAG, "method getPendingMmiCodes is NOT supported in CDMA!");
- return mPendingMMIs;
+ return null;
}
+
public void registerForSuppServiceNotification(
Handler h, int what, Object obj) {
- //TODO: ....
+ Log.e(LOG_TAG, "method registerForSuppServiceNotification is NOT supported in CDMA!");
}
-
+
public CdmaCall getBackgroundCall() {
return mCT.backgroundCall;
}
-
+
public String getGateway(String apnType) {
- //TODO: ....
-// throw new RuntimeException();
- return null;
+ return mDataConnection.getGateway();
}
-
+
public boolean handleInCallMmiCommands(String dialString) {
Log.e(LOG_TAG, "method handleInCallMmiCommands is NOT supported in CDMA!");
return false;
}
-
+
public int enableApnType(String type) {
- //TODO: ....
- return 42;
+ // This request is mainly used to enable MMS APN
+ // In CDMA there is no need to enable/disable a different APN for MMS
+ Log.d(LOG_TAG, "Request to enableApnType("+type+")");
+ if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
+ return Phone.APN_ALREADY_ACTIVE;
+ } else {
+ return Phone.APN_REQUEST_FAILED;
+ }
}
+
public int disableApnType(String type) {
- //TODO: to be implemented
- return 42;
+ // This request is mainly used to disable MMS APN
+ // In CDMA there is no need to enable/disable a different APN for MMS
+ Log.d(LOG_TAG, "Request to disableApnType("+type+")");
+ if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
+ return Phone.APN_REQUEST_STARTED;
+ } else {
+ return Phone.APN_REQUEST_FAILED;
+ }
}
-
+
public String getActiveApn() {
- //TODO: ...
-// throw new RuntimeException();
- return null;
+ Log.d(LOG_TAG, "Request to getActiveApn()");
+ return null;
}
-
- public void
+
+ public void
setNetworkSelectionModeAutomatic(Message response) {
- //TODO: ...
+ Log.e(LOG_TAG, "method setNetworkSelectionModeAutomatic is NOT supported in CDMA!");
}
-
+
public void unregisterForSuppServiceNotification(Handler h) {
- //TODO: ...
+ Log.e(LOG_TAG, "method unregisterForSuppServiceNotification is NOT supported in CDMA!");
}
-
- public void
+
+ public void
acceptCall() throws CallStateException {
mCT.acceptCall();
}
- public void
+ public void
rejectCall() throws CallStateException {
mCT.rejectCall();
}
@@ -283,155 +356,124 @@ public class CDMAPhone extends PhoneBase {
switchHoldingAndActive() throws CallStateException {
mCT.switchWaitingOrHoldingAndActive();
}
-
+
public String getLine1Number() {
return mRuimRecords.getMdnNumber();
}
- public void stopDtmf() {
- //TODO: ...
- }
-
- // TODO: might not be used any longer in CDMA
public void getCallWaiting(Message onComplete) {
mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
}
-
+
public void
setRadioPower(boolean power) {
mSST.setRadioPower(power);
}
-
+
public String getEsn() {
return mEsn;
}
-
+
public String getMeid() {
return mMeid;
}
-
+ //returns MEID in CDMA
public String getDeviceId() {
- Log.d(LOG_TAG, "getDeviceId(): return 0");
- return "0";
+ return getMeid();
}
-
+
public String getDeviceSvn() {
Log.d(LOG_TAG, "getDeviceSvn(): return 0");
return "0";
}
-
+
public String getSubscriberId() {
- //TODO: ...
-// throw new RuntimeException();
- return null;
+ Log.e(LOG_TAG, "method getSubscriberId for IMSI is NOT supported in CDMA!");
+ return null;
}
-
+
public boolean canConference() {
- // TODO: to be implemented
+ Log.e(LOG_TAG, "canConference: not possible in CDMA");
return false;
}
-
+
public String getInterfaceName(String apnType) {
- //TODO: ....
-// throw new RuntimeException();
- return null;
+ return mDataConnection.getInterfaceName();
}
-
+
public CellLocation getCellLocation() {
return mSST.cellLoc;
}
-
+
public boolean disableDataConnectivity() {
- //TODO:
-// throw new RuntimeException();
- return true;
- }
- public void setBandMode(int bandMode, Message response) {
- //TODO: ...
+ return mDataConnection.setDataEnabled(false);
}
-
+
public CdmaCall getForegroundCall() {
return mCT.foregroundCall;
}
-
- public void
+
+ public void
selectNetworkManually(com.android.internal.telephony.gsm.NetworkInfo network,
Message response) {
- //TODO: ...
+ Log.e(LOG_TAG, "selectNetworkManually: not possible in CDMA");
}
-
+
public void setOnPostDialCharacter(Handler h, int what, Object obj) {
- //TODO: ...
+ Log.e(LOG_TAG, "setOnPostDialCharacter: not possible in CDMA");
}
-
+
public boolean handlePinMmi(String dialString) {
Log.e(LOG_TAG, "method handlePinMmi is NOT supported in CDMA!");
- return false;
+ return false;
}
-
- public boolean isDataConnectivityPossible() {
- // TODO: Currently checks if any GPRS connection is active. Should it only
- // check for "default"?
-
- // TODO This function has to be implemented, when the CDMAPhone is able to generate a cdma.DataConnectionTracker
- // Until this will happen, we return TRUE!!!
- return true;
- /*boolean noData = mDataConnection.getDataEnabled() &&
- getDataConnectionState() == DataState.DISCONNECTED;
- return !noData && getSimCard().getState() == SimCard.State.READY &&
- getServiceState().getState() == ServiceState.STATE_IN_SERVICE &&
- (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming());*/
+ public boolean isDataConnectivityPossible() {
+ boolean noData = mDataConnection.getDataEnabled() &&
+ getDataConnectionState() == DataState.DISCONNECTED;
+ return !noData && getIccCard().getState() == IccCard.State.READY &&
+ getServiceState().getState() == ServiceState.STATE_IN_SERVICE &&
+ (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming());
}
-
+
public void setLine1Number(String alphaTag, String number, Message onComplete) {
- //TODO: ...
+ Log.e(LOG_TAG, "setLine1Number: not possible in CDMA");
}
-
+
public String[] getDnsServers(String apnType) {
- //TODO: ....
-// throw new RuntimeException();
- return null;
+ return mDataConnection.getDnsServers();
}
-
+
public IccCard getIccCard() {
return mRuimCard;
}
-
+
public String getIccSerialNumber() {
return mRuimRecords.iccid;
}
-
- public void queryAvailableBandMode(Message response) {
- //TODO: ....
- }
-
- // TODO: might not be used any longer in CDMA
+
public void setCallWaiting(boolean enable, Message onComplete) {
- mCM.setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
+ Log.e(LOG_TAG, "method setCallWaiting is NOT supported in CDMA!");
}
-
+
public void updateServiceLocation(Message response) {
mSST.getLacAndCid(response);
}
public void setDataRoamingEnabled(boolean enable) {
- //TODO: ....
+ mDataConnection.setDataOnRoamingEnabled(enable);
}
-
+
public String getIpAddress(String apnType) {
- //TODO: ....
-// throw new RuntimeException();
- return null;
+ return mDataConnection.getIpAddress();
}
-
+
public void
getNeighboringCids(Message response) {
- //TODO: ....
-// throw new RuntimeException();
+ //TODO T: implement after Cupcake merge
}
-
+
public DataState getDataConnectionState() {
DataState ret = DataState.DISCONNECTED;
@@ -443,88 +485,102 @@ public class CDMAPhone extends PhoneBase {
// we report data connected
ret = DataState.CONNECTED;
- } else if (mSST.getCurrentCdmaDataConnectionState() == ServiceState.RADIO_TECHNOLOGY_UNKNOWN) {
+ } else if (mSST.getCurrentCdmaDataConnectionState()
+ == ServiceState.RADIO_TECHNOLOGY_UNKNOWN) {
// If we're out of service, open TCP sockets may still work
// but no data will flow
ret = DataState.DISCONNECTED;
- } else { /* mSST.getCurrentCdmaDataConnectionState() is ServiceState.RADIO_TECHNOLOGY_1xRTT or EVDO */
-
-
- // TODO This "switch" has to be implemented, when the CDMAPhone is able to generate a cdma.DataConnectionTracker
- // Until this will happen, we return DataState.CONNECTED!!!
-
- ret = DataState.CONNECTED; //TODO Remove this, when "switch" iis implemented
-
- /* switch (mDataConnection.state) {
- case FAILED:
- case IDLE:
- ret = DataState.DISCONNECTED;
- break;
-
- case CONNECTED:
- if ( mCT.state != Phone.State.IDLE
- && !mSST.isConcurrentVoiceAndData())
- ret = DataState.SUSPENDED;
- else
- ret = DataState.CONNECTED;
- break;
-
- case INITING:
- case CONNECTING:
- case SCANNING:
- ret = DataState.CONNECTING;
- break;
- }*/
+ } else {
+ switch (mDataConnection.getState()) {
+ case FAILED:
+ case IDLE:
+ ret = DataState.DISCONNECTED;
+ break;
+
+ case CONNECTED:
+ if ( mCT.state != Phone.State.IDLE
+ && !mSST.isConcurrentVoiceAndData())
+ ret = DataState.SUSPENDED;
+ else
+ ret = DataState.CONNECTED;
+ break;
+
+ case INITING:
+ case CONNECTING:
+ case SCANNING:
+ ret = DataState.CONNECTING;
+ break;
+ }
}
return ret;
}
public void sendUssdResponse(String ussdMessge) {
- //TODO: ...
+ Log.e(LOG_TAG, "sendUssdResponse: not possible in CDMA");
}
+
public void sendDtmf(char c) {
- //TODO: ....
+ if (!PhoneNumberUtils.is12Key(c)) {
+ Log.e(LOG_TAG,
+ "sendDtmf called with invalid character '" + c + "'");
+ } else {
+ if (mCT.state == Phone.State.OFFHOOK) {
+ mCM.sendDtmf(c, null);
+ }
+ }
}
-
+
public void startDtmf(char c) {
- //TODO: ....
+ if (!PhoneNumberUtils.is12Key(c)) {
+ Log.e(LOG_TAG,
+ "startDtmf called with invalid character '" + c + "'");
+ } else {
+ mCM.startDtmf(c, null);
+ }
}
-
- public void
- getAvailableNetworks(Message response) {
- //TODO: ....
+
+ public void stopDtmf() {
+ mCM.stopDtmf(null);
+ }
+
+ public void getAvailableNetworks(Message response) {
+ Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA");
}
-
+
public String[] getActiveApnTypes() {
- //TODO: .....
-// throw new RuntimeException();
- return null;
+ String[] result;
+ Log.d(LOG_TAG, "Request to getActiveApn()");
+ result = new String[1];
+ result[0] = Phone.APN_TYPE_DEFAULT;
+ return result;
}
-
+
public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) {
- // TODO: might not be used any longer in CDMA
-// mCM.setCLIR(commandInterfaceCLIRMode, h.obtainMessage(EVENT_SET_CLIR_COMPLETE, commandInterfaceCLIRMode, 0, onComplete));
+ Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA");
}
-
+
public void enableLocationUpdates() {
mSST.enableLocationUpdates();
}
-
+
+ /**
+ * @deprecated
+ */
public void getPdpContextList(Message response) {
- //TODO: to be implemented
+ getDataCallList(response);
+ }
+
+ public void getDataCallList(Message response) {
+ mCM.getDataCallList(response);
}
-
+
public boolean getDataRoamingEnabled() {
- //TODO: ....
- return false; //mDataConnection.getDataOnRoamingEnabled();
+ return mDataConnection.getDataOnRoamingEnabled();
}
-
- public List<PdpConnection> getCurrentPdpList () {
- //TODO: to be implemented and import pdpConcecntion from
- // GSM to be removed/replaced
- return null;
+ public List<DataConnection> getCurrentDataConnectionList () {
+ return mDataConnection.getAllDataConnections();
}
public void setVoiceMailNumber(String alphaTag,
@@ -533,14 +589,14 @@ public class CDMAPhone extends PhoneBase {
//mSIMRecords.setVoiceMailNumber(alphaTag, voiceMailNumber, onComplete);
//TODO: Where do we have to store this value has to be clarified with QC
}
-
+
public String getVoiceMailNumber() {
//TODO: Where can we get this value has to be clarified with QC
//return mSIMRecords.getVoiceMailNumber();
-// throw new RuntimeException();
+// throw new RuntimeException();
return "12345";
}
-
+
public String getVoiceMailAlphaTag() {
// TODO: Where can we get this value has to be clarified with QC.
String ret = "";//TODO: Remove = "", if we know where to get this value.
@@ -552,56 +608,52 @@ public class CDMAPhone extends PhoneBase {
com.android.internal.R.string.defaultVoiceMailAlphaTag).toString();
}
- return ret;
+ return ret;
}
-
public boolean enableDataConnectivity() {
- //TODO: to be implemented
- return false;
+ return mDataConnection.setDataEnabled(true);
}
public void disableLocationUpdates() {
mSST.disableLocationUpdates();
}
- public boolean
- getSimRecordsLoaded() {
- // TODO: this method is expected to be renamed
- // and implemented in PhoneBase!!!
+ public boolean getIccRecordsLoaded() {
return mRuimRecords.getRecordsLoaded();
}
-
- public void invokeOemRilRequestRaw(byte[] data, Message response) {
- //TODO: .....
+
+ public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
+ Log.e(LOG_TAG, "getCallForwardingOption: not possible in CDMA");
}
- public void invokeOemRilRequestStrings(String[] strings, Message response) {
- // TODO: to be implemented
+
+ public void setCallForwardingOption(int commandInterfaceCFAction,
+ int commandInterfaceCFReason,
+ String dialingNumber,
+ int timerSeconds,
+ Message onComplete) {
+ Log.e(LOG_TAG, "setCallForwardingOption: not possible in CDMA");
}
- // TODO: might not be used any longer in CDMA
- public void
+ public void
getOutgoingCallerIdDisplay(Message onComplete) {
- // TODO: might not be used any longer in CDMA
-// mCM.getCLIR(onComplete);
+ Log.e(LOG_TAG, "getOutgoingCallerIdDisplay: not possible in CDMA");
}
-
+
public boolean
getCallForwardingIndicator() {
- // TODO: to be implemented
+ Log.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA");
return false;
}
public void explicitCallTransfer() {
- //TODO: to be implemented like GSM
- }
-
+ Log.e(LOG_TAG, "explicitCallTransfer: not possible in CDMA");
+ }
+
public String getLine1AlphaTag() {
- // TODO: to be implemented
- String ret = "to be implemented";
- return ret;
+ Log.e(LOG_TAG, "getLine1AlphaTag: not possible in CDMA");
+ return null;
}
-
/**
* Notify any interested party of a Phone state change.
@@ -609,17 +661,16 @@ public class CDMAPhone extends PhoneBase {
/*package*/ void notifyPhoneStateChanged() {
mNotifier.notifyPhoneState(this);
}
-
+
/**
* Notifies registrants (ie, activities in the Phone app) about
* changes to call state (including Phone and Connection changes).
*/
- /*package*/ void
- notifyCallStateChanged() {
+ /*package*/ void notifyCallStateChanged() {
/* we'd love it if this was package-scoped*/
super.notifyCallStateChangedP();
}
-
+
void notifyServiceStateChanged(ServiceState ss) {
super.notifyServiceStateChangedP(ss);
}
@@ -627,13 +678,8 @@ public class CDMAPhone extends PhoneBase {
void notifyLocationChanged() {
mNotifier.notifyCellLocation(this);
}
-
- void notifyDataConnection(String reason) {
- mNotifier.notifyDataConnection(this, reason);
- }
-
- /*package*/ void
- notifyNewRingingConnection(Connection c) {
+
+ /*package*/ void notifyNewRingingConnection(Connection c) {
/* we'd love it if this was package-scoped*/
super.notifyNewRingingConnectionP(c);
}
@@ -641,20 +687,43 @@ public class CDMAPhone extends PhoneBase {
/**
* Notifiy registrants of a RING event.
*/
- void notifyIncomingRing() {
+ void notifyIncomingRing() {
AsyncResult ar = new AsyncResult(null, this, null);
mIncomingRingRegistrants.notifyRegistrants(ar);
}
-
- /*package*/ void
- notifyDisconnect(Connection cn) {
+
+ /*package*/ void notifyDisconnect(Connection cn) {
mDisconnectRegistrants.notifyResult(cn);
}
void notifyUnknownConnection() {
mUnknownConnectionRegistrants.notifyResult(this);
}
-
+
+ /*package*/ void
+ updateMessageWaitingIndicator(boolean mwi) {
+ // this also calls notifyMessageWaitingIndicator()
+ mRuimRecords.setVoiceMessageWaiting(1, mwi ? -1 : 0);
+ }
+
+
+ /**
+ * Removes the given FC from the pending list and notifies
+ * registrants that it is complete.
+ * @param fc FC that is done
+ */
+ /*package*/ void onMMIDone(FeatureCode fc) {
+ /* Only notify complete if it's on the pending list.
+ * Otherwise, it's already been handled (eg, previously canceled).
+ * The exception is cancellation of an incoming USSD-REQUEST, which is
+ * not on the list.
+ */
+ if (mPendingMMIs.remove(fc)) {
+ mMmiCompleteRegistrants.notifyRegistrants(
+ new AsyncResult(null, fc, null));
+ }
+ }
+
//***** Inner Classes
class MyHandler extends Handler {
MyHandler() {
@@ -664,14 +733,12 @@ public class CDMAPhone extends PhoneBase {
super(l);
}
- public void
- handleMessage(Message msg) {
+ public void handleMessage(Message msg) {
AsyncResult ar;
Message onComplete;
switch(msg.what) {
case EVENT_RADIO_AVAILABLE: {
- Log.d(LOG_TAG, "Event EVENT_RADIO_AVAILABLE Received"); //TODO Remove
mCM.getBasebandVersion(obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE));
mCM.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE));
@@ -679,7 +746,6 @@ public class CDMAPhone extends PhoneBase {
break;
case EVENT_GET_BASEBAND_VERSION_DONE:{
- Log.d(LOG_TAG, "Event EVENT_GET_BASEBAND_VERSION_DONE Received"); //TODO Remove
ar = (AsyncResult)msg.obj;
if (ar.exception != null) {
@@ -690,132 +756,61 @@ public class CDMAPhone extends PhoneBase {
setSystemProperty(PROPERTY_BASEBAND_VERSION, (String)ar.result);
}
break;
-
+
case EVENT_GET_DEVICE_IDENTITY_DONE:{
- Log.d(LOG_TAG, "Event EVENT_GET_DEVICE_IDENTITY_DONE Received"); //TODO Remove
ar = (AsyncResult)msg.obj;
if (ar.exception != null) {
break;
}
- String[] localTemp = (String[])ar.result;
- mEsn = localTemp[2];
- mMeid = localTemp[3];
- Log.d(LOG_TAG, "ESN: " + mEsn); //TODO Remove
- Log.d(LOG_TAG, "MEID: " + mMeid); //TODO Remove
+ String[] respId = (String[])ar.result;
+ mEsn = respId[2];
+ mMeid = respId[3];
}
break;
case EVENT_RUIM_RECORDS_LOADED:{
- Log.d(LOG_TAG, "Event EVENT_RUIM_RECORDS_LOADED Received"); //TODO Remove
- //TODO
+ Log.d(LOG_TAG, "Event EVENT_RUIM_RECORDS_LOADED Received");
}
break;
case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:{
- Log.d(LOG_TAG, "Event EVENT_RADIO_OFF_OR_NOT_AVAILABLE Received"); //TODO Remove
- //TODO
+ Log.d(LOG_TAG, "Event EVENT_RADIO_OFF_OR_NOT_AVAILABLE Received");
}
break;
case EVENT_RADIO_ON:{
- Log.d(LOG_TAG, "Event EVENT_RADIO_ON Received"); //TODO Remove
+ Log.d(LOG_TAG, "Event EVENT_RADIO_ON Received");
}
break;
case EVENT_SSN:{
- Log.d(LOG_TAG, "Event EVENT_SSN Received"); //TODO Remove
+ Log.d(LOG_TAG, "Event EVENT_SSN Received");
}
break;
case EVENT_CALL_RING:{
- Log.d(LOG_TAG, "Event EVENT_CALL_RING Received"); //TODO Remove
- }
+ Log.d(LOG_TAG, "Event EVENT_CALL_RING Received");
+ }
break;
case EVENT_REGISTERED_TO_NETWORK:{
- Log.d(LOG_TAG, "Event EVENT_REGISTERED_TO_NETWORK Received"); //TODO Remove
- // TODO: might not be used any longer in CDMA
- // syncClirSetting();
- }
+ Log.d(LOG_TAG, "Event EVENT_REGISTERED_TO_NETWORK Received");
+ }
break;
case EVENT_NV_READY:{
- Log.d(LOG_TAG, "Event EVENT_NV_READY Received"); //TODO Remove
- //Get the records from NV
- //TODO
+ Log.d(LOG_TAG, "Event EVENT_NV_READY Received");
//Inform the Service State Tracker
mNvLoadedRegistrants.notifyRegistrants();
- }
+ }
break;
- // TODO: might not be used any longer in CDMA
-// case EVENT_GET_CALL_FORWARD_DONE:
-// ar = (AsyncResult)msg.obj;
-// if (ar.exception == null) {
-// handleCfuQueryResult((CallForwardInfo[])ar.result);
-// }
-// onComplete = (Message) ar.userObj;
-// if (onComplete != null) {
-// AsyncResult.forMessage(onComplete, ar.result, ar.exception);
-// onComplete.sendToTarget();
-// }
-// break;
-
- // TODO: might not be used any longer in CDMA
-// case EVENT_SET_CALL_FORWARD_DONE:
-// ar = (AsyncResult)msg.obj;
-//
-// // TODO: Normally, we don't have to set this flag at the RUIM card too. But check it again before deleting this code.
-// /*if (ar.exception == null) {
-// mSIMRecords.setVoiceCallForwardingFlag(1, msg.arg1 == 1);
-// }*/
-//
-// onComplete = (Message) ar.userObj;
-// if (onComplete != null) {
-// AsyncResult.forMessage(onComplete, ar.result, ar.exception);
-// onComplete.sendToTarget();
-// }
-// break;
-
- // TODO: might not be used any longer in CDMA
-// case EVENT_SET_CLIR_COMPLETE:
-// ar = (AsyncResult)msg.obj;
-// if (ar.exception == null) {
-// saveClirSetting(msg.arg1);
-// }
-// onComplete = (Message) ar.userObj;
-// if (onComplete != null) {
-// AsyncResult.forMessage(onComplete, ar.result, ar.exception);
-// onComplete.sendToTarget();
-// }
-// break;
-
default:{
throw new RuntimeException("unexpected event not handled");
}
}
- }
- }
-
- private void handleCfuQueryResult(CallForwardInfo[] infos) {
-
- // TODO: Normally, we don't need to set this flag at the RUIM card too. But this has to be checked.
- // Remove this function, if we don't need it in CDMA.
-
- /*if (infos == null || infos.length == 0) {
- // Assume the default is not active
- // Set unconditional CFF in SIM to false
- mSIMRecords.setVoiceCallForwardingFlag(1, false);
- } else {
- for (int i = 0, s = infos.length; i < s; i++) {
- if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) {
- mSIMRecords.setVoiceCallForwardingFlag(1, (infos[i].status == 1));
- // should only have the one
- break;
- }
- }
- }*/
+ }
}
/**
@@ -829,8 +824,7 @@ public class CDMAPhone extends PhoneBase {
* Retrieves the IccSmsInterfaceManager of the CDMAPhone
*/
public IccSmsInterfaceManager getIccSmsInterfaceManager(){
- //TODO
- return null;
+ return mRuimSmsInterfaceManager;
}
/**
@@ -844,30 +838,33 @@ public class CDMAPhone extends PhoneBase {
Registrant r = new Registrant (h, what, obj);
mNvLoadedRegistrants.add(r);
}
-
+
+ public void unregisterForNvLoaded(Handler h) {
+ mNvLoadedRegistrants.remove(h);
+ }
+
// override for allowing access from other classes of this package
/**
* {@inheritDoc}
*/
- protected final void
- setSystemProperty(String property, String value) {
+ public final void setSystemProperty(String property, String value) {
super.setSystemProperty(property, value);
- }
-
+ }
+
/**
* {@inheritDoc}
- */
- protected Handler getHandler(){
+ */
+ public Handler getHandler(){
return h;
}
-
+
/**
* {@inheritDoc}
- */
- protected IccFileHandler getIccFileHandler(){
- return this.mIccFileHandler;
+ */
+ public IccFileHandler getIccFileHandler(){
+ return this.mIccFileHandler;
}
-
+
/**
* Set the TTY mode of the CDMAPhone
*/
@@ -881,4 +878,36 @@ public class CDMAPhone extends PhoneBase {
public void queryTTYModeEnabled(Message onComplete) {
this.mCM.queryTTYModeEnabled(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);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
index 9fcc37a661d3..ea557b2068e1 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
@@ -15,7 +15,7 @@
*/
package com.android.internal.telephony.cdma;
-
+
/**
* Call fail causes from TS 24.008 .
* These are mostly the cause codes we need to distinguish for the UI.
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
index 9982d1422bea..9ccb310c211b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
@@ -22,9 +22,8 @@ import java.util.List;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
import com.android.internal.telephony.DriverCall;
-
+import com.android.internal.telephony.Phone;
/**
* {@hide}
@@ -35,7 +34,7 @@ public final class CdmaCall extends Call {
/*package*/ ArrayList<Connection> connections = new ArrayList<Connection>();
/*package*/ State state = State.IDLE;
/*package*/ CdmaCallTracker owner;
-
+
/***************************** Class Methods *****************************/
static State
@@ -50,34 +49,35 @@ public final class CdmaCall extends Call {
default: throw new RuntimeException ("illegal call state:" + dcState);
}
}
-
+
/****************************** Constructors *****************************/
/*package*/
CdmaCall (CdmaCallTracker owner) {
this.owner = owner;
}
-
+
+ public void dispose() {
+ }
+
/************************** Overridden from Call *************************/
- // TODO is currently a copy of GSM to build
- // has to be implemented
public List<Connection>
getConnections() {
// FIXME should return Collections.unmodifiableList();
return connections;
}
-
- public State
+
+ public State
getState() {
return state;
}
-
- public Phone
+
+ public Phone
getPhone() {
- //TODO
+ //TODO, see GsmCall
return null;
}
-
+
public boolean isMultiparty() {
return connections.size() > 1;
}
@@ -86,11 +86,11 @@ public final class CdmaCall extends Call {
* background call exists, the background call will be resumed
* because an AT+CHLD=1 will be sent
*/
- public void
+ public void
hangup() throws CallStateException {
owner.hangup(this);
- }
-
+ }
+
public String
toString() {
return state.toString();
@@ -121,20 +121,20 @@ public final class CdmaCall extends Call {
/* If only disconnected connections remain, we are disconnected*/
boolean hasOnlyDisconnectedConnections = true;
-
+
for (int i = 0, s = connections.size() ; i < s; i ++) {
- if (connections.get(i).getState()
+ if (connections.get(i).getState()
!= State.DISCONNECTED
) {
hasOnlyDisconnectedConnections = false;
break;
- }
+ }
}
if (hasOnlyDisconnectedConnections) {
- state = State.DISCONNECTED;
+ state = State.DISCONNECTED;
}
- }
+ }
}
@@ -151,9 +151,9 @@ public final class CdmaCall extends Call {
update (CdmaConnection conn, DriverCall dc) {
State newState;
boolean changed = false;
-
+
newState = stateFromDCState(dc.state);
-
+
if (newState != state) {
state = newState;
changed = true;
@@ -174,7 +174,7 @@ public final class CdmaCall extends Call {
//***** Called from CdmaCallTracker
- /**
+ /**
* Called when this Call is being hung up locally (eg, user pressed "end")
* Note that at this point, the hangup request has been dispatched to the radio
* but no response has yet been received so update() has not yet been called
@@ -189,18 +189,18 @@ public final class CdmaCall extends Call {
cn.onHangupLocal();
}
}
-
+
/**
* Called when it's time to clean up disconnected Connection objects
*/
void clearDisconnected() {
for (int i = connections.size() - 1 ; i >= 0 ; i--) {
CdmaConnection cn = (CdmaConnection)connections.get(i);
-
+
if (cn.getState() == State.DISCONNECTED) {
connections.remove(i);
}
- }
+ }
if (connections.size() == 0) {
state = State.IDLE;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index d813ecaf9f5b..2485dcb4e5b0 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -37,42 +37,42 @@ import com.android.internal.telephony.*;
* {@hide}
*/
public final class CdmaCallTracker extends CallTracker {
- static final String LOG_TAG = "CDMA";
-
+ static final String LOG_TAG = "CDMA";
+
private static final boolean REPEAT_POLLING = false;
private static final boolean DBG_POLL = false;
//***** Constants
- static final int MAX_CONNECTIONS = 7; // only 7 connections allowed in GSM
- static final int MAX_CONNECTIONS_PER_CALL = 5; // only 5 connections allowed per call
+ static final int MAX_CONNECTIONS = 1; // only 1 connection allowed in CDMA
+ static final int MAX_CONNECTIONS_PER_CALL = 1; // only 1 connection allowed per call
//***** Instance Variables
-
+
CdmaConnection connections[] = new CdmaConnection[MAX_CONNECTIONS];
RegistrantList voiceCallEndedRegistrants = new RegistrantList();
RegistrantList voiceCallStartedRegistrants = new RegistrantList();
// connections dropped durin last poll
- ArrayList<CdmaConnection> droppedDuringPoll
- = new ArrayList<CdmaConnection>(MAX_CONNECTIONS);
+ ArrayList<CdmaConnection> droppedDuringPoll
+ = new ArrayList<CdmaConnection>(MAX_CONNECTIONS);
- CdmaCall ringingCall = new CdmaCall(this);
+ CdmaCall ringingCall = new CdmaCall(this);
// A call that is ringing or (call) waiting
CdmaCall foregroundCall = new CdmaCall(this);
CdmaCall backgroundCall = new CdmaCall(this);
CdmaConnection pendingMO;
boolean hangupPendingMO;
-
+
CDMAPhone phone;
-
+
boolean desiredMute = false; // false = mute off
Phone.State state = Phone.State.IDLE;
-
+
// boolean needsPoll;
@@ -88,7 +88,34 @@ public final class CdmaCallTracker extends CallTracker {
cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
}
-
+
+ public void dispose() {
+ cm.unregisterForCallStateChanged(this);
+ cm.unregisterForOn(this);
+ cm.unregisterForNotAvailable(this);
+
+ for(CdmaConnection c : connections) {
+ try {
+ if(c != null) hangup(c);
+ } catch (CallStateException ex) {
+ Log.e(LOG_TAG, "unexpected error on hangup during dispose");
+ }
+ }
+
+ try {
+ if(pendingMO != null) hangup(pendingMO);
+ } catch (CallStateException ex) {
+ Log.e(LOG_TAG, "unexpected error on hangup during dispose");
+ }
+
+ clearDisconnected();
+
+ }
+
+ protected void finalize() {
+ Log.d(LOG_TAG, "CdmaCallTracker finalized");
+ }
+
//***** Instance Methods
//***** Public Methods
@@ -96,12 +123,19 @@ public final class CdmaCallTracker extends CallTracker {
Registrant r = new Registrant(h, what, obj);
voiceCallStartedRegistrants.add(r);
}
+ public void unregisterForVoiceCallStarted(Handler h) {
+ voiceCallStartedRegistrants.remove(h);
+ }
public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
voiceCallEndedRegistrants.add(r);
}
+ public void unregisterForVoiceCallEnded(Handler h) {
+ voiceCallEndedRegistrants.remove(h);
+ }
+
private void
fakeHoldForegroundBeforeDial() {
List<Connection> connCopy;
@@ -116,7 +150,7 @@ public final class CdmaCallTracker extends CallTracker {
conn.fakeHoldBeforeDial();
}
}
-
+
/**
* clirMode is one of the CLIR_ constants
*/
@@ -139,13 +173,13 @@ public final class CdmaCallTracker extends CallTracker {
// for the newly dialed connection
switchWaitingOrHoldingAndActive();
- // Fake local state so that
+ // 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");
@@ -161,33 +195,33 @@ public final class CdmaCallTracker extends CallTracker {
pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
// handlePollCalls() will notice this call not present
- // and will mark it as dropped.
+ // and will mark it as dropped.
pollCallsWhenSafe();
} else {
// Always unmute when initiating a new call
setMute(false);
- cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
+ cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
}
updatePhoneState();
phone.notifyCallStateChanged();
-
+
return pendingMO;
}
-
+
Connection
dial (String dialString) throws CallStateException {
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
-
+
if (ringingCall.getState() == CdmaCall.State.INCOMING) {
Log.i("phone", "acceptCall: incoming...");
// Always unmute when answering a new call
@@ -218,21 +252,21 @@ public final class CdmaCallTracker extends CallTracker {
if (ringingCall.getState() == CdmaCall.State.INCOMING) {
throw new CallStateException("cannot be in the incoming state");
} else {
- cm.switchWaitingOrHoldingAndActive(
- obtainCompleteMessage(EVENT_SWITCH_RESULT));
+ cm.sendCDMAFeatureCode("", obtainCompleteMessage(EVENT_SWITCH_RESULT));
}
}
void
conference() throws CallStateException {
- cm.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT));
+ // three way calls in CDMA will be handled by feature codes
+ Log.e(LOG_TAG, "conference: not possible in CDMA");
}
void
explicitCallTransfer() throws CallStateException {
cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
}
-
+
void
clearDisconnected() {
internalClearDisconnected();
@@ -241,7 +275,7 @@ public final class CdmaCallTracker extends CallTracker {
phone.notifyCallStateChanged();
}
- boolean
+ boolean
canConference() {
return foregroundCall.getState() == CdmaCall.State.ACTIVE
&& backgroundCall.getState() == CdmaCall.State.HOLDING
@@ -265,21 +299,19 @@ public final class CdmaCallTracker extends CallTracker {
boolean
canTransfer() {
- return foregroundCall.getState() == CdmaCall.State.ACTIVE
- && backgroundCall.getState() == CdmaCall.State.HOLDING;
+ Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
+ return false;
}
-
+
//***** Private Instance Methods
-
+
private void
internalClearDisconnected() {
ringingCall.clearDisconnected();
foregroundCall.clearDisconnected();
- backgroundCall.clearDisconnected();
+ backgroundCall.clearDisconnected();
}
-
-
-
+
/**
* Obtain a message to use for signalling "invoke getCurrentCalls() when
* this operation and all other pending operations are complete
@@ -288,7 +320,7 @@ public final class CdmaCallTracker extends CallTracker {
obtainCompleteMessage() {
return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
}
-
+
/**
* Obtain a message to use for signalling "invoke getCurrentCalls() when
* this operation and all other pending operations are complete
@@ -308,26 +340,26 @@ public final class CdmaCallTracker extends CallTracker {
private void
operationComplete() {
pendingOperations--;
-
+
if (DBG_POLL) log("operationComplete: pendingOperations=" +
pendingOperations + ", needsPoll=" + needsPoll);
if (pendingOperations == 0 && needsPoll) {
lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
- cm.getCurrentCalls(lastRelevantPoll);
+ cm.getCurrentCalls(lastRelevantPoll);
} else if (pendingOperations < 0) {
// this should never happen
Log.e(LOG_TAG,"CdmaCallTracker.pendingOperations < 0");
pendingOperations = 0;
}
}
-
+
private void
updatePhoneState() {
Phone.State oldState = state;
-
+
if (ringingCall.isRinging()) {
state = Phone.State.RINGING;
} else if (pendingMO != null ||
@@ -335,7 +367,7 @@ public final class CdmaCallTracker extends CallTracker {
state = Phone.State.OFFHOOK;
} else {
state = Phone.State.IDLE;
- }
+ }
if (state == Phone.State.IDLE && oldState != state) {
voiceCallEndedRegistrants.notifyRegistrants(
@@ -349,13 +381,13 @@ public final class CdmaCallTracker extends CallTracker {
phone.notifyPhoneStateChanged();
}
}
-
+
// ***** Overwritten from CallTracker
-
+
protected void
handlePollCalls(AsyncResult ar) {
List polledCalls;
-
+
if (ar.exception == null) {
polledCalls = (List)ar.result;
} else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
@@ -375,7 +407,7 @@ public final class CdmaCallTracker extends CallTracker {
boolean needsPollDelay = false;
boolean unknownConnectionAppeared = false;
- for (int i = 0, curDC = 0, dcSize = polledCalls.size()
+ for (int i = 0, curDC = 0, dcSize = polledCalls.size()
; i < connections.length; i++) {
CdmaConnection conn = connections[i];
DriverCall dc = null;
@@ -432,7 +464,7 @@ public final class CdmaCallTracker extends CallTracker {
// which is neither a ringing call or one we created.
// Either we've crashed and re-attached to an existing
// call, or something else (eg, SIM) initiated the call.
-
+
Log.i(LOG_TAG,"Phantom call appeared " + dc);
// If it's a connected call, set the connect time so that
@@ -449,8 +481,8 @@ 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);
+ // tracking.
+ droppedDuringPoll.add(conn);
// Dropped connections are removed from the CallTracker
// list but kept in the Call list
connections[i] = null;
@@ -458,7 +490,7 @@ public final class CdmaCallTracker extends CallTracker {
// Connection in CLCC response does not match what
// we were tracking. Assume dropped call and new call
- droppedDuringPoll.add(conn);
+ droppedDuringPoll.add(conn);
connections[i] = new CdmaConnection (dc, this, i);
if (connections[i].getCall() == ringingCall) {
@@ -494,11 +526,11 @@ public final class CdmaCallTracker extends CallTracker {
// This is the first poll after an ATD.
// We expect the pending call to appear in the list
// If it does not, we land here
- if (pendingMO != null) {
- Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
+ if (pendingMO != null) {
+ Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
+ foregroundCall.getState());
- droppedDuringPoll.add(pendingMO);
+ droppedDuringPoll.add(pendingMO);
pendingMO = null;
hangupPendingMO = false;
}
@@ -519,7 +551,7 @@ public final class CdmaCallTracker extends CallTracker {
if (conn.cause == Connection.DisconnectCause.LOCAL) {
cause = Connection.DisconnectCause.INCOMING_REJECTED;
} else {
- cause = Connection.DisconnectCause.INCOMING_MISSED;
+ cause = Connection.DisconnectCause.INCOMING_MISSED;
}
if (Phone.DEBUG_PHONE) {
@@ -532,8 +564,7 @@ public final class CdmaCallTracker extends CallTracker {
// Local hangup
droppedDuringPoll.remove(i);
conn.onDisconnect(Connection.DisconnectCause.LOCAL);
- } else if (conn.cause ==
- Connection.DisconnectCause.INVALID_NUMBER) {
+ } else if (conn.cause == Connection.DisconnectCause.INVALID_NUMBER) {
droppedDuringPoll.remove(i);
conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER);
}
@@ -575,7 +606,7 @@ public final class CdmaCallTracker extends CallTracker {
/*package*/ void
hangup (CdmaConnection conn) throws CallStateException {
if (conn.owner != this) {
- throw new CallStateException ("CdmaConnection " + conn
+ throw new CallStateException ("CdmaConnection " + conn
+ "does not belong to CdmaCallTracker " + this);
}
@@ -584,14 +615,14 @@ public final class CdmaCallTracker extends CallTracker {
// GSM index assigned yet
if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
- hangupPendingMO = true;
+ hangupPendingMO = true;
} else {
- try {
- cm.hangupConnection (conn.getGSMIndex(), obtainCompleteMessage());
+ try {
+ cm.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage());
} catch (CallStateException ex) {
// Ignore "connection not found"
// Call may have hung up already
- Log.w(LOG_TAG,"CdmaCallTracker WARN: hangup() on absent connection "
+ Log.w(LOG_TAG,"CdmaCallTracker WARN: hangup() on absent connection "
+ conn);
}
}
@@ -602,20 +633,20 @@ public final class CdmaCallTracker extends CallTracker {
/*package*/ void
separate (CdmaConnection conn) throws CallStateException {
if (conn.owner != this) {
- throw new CallStateException ("CdmaConnection " + conn
+ throw new CallStateException ("CdmaConnection " + conn
+ "does not belong to CdmaCallTracker " + this);
}
try {
- cm.separateConnection (conn.getGSMIndex(),
+ cm.separateConnection (conn.getCDMAIndex(),
obtainCompleteMessage(EVENT_SEPARATE_RESULT));
} catch (CallStateException ex) {
// Ignore "connection not found"
// Call may have hung up already
- Log.w(LOG_TAG,"CdmaCallTracker WARN: separate() on absent connection "
+ Log.w(LOG_TAG,"CdmaCallTracker WARN: separate() on absent connection "
+ conn);
}
- }
-
+ }
+
//***** Called from CDMAPhone
/*package*/ void
@@ -623,13 +654,13 @@ public final class CdmaCallTracker extends CallTracker {
desiredMute = mute;
cm.setMute(desiredMute, null);
}
-
+
/*package*/ boolean
getMute() {
return desiredMute;
- }
+ }
+
-
//***** Called from CdmaCall
/* package */ void
@@ -684,7 +715,7 @@ public final class CdmaCallTracker extends CallTracker {
int count = call.connections.size();
for (int i = 0; i < count; i++) {
CdmaConnection cn = (CdmaConnection)call.connections.get(i);
- if (cn.getGSMIndex() == index) {
+ if (cn.getCDMAIndex() == index) {
cm.hangupConnection(index, obtainCompleteMessage());
return;
}
@@ -698,27 +729,27 @@ public final class CdmaCallTracker extends CallTracker {
int count = call.connections.size();
for (int i = 0; i < count; i++) {
CdmaConnection cn = (CdmaConnection)call.connections.get(i);
- cm.hangupConnection(cn.getGSMIndex(), obtainCompleteMessage());
+ cm.hangupConnection(cn.getCDMAIndex(), obtainCompleteMessage());
}
} catch (CallStateException ex) {
Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
}
}
-
+
/* package */
CdmaConnection getConnectionByIndex(CdmaCall call, int index)
throws CallStateException {
int count = call.connections.size();
for (int i = 0; i < count; i++) {
CdmaConnection cn = (CdmaConnection)call.connections.get(i);
- if (cn.getGSMIndex() == index) {
+ if (cn.getCDMAIndex() == index) {
return cn;
}
}
return null;
}
-
+
private Phone.SuppService getFailedService(int what) {
switch (what) {
case EVENT_SWITCH_RESULT:
@@ -733,16 +764,22 @@ public final class CdmaCallTracker extends CallTracker {
return Phone.SuppService.UNKNOWN;
}
+ private void handleRadioNotAvailable() {
+ // handlePollCalls will clear out its
+ // call list when it gets the CommandException
+ // error result from this
+ pollCallsWhenSafe();
+ }
+
//****** Overridden from Handler
- public void
+ public void
handleMessage (Message msg) {
AsyncResult ar;
-
+
switch (msg.what) {
case EVENT_POLL_CALLS_RESULT:{
- //TODO Remove
- Log.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
+ Log.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
ar = (AsyncResult)msg.obj;
if(msg == lastRelevantPoll) {
@@ -759,25 +796,17 @@ public final class CdmaCallTracker extends CallTracker {
ar = (AsyncResult)msg.obj;
operationComplete();
break;
-
-// TODO
+
case EVENT_SWITCH_RESULT:
-// case EVENT_CONFERENCE_RESULT:
-// case EVENT_SEPARATE_RESULT:
-// case EVENT_ECT_RESULT:
- ar = (AsyncResult)msg.obj;
- if (ar.exception != null) {
- // TODO: will be handles by InCall Supp. Service use case
- //phone.notifySuppServiceFailed(getFailedService(msg.what));
- }
- operationComplete();
+ ar = (AsyncResult)msg.obj;
+ operationComplete();
break;
case EVENT_GET_LAST_CALL_FAIL_CAUSE:
int causeCode;
ar = (AsyncResult)msg.obj;
- operationComplete();
+ operationComplete();
if (ar.exception != null) {
// An exception occurred...just treat the disconnect
@@ -788,7 +817,7 @@ public final class CdmaCallTracker extends CallTracker {
} else {
causeCode = ((int[])ar.result)[0];
}
-
+
for (int i = 0, s = droppedDuringPoll.size()
; i < s ; i++
) {
@@ -802,31 +831,26 @@ public final class CdmaCallTracker extends CallTracker {
phone.notifyCallStateChanged();
droppedDuringPoll.clear();
break;
-
-// TODO: check if needed
-// case EVENT_REPOLL_AFTER_DELAY:
+
case EVENT_CALL_STATE_CHANGE:
- Log.d(LOG_TAG, "Event EVENT_CALL_STATE_CHANGE Received"); //TODO Remove
pollCallsWhenSafe();
break;
- case EVENT_RADIO_AVAILABLE:{
- Log.d(LOG_TAG, "Event EVENT_RADIO_AVAILABLE Received"); //TODO Remove
+ case EVENT_RADIO_AVAILABLE:
handleRadioAvailable();
- }
break;
-
+
case EVENT_RADIO_NOT_AVAILABLE:
- Log.d(LOG_TAG, "Event EVENT_RADIO_NOT_AVAILABLE Received"); //TODO Remove
- //handleRadioNotAvailable(); //TODO
+ handleRadioNotAvailable();
break;
+
default:{
- throw new RuntimeException("unexpected event not handled");
+ throw new RuntimeException("unexpected event not handled");
}
}
}
-
- private void log(String msg) {
+
+ protected void log(String msg) {
Log.d(LOG_TAG, "[CdmaCallTracker] " + msg);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index 495bf3b66d89..019685b9cb79 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -18,17 +18,17 @@ package com.android.internal.telephony.cdma;
import com.android.internal.telephony.*;
+import android.os.AsyncResult;
import android.os.Handler;
-import android.os.Registrant;
import android.os.Looper;
import android.os.Message;
-import android.os.AsyncResult;
+import android.os.Registrant;
import android.os.SystemClock;
-import android.util.Log;
import android.util.Config;
+import android.util.Log;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
-
+
/**
* {@hide}
@@ -41,13 +41,13 @@ public class CdmaConnection extends Connection {
CdmaCallTracker owner;
CdmaCall parent;
-
- String address; // MAY BE NULL!!!
+
+ String address; // MAY BE NULL!!!
String dialString; // outgoing calls only
- String postDialString; // outgoing calls only
+ String postDialString; // outgoing calls only
boolean isIncoming;
- boolean disconnected;
-
+ boolean disconnected;
+
int index; // index in CdmaCallTracker.connections[], -1 if unassigned
/*
@@ -65,14 +65,14 @@ public class CdmaConnection extends Connection {
*/
long connectTimeReal;
long duration;
- long holdingStartTime; // The time when the Connection last transitioned
+ long holdingStartTime; // The time when the Connection last transitioned
// into HOLDING
int nextPostDialChar; // index into postDialString
-
+
DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED;
PostDialState postDialState = PostDialState.NOT_STARTED;
-
+
Handler h;
//***** Event Constants
@@ -93,6 +93,7 @@ public class CdmaConnection extends Connection {
public void
handleMessage(Message msg) {
+
switch (msg.what) {
case EVENT_NEXT_POST_DIAL:
case EVENT_DTMF_DONE:
@@ -143,6 +144,9 @@ public class CdmaConnection extends Connection {
parent.attachFake(this, CdmaCall.State.DIALING);
}
+ public void dispose() {
+ }
+
static boolean
equalsHandlesNulls (Object a, Object b) {
return (a == null) ? (b == null) : a.equals (b);
@@ -161,19 +165,18 @@ public class CdmaConnection extends Connection {
// no control over when they begin, so we might as well
String cAddress = PhoneNumberUtils.stringFromStringAndTOA(c.number, c.TOA);
- return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
- }
-
+ return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
+ }
+
public String
toString() {
return (isIncoming ? "incoming" : "outgoing");
}
public String getAddress() {
- return address;
+ return address;
}
-
public CdmaCall getCall() {
return parent;
}
@@ -220,13 +223,13 @@ public class CdmaConnection extends Connection {
public CdmaCall.State getState() {
if (disconnected) {
return CdmaCall.State.DISCONNECTED;
- } else {
+ } else {
return super.getState();
}
}
public void hangup() throws CallStateException {
- if (!disconnected) {
+ if (!disconnected) {
owner.hangup(this);
} else {
throw new CallStateException ("disconnected");
@@ -234,7 +237,7 @@ public class CdmaConnection extends Connection {
}
public void separate() throws CallStateException {
- if (!disconnected) {
+ if (!disconnected) {
owner.separate(this);
} else {
throw new CallStateException ("disconnected");
@@ -247,7 +250,7 @@ public class CdmaConnection extends Connection {
public void proceedAfterWaitChar() {
if (postDialState != PostDialState.WAIT) {
- Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected "
+ Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected "
+ "getPostDialState() to be WAIT but was " + postDialState);
return;
}
@@ -256,10 +259,10 @@ public class CdmaConnection extends Connection {
processNextPostDialChar();
}
-
+
public void proceedAfterWildChar(String str) {
if (postDialState != PostDialState.WILD) {
- Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected "
+ Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected "
+ "getPostDialState() to be WILD but was " + postDialState);
return;
}
@@ -296,22 +299,22 @@ public class CdmaConnection extends Connection {
postDialString = buf.toString();
nextPostDialChar = 0;
if (Phone.DEBUG_PHONE) {
- log("proceedAfterWildChar: new postDialString is " +
+ log("proceedAfterWildChar: new postDialString is " +
postDialString);
}
processNextPostDialChar();
}
}
-
+
public void cancelPostDial() {
postDialState = PostDialState.CANCELLED;
}
- /**
+ /**
* Called when this Connection is being hung up locally (eg, user pressed "end")
* Note that at this point, the hangup request has been dispatched to the radio
- * but no response has yet been received so update() has not yet been called
+ * but no response has yet been received so update() has not yet been called
*/
void
onHangupLocal() {
@@ -324,31 +327,12 @@ public class CdmaConnection extends Connection {
* See 22.001 Annex F.4 for mapping of cause codes
* to local tones
*/
-
+
switch (causeCode) {
case CallFailCause.USER_BUSY:
return DisconnectCause.BUSY;
-
- // TODO: check if cases are needed for CDMA
-// case CallFailCause.NO_CIRCUIT_AVAIL:
-// case CallFailCause.TEMPORARY_FAILURE:
-// case CallFailCause.SWITCHING_CONGESTION:
-// case CallFailCause.CHANNEL_NOT_AVAIL:
-// case CallFailCause.QOS_NOT_AVAIL:
-// case CallFailCause.BEARER_NOT_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.ERROR_UNSPECIFIED:
- case CallFailCause.NORMAL_CLEARING:
+ case CallFailCause.NORMAL_CLEARING:
default:
CDMAPhone phone = owner.phone;
int serviceState = phone.getServiceState().getState();
@@ -357,8 +341,9 @@ public class CdmaConnection extends Connection {
} else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
|| serviceState == ServiceState.STATE_EMERGENCY_ONLY ) {
return DisconnectCause.OUT_OF_SERVICE;
- } else if (phone.getIccCard().getState() != RuimCard.State.READY) {
- return DisconnectCause.SIM_ERROR;
+ } else if (phone.mCM.getRadioState() != CommandsInterface.RadioState.NV_READY
+ && phone.getIccCard().getState() != RuimCard.State.READY) {
+ return DisconnectCause.ICC_ERROR;
} else {
return DisconnectCause.NORMAL;
}
@@ -374,10 +359,10 @@ public class CdmaConnection extends Connection {
/*package*/ void
onDisconnect(DisconnectCause cause) {
this.cause = cause;
-
- if (!disconnected) {
+
+ if (!disconnected) {
index = -1;
-
+
disconnectTime = System.currentTimeMillis();
duration = SystemClock.elapsedRealtime() - connectTimeReal;
disconnected = true;
@@ -388,7 +373,7 @@ public class CdmaConnection extends Connection {
owner.phone.notifyDisconnect(this);
if (parent != null) {
- parent.connectionDisconnected(this);
+ parent.connectionDisconnected(this);
}
}
}
@@ -463,13 +448,12 @@ public class CdmaConnection extends Connection {
onStartedHolding();
}
- // TODO: find another name for this function
/*package*/ int
- getGSMIndex() throws CallStateException {
+ getCDMAIndex() throws CallStateException {
if (index >= 0) {
return index + 1;
} else {
- throw new CallStateException ("GSM index not yet assigned");
+ throw new CallStateException ("CDMA connection index not assigned");
}
}
@@ -510,21 +494,21 @@ public class CdmaConnection extends Connection {
} 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
+ // "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...."
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),
+ 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
+ // "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),
+ h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
PAUSE_DELAY_MILLIS);
}
} else if (c == PhoneNumberUtils.WAIT) {
@@ -540,7 +524,7 @@ public class CdmaConnection extends Connection {
public String
getRemainingPostDialString() {
- if (postDialState == PostDialState.CANCELLED
+ if (postDialState == PostDialState.CANCELLED
|| postDialState == PostDialState.COMPLETE
|| postDialString == null
|| postDialString.length() <= nextPostDialChar
@@ -550,7 +534,7 @@ public class CdmaConnection extends Connection {
return postDialString.substring(nextPostDialChar);
}
-
+
private void
processNextPostDialChar() {
char c = 0;
@@ -569,7 +553,7 @@ public class CdmaConnection extends Connection {
c = 0;
} else {
boolean isValid;
-
+
postDialState = PostDialState.STARTED;
c = postDialString.charAt(nextPostDialChar++);
@@ -589,7 +573,8 @@ public class CdmaConnection extends Connection {
Message notifyMessage;
- if (postDialHandler != null && (notifyMessage = postDialHandler.messageForRegistrant()) != null) {
+ if (postDialHandler != null &&
+ (notifyMessage = postDialHandler.messageForRegistrant()) != null) {
// The AsyncResult.result is the Connection object
PostDialState state = postDialState;
AsyncResult ar = AsyncResult.forMessage(notifyMessage);
@@ -599,17 +584,8 @@ public class CdmaConnection extends Connection {
// arg1 is the character that was/is being processed
notifyMessage.arg1 = c;
- //Log.v("CDMA", "##### processNextPostDialChar: send msg to postDialHandler, arg1=" + c);
notifyMessage.sendToTarget();
}
-/* Reviewer Comment: moved due to Line length more than 100
- else {
- if (postDialHandler == null)
- Log.v("CDMA", "##### processNextPostDialChar: postDialHandler is NULL!");
- else
- Log.v("CDMA", "##### processNextPostDialChar: postDialHandler.messageForRegistrant() returned NULL!");
- }
-*/
}
@@ -618,11 +594,11 @@ public class CdmaConnection extends Connection {
*/
private boolean
isConnectingInOrOut() {
- return parent == null || parent == owner.ringingCall
- || parent.state == CdmaCall.State.DIALING
+ return parent == null || parent == owner.ringingCall
+ || parent.state == CdmaCall.State.DIALING
|| parent.state == CdmaCall.State.ALERTING;
}
-
+
private CdmaCall
parentFromDCState (DriverCall.State state) {
switch (state) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
new file mode 100644
index 000000000000..1b431c9f1fea
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -0,0 +1,315 @@
+/*
+ * 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.cdma;
+
+import android.os.*;
+import android.util.EventLog;
+import android.util.Log;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.DataConnection;
+import com.android.internal.telephony.DataLink;
+import com.android.internal.telephony.RILConstants;
+
+/**
+ * {@hide}
+ *
+ */
+public class CdmaDataConnection extends DataConnection {
+
+ private static final String LOG_TAG = "CDMA";
+ private static final boolean DBG = true;
+
+ /** Fail cause of last Data Call activate from RIL_LastDataCallActivateFailCause */
+ private final static int PS_NET_DOWN_REASON_OPERATOR_DETERMINED_BARRING = 8;
+ private final static int PS_NET_DOWN_REASON_UNKNOWN_APN = 27;
+ private final static int PS_NET_DOWN_REASON_AUTH_FAILED = 29;
+ private final static int PS_NET_DOWN_REASON_OPTION_NOT_SUPPORTED = 32;
+ private final static int PS_NET_DOWN_REASON_OPTION_UNSUBSCRIBED = 33;
+
+/** It is likely that the number of error codes listed below will be removed
+ * in the foreseeable future. They have been added, but not agreed upon.
+ *
+ */
+ private final static int PS_NET_DOWN_REASON_NOT_SPECIFIED = 0;
+ private final static int PS_NET_DOWN_REASON_CLOSE_IN_PROGRESS = 1;
+ private final static int PS_NET_DOWN_REASON_NW_INITIATED_TERMINATION = 2;
+ private final static int PS_NET_DOWN_REASON_APP_PREEMPTED = 3;
+ private final static int PS_NET_DOWN_REASON_LLC_SNDCP_FAILURE = 25;
+ private final static int PS_NET_DOWN_REASON_INSUFFICIENT_RESOURCES = 26;
+ private final static int PS_NET_DOWN_REASON_UNKNOWN_PDP = 28;
+ private final static int PS_NET_DOWN_REASON_GGSN_REJECT = 30;
+ private final static int PS_NET_DOWN_REASON_ACTIVATION_REJECT = 31;
+ private final static int PS_NET_DOWN_REASON_OPTION_TEMP_OOO = 34;
+ private final static int PS_NET_DOWN_REASON_NSAPI_ALREADY_USED = 35;
+ private final static int PS_NET_DOWN_REASON_REGULAR_DEACTIVATION = 36;
+ private final static int PS_NET_DOWN_REASON_QOS_NOT_ACCEPTED = 37;
+ private final static int PS_NET_DOWN_REASON_NETWORK_FAILURE = 38;
+ private final static int PS_NET_DOWN_REASON_UMTS_REATTACH_REQ = 39;
+ private final static int PS_NET_DOWN_REASON_TFT_SEMANTIC_ERROR = 41;
+ private final static int PS_NET_DOWN_REASON_TFT_SYNTAX_ERROR = 42;
+ private final static int PS_NET_DOWN_REASON_UNKNOWN_PDP_CONTEXT = 43;
+ private final static int PS_NET_DOWN_REASON_FILTER_SEMANTIC_ERROR = 44;
+ private final static int PS_NET_DOWN_REASON_FILTER_SYNTAX_ERROR = 45;
+ private final static int PS_NET_DOWN_REASON_PDP_WITHOUT_ACTIVE_TFT = 46;
+ private final static int PS_NET_DOWN_REASON_INVALID_TRANSACTION_ID = 81;
+ private final static int PS_NET_DOWN_REASON_MESSAGE_INCORRECT_SEMANTIC = 95;
+ private final static int PS_NET_DOWN_REASON_INVALID_MANDATORY_INFO = 96;
+ private final static int PS_NET_DOWN_REASON_MESSAGE_TYPE_UNSUPPORTED = 97;
+ private final static int PS_NET_DOWN_REASON_MSG_TYPE_NONCOMPATIBLE_STATE = 98;
+ private final static int PS_NET_DOWN_REASON_UNKNOWN_INFO_ELEMENT = 99;
+ private final static int PS_NET_DOWN_REASON_CONDITIONAL_IE_ERROR = 100;
+ private final static int PS_NET_DOWN_REASON_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 101;
+ private final static int PS_NET_DOWN_REASON_PROTOCOL_ERROR = 111;
+ private final static int PS_NET_DOWN_REASON_APN_TYPE_CONFLICT = 112;
+ private final static int PS_NET_DOWN_REASON_UNKNOWN_CAUSE_CODE = 113;
+ private final static int PS_NET_DOWN_REASON_INTERNAL_MIN = 200;
+ private final static int PS_NET_DOWN_REASON_INTERNAL_ERROR = 201;
+ private final static int PS_NET_DOWN_REASON_INTERNAL_CALL_ENDED = 202;
+ private final static int PS_NET_DOWN_REASON_INTERNAL_UNKNOWN_CAUSE_CODE = 203;
+ private final static int PS_NET_DOWN_REASON_INTERNAL_MAX = 204;
+ private final static int PS_NET_DOWN_REASON_CDMA_LOCK = 500;
+ private final static int PS_NET_DOWN_REASON_INTERCEPT = 501;
+ private final static int PS_NET_DOWN_REASON_REORDER = 502;
+ private final static int PS_NET_DOWN_REASON_REL_SO_REJ = 503;
+ private final static int PS_NET_DOWN_REASON_INCOM_CALL = 504;
+ private final static int PS_NET_DOWN_REASON_ALERT_STOP = 505;
+ private final static int PS_NET_DOWN_REASON_ACTIVATION = 506;
+ private final static int PS_NET_DOWN_REASON_MAX_ACCESS_PROBE = 507;
+ private final static int PS_NET_DOWN_REASON_CCS_NOT_SUPPORTED_BY_BS = 508;
+ private final static int PS_NET_DOWN_REASON_NO_RESPONSE_FROM_BS = 509;
+ private final static int PS_NET_DOWN_REASON_REJECTED_BY_BS = 510;
+ private final static int PS_NET_DOWN_REASON_INCOMPATIBLE = 511;
+ private final static int PS_NET_DOWN_REASON_ALREADY_IN_TC = 512;
+ private final static int PS_NET_DOWN_REASON_USER_CALL_ORIG_DURING_GPS = 513;
+ private final static int PS_NET_DOWN_REASON_USER_CALL_ORIG_DURING_SMS = 514;
+ private final static int PS_NET_DOWN_REASON_NO_CDMA_SRV = 515;
+ private final static int PS_NET_DOWN_REASON_CONF_FAILED = 1000;
+ private final static int PS_NET_DOWN_REASON_INCOM_REJ = 1001;
+ private final static int PS_NET_DOWN_REASON_NO_GW_SRV = 1002;
+ private final static int PS_NET_DOWN_REASON_CD_GEN_OR_BUSY = 1500;
+ private final static int PS_NET_DOWN_REASON_CD_BILL_OR_AUTH = 1501;
+ private final static int PS_NET_DOWN_REASON_CHG_HDR = 1502;
+ private final static int PS_NET_DOWN_REASON_EXIT_HDR = 1503;
+ private final static int PS_NET_DOWN_REASON_HDR_NO_SESSION = 1504;
+ private final static int PS_NET_DOWN_REASON_HDR_ORIG_DURING_GPS_FIX = 1505;
+ private final static int PS_NET_DOWN_REASON_HDR_CS_TIMEOUT = 1506;
+ private final static int PS_NET_DOWN_REASON_HDR_RELEASED_BY_CM = 1507;
+ private final static int PS_NET_DOWN_REASON_CLIENT_END = 2000;
+ private final static int PS_NET_DOWN_REASON_NO_SRV = 2001;
+ private final static int PS_NET_DOWN_REASON_FADE = 2002;
+ private final static int PS_NET_DOWN_REASON_REL_NORMAL = 2003;
+ private final static int PS_NET_DOWN_REASON_ACC_IN_PROG = 2004;
+ private final static int PS_NET_DOWN_REASON_ACC_FAIL = 2005;
+ private final static int PS_NET_DOWN_REASON_REDIR_OR_HANDOFF = 2006;
+
+ // ***** Instance Variables
+
+ // ***** Constructor
+ CdmaDataConnection(CDMAPhone phone) {
+ super(phone);
+
+ if (DBG) log("CdmaDataConnection <constructor>");
+ }
+
+ /**
+ * Setup a data connection
+ *
+ * @param onCompleted
+ * notify success or not after down
+ */
+ void connect(Message onCompleted) {
+ if (DBG) log("CdmaDataConnection Connecting...");
+
+ //setHttpProxy (apn.proxy, apn.port);
+
+ state = State.ACTIVATING;
+ onConnectCompleted = onCompleted;
+ createTime = -1;
+ lastFailTime = -1;
+ lastFailCause = FailCause.NONE;
+ receivedDisconnectReq = false;
+ phone.mCM.setupDataCall(Integer.toString(RILConstants.CDMA_PHONE), null, null, null,
+ null, obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
+ }
+
+ 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));
+ }
+ } else if (state == State.ACTIVATING) {
+ receivedDisconnectReq = true;
+ }
+ }
+
+
+ public String toString() {
+ return "State=" + state + " create=" + createTime + " lastFail="
+ + lastFailTime + " lastFailCause=" + lastFailCause;
+ }
+
+
+ protected void notifyFail(FailCause cause, Message onCompleted) {
+ if (onCompleted == null) {
+ return;
+ }
+ state = State.INACTIVE;
+ lastFailCause = cause;
+ lastFailTime = System.currentTimeMillis();
+ onConnectCompleted = null;
+
+ if(DBG) {
+ log("Notify data connection fail at " + lastFailTime +
+ " due to " + lastFailCause);
+ }
+
+ AsyncResult.forMessage(onCompleted, cause, new Exception());
+ onCompleted.sendToTarget();
+ }
+
+ protected void notifySuccess(Message onCompleted) {
+ if (onCompleted == null) {
+ return;
+ }
+
+ state = State.ACTIVE;
+ createTime = System.currentTimeMillis();
+ onConnectCompleted = null;
+ onCompleted.arg1 = cid;
+
+ if (DBG) log("Notify data connection success at " + createTime);
+
+ AsyncResult.forMessage(onCompleted);
+ onCompleted.sendToTarget();
+ }
+
+ protected void notifyDisconnect(Message msg) {
+ if (DBG) log("Notify data connection disconnect");
+
+ if (msg != null) {
+ AsyncResult.forMessage(msg);
+ msg.sendToTarget();
+ }
+ clearSettings();
+ }
+
+ protected void onLinkStateChanged(DataLink.LinkState linkState) {
+ switch (linkState) {
+ case LINK_UP:
+ notifySuccess(onConnectCompleted);
+ break;
+
+ case LINK_DOWN:
+ case LINK_EXITED:
+ phone.mCM.getLastDataCallFailCause(obtainMessage(EVENT_GET_LAST_FAIL_DONE));
+ break;
+ }
+ }
+
+ protected FailCause getFailCauseFromRequest(int rilCause) {
+ FailCause cause;
+
+ switch (rilCause) {
+ case PS_NET_DOWN_REASON_OPERATOR_DETERMINED_BARRING:
+ cause = FailCause.BARRED;
+ break;
+ case PS_NET_DOWN_REASON_AUTH_FAILED:
+ cause = FailCause.USER_AUTHENTICATION;
+ break;
+ case PS_NET_DOWN_REASON_OPTION_NOT_SUPPORTED:
+ cause = FailCause.SERVICE_OPTION_NOT_SUPPORTED;
+ break;
+ case PS_NET_DOWN_REASON_OPTION_UNSUBSCRIBED:
+ cause = FailCause.SERVICE_OPTION_NOT_SUBSCRIBED;
+ break;
+ default:
+ cause = FailCause.UNKNOWN;
+ }
+ return cause;
+ }
+
+ protected void log(String s) {
+ Log.d(LOG_TAG, "[CdmaDataConnection] " + s);
+ }
+
+ @Override
+ protected void onDeactivated(AsyncResult ar) {
+ notifyDisconnect((Message) ar.userObj);
+ if (DBG) log("CDMA Connection Deactivated");
+ }
+
+ @Override
+ protected void onSetupConnectionCompleted(AsyncResult ar) {
+ if (ar.exception != null) {
+ Log.e(LOG_TAG, "CdmaDataConnection Init failed " + ar.exception);
+
+ if (receivedDisconnectReq) {
+ // Don't bother reporting the error if there's already a
+ // pending disconnect request, since DataConnectionTracker
+ // has already updated its state.
+ notifyDisconnect(onDisconnect);
+ } else {
+ if (ar.exception instanceof CommandException
+ && ((CommandException) (ar.exception)).getCommandError()
+ == CommandException.Error.RADIO_NOT_AVAILABLE) {
+ notifyFail(FailCause.RADIO_NOT_AVAILABLE, onConnectCompleted);
+ } else {
+ phone.mCM.getLastDataCallFailCause(obtainMessage(EVENT_GET_LAST_FAIL_DONE));
+ }
+ }
+ } else {
+ if (receivedDisconnectReq) {
+ // Don't bother reporting success if there's already a
+ // pending disconnect request, since DataConnectionTracker
+ // has already updated its state.
+ disconnect(onDisconnect);
+ } else {
+ String[] response = ((String[]) ar.result);
+ cid = Integer.parseInt(response[0]);
+
+ if (response.length > 2) {
+ interfaceName = response[1];
+ ipAddress = response[2];
+ String prefix = "net." + interfaceName + ".";
+ gatewayAddress = SystemProperties.get(prefix + "gw");
+ dnsServers[0] = SystemProperties.get(prefix + "dns1");
+ dnsServers[1] = SystemProperties.get(prefix + "dns2");
+ if (DBG) {
+ log("interface=" + interfaceName + " ipAddress=" + ipAddress
+ + " gateway=" + gatewayAddress + " DNS1=" + dnsServers[0]
+ + " DNS2=" + dnsServers[1]);
+ }
+
+ if (NULL_IP.equals(dnsServers[0]) && NULL_IP.equals(dnsServers[1])) {
+ // Work around a race condition where QMI does not fill in DNS:
+ // Deactivate PDP and let DataConnectionTracker retry.
+ EventLog.writeEvent(EVENT_LOG_BAD_DNS_ADDRESS, dnsServers[0]);
+ phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_FORCE_RETRY));
+ return;
+ }
+ }
+
+ onLinkStateChanged(DataLink.LinkState.LINK_UP);
+
+ if (DBG) log("CdmaDataConnection setup on cid = " + cid);
+ }
+ }
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
new file mode 100644
index 000000000000..bc9f0d3a7003
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -0,0 +1,738 @@
+/*
+ * 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.cdma;
+
+import android.app.AlarmManager;
+import android.app.IAlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.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.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.telephony.CommandsInterface;
+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 java.util.ArrayList;
+
+/**
+ * {@hide}
+ *
+ */
+public final class CdmaDataConnectionTracker extends DataConnectionTracker {
+ private static final String LOG_TAG = "CDMA";
+ private static final boolean DBG = true;
+
+ //***** Instance Variables
+
+ // Indicates baseband will not auto-attach
+ private boolean noAutoAttach = false;
+ long nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ private IntentFilter filterS;
+ private IntentFilter filter;
+
+ //useful for debugging
+ boolean failNextConnect = false;
+
+ /**
+ * dataConnectionList holds all the Data connection
+ */
+ private ArrayList<DataConnection> dataConnectionList;
+
+ /** Currently active CdmaDataConnection */
+ private CdmaDataConnection mActiveDataConnection;
+
+ /** Defined cdma connection profiles */
+ private static int EXTERNAL_NETWORK_DEFAULT_ID = 0;
+ private static int EXTERNAL_NETWORK_NUM_TYPES = 1;
+
+ private boolean[] dataEnabled = new boolean[EXTERNAL_NETWORK_NUM_TYPES];
+
+ //***** Constants
+
+ /**
+ * Pool size of CdmaDataConnection objects.
+ */
+ private static final int DATA_CONNECTION_POOL_SIZE = 1;
+
+ private static final int POLL_CONNECTION_MILLIS = 5 * 1000;
+ static final String INTENT_RECONNECT_ALARM = "com.android.internal.telephony.cdma-reconnect";
+
+ BroadcastReceiver screenOnOffReceiver = new BroadcastReceiver () {
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Intent.ACTION_SCREEN_ON) &&
+ phone.getState() == Phone.State.IDLE) {
+ stopNetStatPoll();
+ startNetStatPoll();
+ } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
+ stopNetStatPoll();
+ startNetStatPoll();
+ } else {
+ Log.w(LOG_TAG, "DataConnectionTracker received unexpected Intent: "
+ + intent.getAction());
+ }
+ }
+ };
+
+ BroadcastReceiver alarmReceiver = new BroadcastReceiver () {
+
+ public void onReceive(Context context, Intent intent) {
+ Log.d(LOG_TAG, "Data reconnect alarm. Previous state was " + state);
+
+ if (state == State.FAILED) {
+ cleanUpConnection(false, null);
+ }
+
+ trySetupData(null);
+ }
+ };
+
+
+ //***** Constructor
+
+ CdmaDataConnectionTracker(CDMAPhone p) {
+ super(p);
+
+ p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
+ p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
+ p.mRuimRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
+ p.mCM.registerForNVReady(this, EVENT_NV_READY, null);
+ p.mCM.registerForDataStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
+ p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
+ p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
+ p.mSST.registerForCdmaDataConnectionAttached(this, EVENT_TRY_SETUP_DATA, null);
+ p.mSST.registerForCdmaDataConnectionDetached(this, EVENT_CDMA_DATA_DETACHED, null);
+ p.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null);
+ p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
+
+ this.netstat = INetStatService.Stub.asInterface(ServiceManager.getService("netstat"));
+
+ filter = new IntentFilter();
+ filter.addAction(INTENT_RECONNECT_ALARM);
+ phone.getContext().registerReceiver(
+ alarmReceiver, filter, null, phone.getHandler());
+
+ filterS = new IntentFilter();
+ filterS.addAction(Intent.ACTION_SCREEN_ON);
+ filterS.addAction(Intent.ACTION_SCREEN_OFF);
+ p.getContext().registerReceiver(screenOnOffReceiver, filterS);
+
+ mDataConnectionTracker = this;
+
+ createAllDataConnectionList();
+
+ // This preference tells us 1) initial condition for "dataEnabled",
+ // and 2) whether the RIL will setup the baseband to auto-PS attach.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(phone.getContext());
+
+ dataEnabled[EXTERNAL_NETWORK_DEFAULT_ID] =
+ !sp.getBoolean(CDMAPhone.DATA_DISABLED_ON_BOOT_KEY, false);
+ noAutoAttach = !dataEnabled[EXTERNAL_NETWORK_DEFAULT_ID];
+ }
+
+ public void dispose() {
+ //Unregister from all events
+ phone.mCM.unregisterForAvailable(this);
+ phone.mCM.unregisterForOffOrNotAvailable(this);
+ ((CDMAPhone) phone).mRuimRecords.unregisterForRecordsLoaded(this);
+ phone.mCM.unregisterForNVReady(this);
+ phone.mCM.unregisterForDataStateChanged(this);
+ ((CDMAPhone) phone).mCT.unregisterForVoiceCallEnded(this);
+ ((CDMAPhone) phone).mCT.unregisterForVoiceCallStarted(this);
+ ((CDMAPhone) phone).mSST.unregisterForCdmaDataConnectionAttached(this);
+ ((CDMAPhone) phone).mSST.unregisterForCdmaDataConnectionDetached(this);
+ ((CDMAPhone) phone).mSST.unregisterForRoamingOn(this);
+ ((CDMAPhone) phone).mSST.unregisterForRoamingOff(this);
+
+ phone.getContext().unregisterReceiver(this.alarmReceiver);
+ phone.getContext().unregisterReceiver(this.screenOnOffReceiver);
+ destroyAllDataConnectionList();
+ }
+
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "CdmaDataConnectionTracker finalized");
+ }
+
+ void setState(State s) {
+ if (state != s) {
+ if (s == State.INITING) { // request Data connection context
+ Checkin.updateStats(phone.getContext().getContentResolver(),
+ Checkin.Stats.Tag.PHONE_CDMA_DATA_ATTEMPTED, 1, 0.0);
+ }
+
+ if (s == State.CONNECTED) { // pppd is up
+ Checkin.updateStats(phone.getContext().getContentResolver(),
+ Checkin.Stats.Tag.PHONE_CDMA_DATA_CONNECTED, 1, 0.0);
+ }
+ }
+
+ state = s;
+ }
+
+ public int enableApnType(String type) {
+ // This request is mainly used to enable MMS APN
+ // In CDMA there is no need to enable/disable a different APN for MMS
+ Log.d(LOG_TAG, "Request to enableApnType("+type+")");
+ if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
+ return Phone.APN_ALREADY_ACTIVE;
+ } else {
+ return Phone.APN_REQUEST_FAILED;
+ }
+ }
+
+ public int disableApnType(String type) {
+ // This request is mainly used to disable MMS APN
+ // In CDMA there is no need to enable/disable a different APN for MMS
+ Log.d(LOG_TAG, "Request to disableApnType("+type+")");
+ if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
+ return Phone.APN_REQUEST_STARTED;
+ } else {
+ return Phone.APN_REQUEST_FAILED;
+ }
+ }
+
+ private boolean isEnabled(int cdmaDataProfile) {
+ return dataEnabled[cdmaDataProfile];
+ }
+
+ private void setEnabled(int cdmaDataProfile, boolean enable) {
+ Log.d(LOG_TAG, "setEnabled(" + cdmaDataProfile + ", " + enable + ')');
+ dataEnabled[cdmaDataProfile] = enable;
+ Log.d(LOG_TAG, "dataEnabled[DEFAULT_PROFILE]=" + dataEnabled[EXTERNAL_NETWORK_DEFAULT_ID]);
+ }
+
+ /**
+ * Prevent mobile data connections from being established,
+ * or once again allow mobile data connections. If the state
+ * toggles, then either tear down or set up data, as
+ * appropriate to match the new state.
+ * <p>This operation only affects the default connection
+ * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data
+ * @return {@code true} if the operation succeeded
+ */
+ public boolean setDataEnabled(boolean enable) {
+
+ boolean isEnabled = isEnabled(EXTERNAL_NETWORK_DEFAULT_ID);
+
+ Log.d(LOG_TAG, "setDataEnabled("+enable+") isEnabled=" + isEnabled);
+ if (!isEnabled && enable) {
+ setEnabled(EXTERNAL_NETWORK_DEFAULT_ID, true);
+ return trySetupData(Phone.REASON_DATA_ENABLED);
+ } else if (!enable) {
+ setEnabled(EXTERNAL_NETWORK_DEFAULT_ID, false);
+ return false;
+ } else // isEnabled && enable
+
+ return true;
+ }
+
+ /**
+ * Report the current state of data connectivity (enabled or disabled)
+ * @return {@code false} if data connectivity has been explicitly disabled,
+ * {@code true} otherwise.
+ */
+ public boolean getDataEnabled() {
+ return dataEnabled[EXTERNAL_NETWORK_DEFAULT_ID];
+ }
+
+ /**
+ * Report on whether data connectivity is enabled
+ * @return {@code false} if data connectivity has been explicitly disabled,
+ * {@code true} otherwise.
+ */
+ public boolean getAnyDataEnabled() {
+ for (int i=0; i < EXTERNAL_NETWORK_NUM_TYPES; i++) {
+ if (isEnabled(i)) return true;
+ }
+ return false;
+ }
+
+ //Retrieve the data roaming setting from the shared preferences.
+ public boolean getDataOnRoamingEnabled() {
+ try {
+ return Settings.System.getInt(phone.getContext().getContentResolver(),
+ Settings.System.DATA_ROAMING) > 0;
+ } catch (SettingNotFoundException snfe) {
+ return false;
+ }
+ }
+
+ private boolean isDataAllowed() {
+ boolean roaming = phone.getServiceState().getRoaming();
+ return getAnyDataEnabled() && (!roaming || getDataOnRoamingEnabled());
+ }
+
+ private boolean trySetupData(String reason) {
+ if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason));
+
+ if (phone.getSimulatedRadioControl() != null) {
+ // Assume data is connected on the simulator
+ // FIXME this can be improved
+ setState(State.CONNECTED);
+ phone.notifyDataConnection(reason);
+
+ Log.i(LOG_TAG, "(fix?) We're on the simulator; assuming data is connected");
+ return true;
+ }
+
+ int psState = ((CDMAPhone) phone).mSST.getCurrentCdmaDataConnectionState();
+ boolean roaming = phone.getServiceState().getRoaming();
+
+ if ((state == State.IDLE || state == State.SCANNING)
+ && (psState == ServiceState.RADIO_TECHNOLOGY_1xRTT ||
+ psState == ServiceState.RADIO_TECHNOLOGY_EVDO_0 ||
+ psState == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
+ && ((phone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY) ||
+ ((CDMAPhone) phone).mRuimRecords.getRecordsLoaded())
+ && ( ((CDMAPhone) phone).mSST.isConcurrentVoiceAndData() ||
+ phone.getState() == Phone.State.IDLE )
+ && isDataAllowed()) {
+
+ return setupData(reason);
+
+ } else {
+ if (DBG) {
+ log("trySetupData: Not ready for data: " +
+ " dataState=" + state +
+ " PS state=" + psState +
+ " radio state=" + phone.mCM.getRadioState() +
+ " ruim=" + ((CDMAPhone) phone).mRuimRecords.getRecordsLoaded() +
+ " concurrentVoice&Data=" + ((CDMAPhone) phone).mSST.isConcurrentVoiceAndData() +
+ " phoneState=" + phone.getState() +
+ " dataEnabled=" + getAnyDataEnabled() +
+ " roaming=" + roaming +
+ " dataOnRoamingEnable=" + getDataOnRoamingEnabled());
+ }
+ return false;
+ }
+ }
+
+ /**
+ * If tearDown is true, this only tears down a CONNECTED session. Presently,
+ * there is no mechanism for abandoning an INITING/CONNECTING session,
+ * but would likely involve cancelling pending async requests or
+ * setting a flag or new state to ignore them when they came in
+ * @param tearDown true if the underlying DataConnection should be
+ * disconnected.
+ * @param reason reason for the clean up.
+ */
+ private void cleanUpConnection(boolean tearDown, String reason) {
+ if (DBG) log("Clean up connection due to " + reason);
+
+ for (DataConnection connBase : dataConnectionList) {
+ CdmaDataConnection conn = (CdmaDataConnection) connBase;
+
+ if(conn != null) {
+ if (tearDown) {
+ Message msg = obtainMessage(EVENT_DISCONNECT_DONE);
+ conn.disconnect(msg);
+ } else {
+ conn.clearSettings();
+ }
+ }
+ }
+
+ stopNetStatPoll();
+ setState(State.IDLE);
+ phone.notifyDataConnection(reason);
+ }
+
+ private CdmaDataConnection findFreeDataConnection() {
+ for (DataConnection connBase : dataConnectionList) {
+ CdmaDataConnection conn = (CdmaDataConnection) connBase;
+ if (conn.getState() == DataConnection.State.INACTIVE) {
+ return conn;
+ }
+ }
+ return null;
+ }
+
+ private boolean setupData(String reason) {
+
+ CdmaDataConnection conn = findFreeDataConnection();
+
+ if (conn == null) {
+ if (DBG) log("setupData: No free CdmaDataConnectionfound!");
+ return false;
+ }
+
+ mActiveDataConnection = conn;
+
+ Message msg = obtainMessage();
+ msg.what = EVENT_DATA_SETUP_COMPLETE;
+
+ conn.connect(msg);
+
+ setState(State.INITING);
+ phone.notifyDataConnection(reason);
+ return true;
+ }
+
+ private void notifyDefaultData() {
+ setState(State.CONNECTED);
+ phone.notifyDataConnection(null);
+ startNetStatPoll();
+ // reset reconnect timer
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ }
+
+ private void resetPollStats() {
+ txPkts = -1;
+ rxPkts = -1;
+ sentSinceLastRecv = 0;
+ netStatPollPeriod = POLL_NETSTAT_MILLIS;
+ mNoRecvPollCount = 0;
+ }
+
+ protected void startNetStatPoll() {
+ if (state == State.CONNECTED) {
+ Log.d(LOG_TAG, "[DataConnection] Start poll NetStat");
+ resetPollStats();
+ netStatPollEnabled = true;
+ mPollNetStat.run();
+ }
+ }
+
+ protected void stopNetStatPoll() {
+ netStatPollEnabled = false;
+ removeCallbacks(mPollNetStat);
+ Log.d(LOG_TAG, "[DataConnection] Stop poll NetStat");
+ }
+
+ protected void restartRadio() {
+ Log.d(LOG_TAG, "************TURN OFF RADIO**************");
+ cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
+ 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),
+ * ServiceStateTracker will call setRadioPower when it receives the
+ * RADIO_STATE_CHANGED notification for the power off. And if the
+ * desired power state has changed in the interim, we don't want to
+ * override it with an unconditional power on.
+ */
+ }
+
+ /**
+ * Returns true if the last fail cause is something that
+ * seems like it deserves an error notification.
+ * Transient errors are ignored
+ */
+ private boolean
+ shouldPostNotification(FailCause cause) {
+ return (cause != FailCause.UNKNOWN);
+ }
+
+ private void
+ reconnectAfterFail(FailCause lastFailCauseCode) {
+ if (state == State.FAILED) {
+ Log.d(LOG_TAG, "Data Connection activate failed. Scheduling next attempt for "
+ + (nextReconnectDelay / 1000) + "s");
+
+ try {
+ IAlarmManager am = IAlarmManager.Stub.asInterface(
+ ServiceManager.getService(Context.ALARM_SERVICE));
+ PendingIntent sender = PendingIntent.getBroadcast(
+ phone.getContext(), 0,
+ new Intent(INTENT_RECONNECT_ALARM), 0);
+ am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ SystemClock.elapsedRealtime() + nextReconnectDelay,
+ sender);
+ } catch (RemoteException ex) {
+ }
+
+ // double it for next time
+ nextReconnectDelay *= 2;
+
+ if (!shouldPostNotification(lastFailCauseCode)) {
+ Log.d(LOG_TAG,"NOT Posting Data Connection Unavailable notification "
+ + "-- likely transient error");
+ } else {
+ notifyNoData(lastFailCauseCode);
+ }
+ }
+ }
+
+ private void notifyNoData(FailCause lastFailCauseCode) {
+ setState(State.FAILED);
+ }
+
+ protected void onRecordsLoaded() {
+ if (state == State.FAILED) {
+ cleanUpConnection(false, null);
+ }
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
+ }
+
+ protected void onNVReady() {
+ if (state == State.FAILED) {
+ cleanUpConnection(false, null);
+ }
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
+ }
+
+ /**
+ * @override com.android.internal.telephony.DataConnectionTracker
+ */
+ protected void onTrySetupData() {
+ trySetupData(null);
+ }
+
+ /**
+ * @override com.android.internal.telephony.DataConnectionTracker
+ */
+ protected void onRoamingOff() {
+ trySetupData(Phone.REASON_ROAMING_OFF);
+ }
+
+ /**
+ * @override com.android.internal.telephony.DataConnectionTracker
+ */
+ protected void onRoamingOn() {
+ if (getDataOnRoamingEnabled()) {
+ trySetupData(Phone.REASON_ROAMING_ON);
+ } else {
+ if (DBG) log("Tear down data connection on roaming.");
+ cleanUpConnection(true, Phone.REASON_ROAMING_ON);
+ }
+ }
+
+ /**
+ * @override com.android.internal.telephony.DataConnectionTracker
+ */
+ protected void onRadioAvailable() {
+ if (phone.getSimulatedRadioControl() != null) {
+ // Assume data is connected on the simulator
+ // FIXME this can be improved
+ setState(State.CONNECTED);
+ phone.notifyDataConnection(null);
+
+ Log.i(LOG_TAG, "We're on the simulator; assuming data is connected");
+ }
+
+ if (state != State.IDLE) {
+ cleanUpConnection(true, null);
+ }
+ }
+
+ /**
+ * @override com.android.internal.telephony.DataConnectionTracker
+ */
+ protected void onRadioOffOrNotAvailable() {
+ // Make sure our reconnect delay starts at the initial value
+ // next time the radio comes on
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+
+ if (phone.getSimulatedRadioControl() != null) {
+ // Assume data is connected on the simulator
+ // FIXME this can be improved
+ Log.i(LOG_TAG, "We're on the simulator; assuming radio off is meaningless");
+ } else {
+ if (DBG) log("Radio is off and clean up all connection");
+ cleanUpConnection(false, Phone.REASON_RADIO_TURNED_OFF);
+ }
+ }
+
+ /**
+ * @override com.android.internal.telephony.DataConnectionTracker
+ */
+ protected void onDataSetupComplete(AsyncResult ar) {
+
+ if (ar.exception == null) {
+ // everything is setup
+ notifyDefaultData();
+
+ } else {
+ FailCause cause = (FailCause) (ar.result);
+ if(DBG) log("Data Connection setup failed " + cause);
+
+ // No try for permanent failure
+ if (cause.isPermanentFail()) {
+ notifyNoData(cause);
+ }
+
+ if (tryAgain(cause)) {
+ trySetupData(null);
+ } else {
+ notifyNoData(cause);
+ reconnectAfterFail(cause);
+ }
+ }
+
+ }
+
+ /**
+ * @override com.android.internal.telephony.DataConnectionTracker
+ */
+ protected void onDisconnectDone() {
+ if(DBG) log("EVENT_DISCONNECT_DONE");
+ trySetupData(null);
+ }
+
+ /**
+ * @override com.android.internal.telephony.DataConnectionTracker
+ */
+ protected void onVoiceCallStarted() {
+ if (state == State.CONNECTED && !((CDMAPhone) phone).mSST.isConcurrentVoiceAndData()) {
+ stopNetStatPoll();
+ phone.notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
+ }
+ }
+
+ /**
+ * @override com.android.internal.telephony.DataConnectionTracker
+ */
+ protected void onVoiceCallEnded() {
+ // in case data setup was attempted when we were on a voice call
+ trySetupData(Phone.REASON_VOICE_CALL_ENDED);
+ if (state == State.CONNECTED &&
+ !((CDMAPhone) phone).mSST.isConcurrentVoiceAndData()) {
+ startNetStatPoll();
+ phone.notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
+ } else {
+ // clean slate after call end.
+ resetPollStats();
+ }
+ }
+
+ 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);
+ }
+
+ private void createAllDataConnectionList() {
+ dataConnectionList = new ArrayList<DataConnection>();
+ CdmaDataConnection dataConn;
+
+ for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) {
+ dataConn = new CdmaDataConnection((CDMAPhone) phone);
+ dataConnectionList.add(dataConn);
+ }
+ }
+
+ private void destroyAllDataConnectionList() {
+ if(dataConnectionList != null) {
+ CdmaDataConnection pdp;
+ dataConnectionList.removeAll(dataConnectionList);
+ }
+ }
+
+ private void onCdmaDataAttached() {
+ if (state == State.CONNECTED) {
+ startNetStatPoll();
+ phone.notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED);
+ } else {
+ trySetupData(Phone.REASON_CDMA_DATA_DETACHED);
+ }
+ }
+
+ protected void onDataStateChanged (AsyncResult ar) {
+
+ if (ar.exception != null) {
+ // This is probably "radio not available" or something
+ // of that sort. If so, the whole connection is going
+ // to come down soon anyway
+ return;
+ }
+
+ Log.i(LOG_TAG, "Data connection has changed.");
+ }
+
+ String getInterfaceName() {
+ if (mActiveDataConnection != null) {
+ return mActiveDataConnection.getInterface();
+ }
+ return null;
+ }
+
+ protected String getIpAddress() {
+ if (mActiveDataConnection != null) {
+ return mActiveDataConnection.getIpAddress();
+ }
+ return null;
+ }
+
+ String getGateway() {
+ if (mActiveDataConnection != null) {
+ return mActiveDataConnection.getGatewayAddress();
+ }
+ return null;
+ }
+
+ protected String[] getDnsServers() {
+ if (mActiveDataConnection != null) {
+ return mActiveDataConnection.getDnsServers();
+ }
+ return null;
+ }
+
+ public ArrayList<DataConnection> getAllDataConnections() {
+ return dataConnectionList;
+ }
+
+ public void handleMessage (Message msg) {
+
+ switch (msg.what) {
+ case EVENT_RECORDS_LOADED:
+ onRecordsLoaded();
+ break;
+
+ case EVENT_NV_READY:
+ onNVReady();
+ break;
+
+ case EVENT_CDMA_DATA_DETACHED:
+ onCdmaDataAttached();
+ break;
+
+ case EVENT_DATA_STATE_CHANGED:
+ onDataStateChanged((AsyncResult) msg.obj);
+ break;
+
+ default:
+ // handle the message in the super class DataConnectionTracker
+ super.handleMessage(msg);
+ break;
+ }
+ }
+
+ protected void log(String s) {
+ Log.d(LOG_TAG, "[CdmaDataConnectionTracker] " + s);
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
new file mode 100644
index 000000000000..b96366b6f976
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma;
+
+
+import android.app.PendingIntent;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.os.AsyncResult;
+import android.os.Message;
+import android.util.Config;
+import android.util.Log;
+
+import com.android.internal.telephony.SmsHeader;
+import com.android.internal.telephony.SmsMessageBase;
+import com.android.internal.telephony.SMSDispatcher;
+import com.android.internal.telephony.cdma.SmsMessage;
+import com.android.internal.telephony.cdma.sms.SmsEnvelope;
+import com.android.internal.util.HexDump;
+
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+
+final class CdmaSMSDispatcher extends SMSDispatcher {
+ private static final String TAG = "CDMA";
+
+ CdmaSMSDispatcher(CDMAPhone phone) {
+ super(phone);
+ }
+
+ /**
+ * Called when a status report is received. This should correspond to
+ * a previously successful SEND.
+ * Is a special GSM function, should never be called in CDMA!!
+ *
+ * @param ar AsyncResult passed into the message handler. ar.result should
+ * be a String representing the status report PDU, as ASCII hex.
+ */
+ protected void handleStatusReport(AsyncResult ar) {
+ 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) {
+ SmsMessage sms = (SmsMessage) smsb;
+ int teleService;
+ boolean handled = false;
+
+ // Decode BD stream and set sms variables.
+ 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);
+ }
+ }
+ }
+
+ if (null == sms.getUserData()){
+ handled = true;
+ if (Config.LOGD) {
+ Log.d(TAG, "Received SMS without user data");
+ }
+ }
+
+ if (handled) return;
+
+ if (SmsEnvelope.TELESERVICE_WAP == teleService){
+ processCdmaWapPdu(sms.getUserData(), sms.messageRef, sms.getOriginatingAddress());
+ return;
+ }
+
+ // 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()) {
+ 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;
+
+ 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;
+
+ break;
+ }
+
+ case SmsHeader.APPLICATION_PORT_ADDRESSING_8_BIT: {
+ byte[] data = element.getData();
+
+ destPort = data[0] & 0xff;
+
+ break;
+ }
+
+ case SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT: {
+ byte[] data = element.getData();
+
+ destPort = (data[0] & 0xff) << 8;
+ destPort |= (data[1] & 0xff);
+
+ break;
+ }
+ }
+ }
+ }
+
+ if (referenceNumber == -1) {
+ // notify everyone of the message if it isn't partial
+ byte[][] pdus = new byte[1][];
+ pdus[0] = sms.getPdu();
+
+ if (destPort != -1) {// GSM-style WAP indication
+ if (destPort == SmsHeader.PORT_WAP_PUSH) {
+ dispatchWapPdu(sms.getUserData());
+ }
+ // The message was sent to a port, so concoct a URI for it
+ dispatchPortAddressedPdus(pdus, destPort);
+ } else {
+ // It's a normal message, dispatch it
+ dispatchPdus(pdus);
+ }
+ } else {
+ // Process the message part
+ processMessagePart(sms, referenceNumber, sequence, count, destPort);
+ }
+ }
+
+ /**
+ * Processes inbound messages that are in the WAP-WDP PDU format. See
+ * wap-259-wdp-20010614-a section 6.5 for details on the WAP-WDP PDU format.
+ * WDP segments are gathered until a datagram completes and gets dispatched.
+ *
+ * @param pdu The WAP-WDP PDU segment
+ */
+ protected void processCdmaWapPdu(byte[] pdu, int referenceNumber, String address){
+ int segment;
+ int totalSegments;
+ int index = 0;
+ int msgType;
+
+ int sourcePort;
+ int destinationPort;
+
+ msgType = pdu[index++];
+ if (msgType != 0){
+ Log.w(TAG, "Received a WAP SMS which is not WDP. Discard.");
+ return;
+ }
+ 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++];
+
+ // Lookup all other related parts
+ StringBuilder where = new StringBuilder("reference_number =");
+ where.append(referenceNumber);
+ where.append(" AND address = ?");
+ String[] whereArgs = new String[] {address};
+
+ Log.i(TAG, "Received WAP PDU. Type = " + msgType + ", originator = " + address
+ + ", src-port = " + sourcePort + ", dst-port = " + destinationPort
+ + ", ID = " + referenceNumber + ", segment# = " + segment + "/" + totalSegments);
+
+ byte[][] pdus = null;
+ Cursor cursor = null;
+ try {
+ cursor = mResolver.query(mRawUri, RAW_PROJECTION, where.toString(), whereArgs, null);
+ int cursorCount = cursor.getCount();
+ if (cursorCount != totalSegments - 1) {
+ // We don't have all the parts yet, store this one away
+ ContentValues values = new ContentValues();
+ values.put("date", new Long(0));
+ values.put("pdu", HexDump.toHexString(pdu, index, pdu.length - index));
+ values.put("address", address);
+ values.put("reference_number", referenceNumber);
+ values.put("count", totalSegments);
+ values.put("sequence", segment);
+ values.put("destination_port", destinationPort);
+
+ mResolver.insert(mRawUri, values);
+
+ return;
+ }
+
+ // All the parts are in place, deal with them
+ int pduColumn = cursor.getColumnIndex("pdu");
+ int sequenceColumn = cursor.getColumnIndex("sequence");
+
+ pdus = new byte[totalSegments][];
+ for (int i = 0; i < cursorCount; i++) {
+ cursor.moveToNext();
+ int cursorSequence = (int)cursor.getLong(sequenceColumn);
+ pdus[cursorSequence - 1] = HexDump.hexStringToByteArray(
+ cursor.getString(pduColumn));
+ }
+ // The last part will be added later
+
+ // 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.
+ } finally {
+ if (cursor != null) cursor.close();
+ }
+
+ // Build up the data stream
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ for (int i = 0; i < totalSegments-1; i++) {
+ // reassemble the (WSP-)pdu
+ output.write(pdus[i], 0, pdus[i].length);
+ }
+
+ // This one isn't in the DB, so add it
+ output.write(pdu, index, pdu.length - index);
+
+ byte[] datagram = output.toByteArray();
+ // Dispatch the PDU to applications
+ switch (destinationPort) {
+ case SmsHeader.PORT_WAP_PUSH:
+ // Handle the PUSH
+ dispatchWapPdu(datagram);
+ break;
+
+ default:{
+ pdus = new byte[1][];
+ pdus[0] = datagram;
+ // The messages were sent to any other WAP port
+ dispatchPortAddressedPdus(pdus, destinationPort);
+ break;
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ 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 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
+
+ PendingIntent sentIntent = null;
+ PendingIntent deliveryIntent = null;
+
+ if (sentIntents != null && sentIntents.size() > i) {
+ sentIntent = sentIntents.get(i);
+ }
+ if (deliveryIntents != null && deliveryIntents.size() > i) {
+ deliveryIntent = deliveryIntents.get(i);
+ }
+
+ SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
+ parts.get(i), deliveryIntent != null, data);
+
+ sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
+ }
+ }
+
+ protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
+ PendingIntent deliveryIntent) {
+ super.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
+ }
+
+ /** {@inheritDoc} */
+ protected void sendSms(SmsTracker tracker) {
+ HashMap map = tracker.mData;
+
+ byte smsc[] = (byte[]) map.get("smsc");
+ byte pdu[] = (byte[]) map.get("pdu");
+
+ Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
+
+ mCm.sendCdmaSms(pdu, reply);
+ }
+
+ /** {@inheritDoc} */
+ protected void acknowledgeLastIncomingSms(boolean success, Message response){
+ // FIXME unit test leaves cm == null. this should change
+ if (mCm != null) {
+ mCm.acknowledgeLastIncomingCdmaSms(success, response);
+ }
+ }
+
+ /** {@inheritDoc} */
+ protected void activateCellBroadcastSms(int activate, Message response) {
+ mCm.activateCdmaBroadcastSms(activate, response);
+ }
+
+ /** {@inheritDoc} */
+ protected void getCellBroadcastSmsConfig(Message response) {
+ mCm.getCdmaBroadcastConfig(response);
+ }
+
+ /** {@inheritDoc} */
+ protected void setCellBroadcastConfig(int[] configValuesArray, Message response) {
+ mCm.setCdmaBroadcastConfig(configValuesArray, response);
+ }
+
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index f6a4b62c6d3f..22ba8f46a1b5 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -22,7 +22,7 @@ import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERAT
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 static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_OPERATOR_ALPHA;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
import android.app.AlarmManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -45,13 +45,13 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.TimeUtils;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.gsm.MccTable;
+import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.gsm.CommandException;
-import com.android.internal.telephony.gsm.MccTable;
import java.util.Arrays;
-import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
@@ -81,19 +81,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
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;
@@ -107,12 +96,13 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
static final String LOG_TAG = "CDMA";
static final String TMUK = "23430";
+ private ContentResolver cr;
private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
- Log.i("CdmaServiceStateTracker", "Auto time state changed");
- revertToNitz();
+ Log.i("CdmaServiceStateTracker", "Auto time state called ...");
+ //NOTE in CDMA NITZ is not used
}
};
@@ -129,11 +119,11 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
cellLoc = new CdmaCellLocation();
newCellLoc = new CdmaCellLocation();
- cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
+ 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.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE_CDMA, null);
+ cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
cm.registerForRUIMReady(this, EVENT_RUIM_READY, null);
@@ -143,17 +133,33 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
int airplaneMode = Settings.System.getInt(
phone.getContext().getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0);
- mDesiredPowerState = ! (airplaneMode > 0);
+ mDesiredPowerState = ! (airplaneMode > 0);
- ContentResolver cr = phone.getContext().getContentResolver();
+ cr = phone.getContext().getContentResolver();
cr.registerContentObserver(
- Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
+ Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
mAutoTimeObserver);
setRssiDefaultValues();
mNeedToRegForRuimLoaded = true;
}
+ public void dispose() {
+ //Unregister for all events
+ cm.unregisterForAvailable(this);
+ cm.unregisterForRadioStateChanged(this);
+ cm.unregisterForNetworkStateChanged(this);
+ cm.unregisterForRUIMReady(this);
+ phone.unregisterForNvLoaded(this);
+ phone.mRuimRecords.unregisterForRecordsLoaded(this);
+ cm.unSetOnSignalStrengthUpdate(this);
+ cr.unregisterContentObserver(this.mAutoTimeObserver);
+ }
+
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "CdmaServiceStateTracker finalized");
+ }
+
void registerForNetworkAttach(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
networkAttachedRegistrants.add(r);
@@ -163,8 +169,12 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
}
+ void unregisterForNetworkAttach(Handler h) {
+ networkAttachedRegistrants.remove(h);
+ }
+
/**
- * Registration point for transition into GPRS attached.
+ * Registration point for transition into Data attached.
* @param h handler to notify
* @param what what code of message when delivered
* @param obj placed in Message.obj
@@ -174,15 +184,18 @@ 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
+ if (cdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_1xRTT
+ || cdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_EVDO_0
|| cdmaDataConnectionState == ServiceState.RADIO_TECHNOLOGY_EVDO_A) {
r.notifyRegistrant();
}
}
+ void unregisterForCdmaDataConnectionAttached(Handler h) {
+ cdmaDataConnectionAttachedRegistrants.remove(h);
+ }
/**
- * Registration point for transition into GPRS detached.
+ * Registration point for transition into Data detached.
* @param h handler to notify
* @param what what code of message when delivered
* @param obj placed in Message.obj
@@ -192,12 +205,15 @@ 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
+ if (cdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_1xRTT
+ && cdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_EVDO_0
&& cdmaDataConnectionState != ServiceState.RADIO_TECHNOLOGY_EVDO_A) {
r.notifyRegistrant();
}
- }
+ }
+ void unregisterForCdmaDataConnectionDetached(Handler h) {
+ cdmaDataConnectionDetachedRegistrants.remove(h);
+ }
//***** Called from CDMAPhone
public void
@@ -247,11 +263,11 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
pollState();
break;
- case EVENT_GET_SIGNAL_STRENGTH_CDMA:
+ case EVENT_GET_SIGNAL_STRENGTH:
// This callback is called when signal strength is polled
// all by itself
- if (!(cm.getRadioState().isOn())) {
+ if (!(cm.getRadioState().isOn()) || (cm.getRadioState().isGsm())) {
// Polling will continue when radio turns back on
return;
}
@@ -289,10 +305,10 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
// only update if cell location really changed
- if (cellLoc.getBaseStationId() != baseStationData[0]
- || cellLoc.getBaseStationLatitude() != baseStationData[1]
+ if (cellLoc.getBaseStationId() != baseStationData[0]
+ || cellLoc.getBaseStationLatitude() != baseStationData[1]
|| cellLoc.getBaseStationLongitude() != baseStationData[2]) {
- cellLoc.setCellLocationData(baseStationData[0],
+ cellLoc.setCellLocationData(baseStationData[0],
baseStationData[1],
baseStationData[2]);
phone.notifyLocationChanged();
@@ -313,23 +329,13 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
handlePollStateResult(msg.what, ar);
break;
- case EVENT_POLL_SIGNAL_STRENGTH_CDMA:
+ case EVENT_POLL_SIGNAL_STRENGTH:
// Just poll signal strength...not part of pollState()
- cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH_CDMA));
+ cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
break;
- //TODO Implement this case for CDMA or remove it, if it is not necessary...
- /*case EVENT_NITZ_TIME:
- ar = (AsyncResult) msg.obj;
-
- String nitzString = (String)((Object[])ar.result)[0];
- int nitzReceiveTime = ((Integer)((Object[])ar.result)[1]).intValue();
-
- setTimeFromNITZString(nitzString, nitzReceiveTime);
- break;*/
-
- case EVENT_SIGNAL_STRENGTH_UPDATE_CDMA:
+ case EVENT_SIGNAL_STRENGTH_UPDATE:
// This is a notification from
// CommandsInterface.setOnSignalStrengthUpdate
@@ -343,6 +349,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
break;
case EVENT_RUIM_RECORDS_LOADED:
+ case EVENT_NV_LOADED:
updateSpnDisplay();
break;
@@ -354,9 +361,6 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
break;
- case EVENT_NV_LOADED:
- updateSpnDisplay(); //TODO same as EVENT_RUIM_RECORDS_LOADED
- break;
default:
Log.e(LOG_TAG, "Unhandled message with number: " + msg.what);
break;
@@ -367,17 +371,18 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
protected void updateSpnDisplay() {
- // TODO Check this method again, because it is not sure at the moment how
+ // 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.getServiceProvideName();
+ String spn = null; //phone.mRuimRecords.getServiceProviderName();
String plmn = ss.getOperatorAlphaLong();
- //if (rule != curSpnRule || !TextUtils.equals(spn, curSpn) || !TextUtils.equals(plmn, curPlmn)) {
if (!TextUtils.equals(this.curPlmn, plmn)) {
- boolean showSpn = false;//TODO (rule & SIMRecords.SPN_RULE_SHOW_SPN) == SIMRecords.SPN_RULE_SHOW_SPN;
- boolean showPlmn = true;//TODO (rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_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;
Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION);
intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn);
intent.putExtra(Intents.EXTRA_SPN, spn);
@@ -432,7 +437,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
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;
+ final int offset = 3;
states = (String[])ar.result;
int responseValuesRegistrationState[] = {
@@ -440,7 +445,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
-1, //[1] baseStationId
-1, //[2] baseStationLatitude
-1, //[3] baseStationLongitude
- 0, //[4] cssIndicator; init with 0, because it is treated as a boolean
+ 0, //[4] cssIndicator; init with 0, because it is treated as a boolean
-1, //[5] systemId
-1 //[6] networkId
};
@@ -448,23 +453,24 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
if (states.length > 0) {
try {
this.mRegistrationState = Integer.parseInt(states[0]);
- if (states.length == 10) {
+ if (states.length == 10) {
for(int i = 0; i < states.length - offset; i++) {
- if (states[i + offset] != null
+ if (states[i + offset] != null
&& states[i + offset].length() > 0) {
try {
- responseValuesRegistrationState[i] =
+ 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.");
+ 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"
+ Log.e(LOG_TAG, "Too less parameters returned from"
+ " RIL_REQUEST_REGISTRATION_STATE");
}
} catch (NumberFormatException ex) {
@@ -473,12 +479,12 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
mCdmaRoaming = regCodeIsRoaming(this.mRegistrationState);
- this.newCdmaDataConnectionState =
+ this.newCdmaDataConnectionState =
radioTechnologyToServiceState(responseValuesRegistrationState[0]);
newSS.setState (regCodeToServiceState(this.mRegistrationState));
newSS.setRadioTechnology(responseValuesRegistrationState[0]);
newSS.setCssIndicator(responseValuesRegistrationState[4]);
- newSS.setSystemAndNetworkId(responseValuesRegistrationState[5],
+ newSS.setSystemAndNetworkId(responseValuesRegistrationState[5],
responseValuesRegistrationState[6]);
newNetworkType = responseValuesRegistrationState[0];
@@ -502,7 +508,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
newSS.setIsManualSelection(ints[0] == 1);
break;
default:
- Log.e(LOG_TAG, "RIL response handle in wrong phone!"
+ Log.e(LOG_TAG, "RIL response handle in wrong phone!"
+ " Expected CDMA RIL request and get GSM RIL request.");
break;
}
@@ -528,7 +534,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
newSS.setExtendedCdmaRoaming(ServiceState.REGISTRATION_STATE_ROAMING_AFFILIATE);
break;
default:
- Log.w(LOG_TAG, "Received a different registration state, "
+ Log.w(LOG_TAG, "Received a different registration state, "
+ "but don't changed the extended cdma roaming mode.");
}
pollStateDone();
@@ -564,7 +570,6 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
pollStateDone();
break;
-
case RADIO_OFF:
newSS.setStateOff();
newCellLoc.setStateInvalid();
@@ -574,25 +579,37 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
pollStateDone();
break;
+ case SIM_NOT_READY:
+ case SIM_LOCKED_OR_ABSENT:
+ case SIM_READY:
+ log("Radio Technology Change ongoing, setting SS to off");
+ newSS.setStateOff();
+ newCellLoc.setStateInvalid();
+ setRssiDefaultValues();
+ mGotCountryCode = false;
+
+ pollStateDone();
+ break;
+
default:
// Issue all poll-related commands at once
// then count down the responses, which
// are allowed to arrive out-of-order
pollingContext[0]++;
- //RIL_REQUEST_OPERATOR is necessary for CDMA
+ //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));
+ 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));
+ obtainMessage(EVENT_POLL_STATE_NETWORK_SELECTION_MODE_CDMA, pollingContext));
break;
}
}
@@ -642,25 +659,25 @@ 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.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);
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);
-
- boolean hasCdmaDataConnectionChanged =
+ (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);
+
+ boolean hasCdmaDataConnectionChanged =
cdmaDataConnectionState != newCdmaDataConnectionState;
- boolean hasNetworkTypeChanged = networkType != newNetworkType;
+ boolean hasNetworkTypeChanged = networkType != newNetworkType;
boolean hasChanged = !newSS.equals(ss);
@@ -721,44 +738,6 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
phone.setSystemProperty(PROPERTY_OPERATOR_ISO_COUNTRY, iso);
mGotCountryCode = true;
-
- if (mNeedFixZone) {
- TimeZone zone = null;
- // If the offset is (0, false) and the timezone property
- // is set, use the timezone 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, iso) < 0)) {
- zone = TimeZone.getDefault();
- // For NITZ string without timezone,
- // need adjust time to reflect default timezone setting
- long tzOffset;
- tzOffset = zone.getOffset(System.currentTimeMillis());
- SystemClock.setCurrentTimeMillis(
- System.currentTimeMillis() - tzOffset);
- } else if (iso.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, iso);
- }
-
- mNeedFixZone = false;
-
- if (zone != null) {
- Context context = phone.getContext();
- if (getAutoTime()) {
- AlarmManager alarm =
- (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- alarm.setTimeZone(zone.getID());
- }
- saveNitzTimeZone(zone.getID());
- }
- }
}
phone.setSystemProperty(PROPERTY_OPERATOR_ISROAMING,
@@ -833,7 +812,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
private void
queueNextSignalStrengthPoll() {
- if (dontPollSignalStrength) {
+ if (dontPollSignalStrength || (cm.getRadioState().isGsm())) {
// The radio is telling us about signal strength changes
// we don't have to ask it
return;
@@ -842,7 +821,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
Message msg;
msg = obtainMessage();
- msg.what = EVENT_POLL_SIGNAL_STRENGTH_CDMA;
+ msg.what = EVENT_POLL_SIGNAL_STRENGTH;
// TODO Done't poll signal strength if screen is off
sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
@@ -873,7 +852,13 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
if (rssi != oldRSSI) {
- phone.notifySignalStrength();
+ 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");
+ }
}
}
@@ -929,42 +914,13 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
/**
* @return The current CDMA data connection state. ServiceState.RADIO_TECHNOLOGY_1xRTT or
- * ServiceState.RADIO_TECHNOLOGY_EVDO is the same as "attached" and
+ * ServiceState.RADIO_TECHNOLOGY_EVDO is the same as "attached" and
* ServiceState.RADIO_TECHNOLOGY_UNKNOWN is the same as detached.
*/
/*package*/ int getCurrentCdmaDataConnectionState() {
return cdmaDataConnectionState;
}
- //TODO Maybe this is not necessary for CDMA part...
- /**
- * In the case a TMUK SIM/USIM is used, there is no indication on the
- * MMI that emergency calls can be made during emergency camping in
- * the United Kingdom on a non T-Mobile UK PLMN.
- * TMUK MCC/MNC + non-TMUK PLMN = no EC allowed.
- * @return true if TMUK MCC/MNC SIM in non-TMUK PLMN
- */
- private boolean isTmobileUkRoamingEmergency() {
- String spn = null;
- String ons = null;
- boolean isTmobileUk = false;
- /*
- if ( phone != null && phone.mSIMRecords != null)
- spn = phone.mSIMRecords.getSIMOperatorNumeric();
- if ( ss != null )
- ons = ss.getOperatorNumeric();
- */
- if ( spn != null && spn.equals(TMUK) &&
- ! (ons!= null && ons.equals(TMUK)) ) {
- isTmobileUk = true;
- }
-
- if(DBG)
- Log.d(LOG_TAG,
- "SPN=" + spn + " ONS=" + ons + " TMUK Emg=" + isTmobileUk);
- return isTmobileUk;
- }
-
/**
* code is registration state 0-5 from TS 27.007 7.2
* returns true if registered roam, false otherwise
@@ -983,7 +939,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
*/
private
boolean isRoamingBetweenOperators(boolean cdmaRoaming, ServiceState s) {
- String spn = SystemProperties.get(PROPERTY_SIM_OPERATOR_ALPHA, "empty");
+ String spn = SystemProperties.get(PROPERTY_ICC_OPERATOR_ALPHA, "empty");
String onsl = s.getOperatorAlphaLong();
String onss = s.getOperatorAlphaShort();
@@ -994,209 +950,6 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
return cdmaRoaming && !(equalsOnsl || equalsOnss);
}
- //TODO Never used. Check it!
- private static
- int twoDigitsAt(String s, int offset) {
- int a, b;
-
- a = Character.digit(s.charAt(offset), 10);
- b = Character.digit(s.charAt(offset+1), 10);
-
- if (a < 0 || b < 0) {
-
- throw new RuntimeException("invalid format");
- }
-
- return a*10 + b;
- }
-
- //TODO Never used. Check it!
- /**
- * Provides the name of the algorithmic time zone for the specified
- * offset. Taken from TimeZone.java.
- */
- private static String displayNameFor(int off) {
- off = off / 1000 / 60;
-
- char[] buf = new char[9];
- buf[0] = 'G';
- buf[1] = 'M';
- buf[2] = 'T';
-
- if (off < 0) {
- buf[3] = '-';
- off = -off;
- } else {
- buf[3] = '+';
- }
-
- int hours = off / 60;
- int minutes = off % 60;
-
- buf[4] = (char) ('0' + hours / 10);
- buf[5] = (char) ('0' + hours % 10);
-
- buf[6] = ':';
-
- buf[7] = (char) ('0' + minutes / 10);
- buf[8] = (char) ('0' + minutes % 10);
-
- return new String(buf);
- }
-
- //TODO Never used. Check it!
- /**
- * nitzReceiveTime is time_t that the NITZ time was posted
- */
- private
- void setTimeFromNITZString (String nitz, int nitzReceiveTime) {
- // "yy/mm/dd,hh:mm:ss(+/-)tz"
- // tz is in number of quarter-hours
-
- Log.i(LOG_TAG, "setTimeFromNITZString: " +
- nitz + "," + 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) {
- Context context = phone.getContext();
- if (getAutoTime()) {
- AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- alarm.setTimeZone(zone.getID());
- }
- saveNitzTimeZone(zone.getID());
- }
-
- long millisSinceNitzReceived
- = System.currentTimeMillis() - (nitzReceiveTime * 1000L);
-
- if (millisSinceNitzReceived < 0) {
- // Sanity check: something is wrong
- Log.i(LOG_TAG, "NITZ: not setting time, clock has rolled "
- + "backwards since NITZ time received, "
- + nitz);
- return;
- }
-
- if (millisSinceNitzReceived > (1000L * 1000L)) {
- // If the time is this far off, something is wrong
- Log.i(LOG_TAG, "NITZ: not setting time, more than 1000 seconds "
- + " have elapsed since time received, "
- + nitz);
-
- return;
- }
-
- // Note: with range checks above, cast to int is safe
- c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
-
- String ignore = SystemProperties.get("cdma.ignore-nitz");
- if (ignore != null && ignore.equals("yes")) {
- Log.i(LOG_TAG,
- "Not setting clock because cdma.ignore-nitz is set");
- return;
- }
-
- if (getAutoTime()) {
- Log.i(LOG_TAG, "Setting time of day to " + c.getTime()
- + " NITZ receive delay(ms): " + millisSinceNitzReceived
- + " gained(ms): "
- + (c.getTimeInMillis() - System.currentTimeMillis())
- + " from " + nitz);
-
- SystemClock.setCurrentTimeMillis(c.getTimeInMillis());
- }
- SystemProperties.set("cdma.nitz.time", String.valueOf(c.getTimeInMillis()));
- saveNitzTime(c.getTimeInMillis());
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "Parsing NITZ time " + nitz, ex);
- }
- }
-
private boolean getAutoTime() {
try {
return Settings.System.getInt(phone.getContext().getContentResolver(),
@@ -1206,39 +959,20 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
}
- private void saveNitzTimeZone(String zoneId) {
- mSavedTimeZone = zoneId;
- // Send out a sticky broadcast so the system can determine if
- // the timezone was set by the carrier...
- Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
- intent.putExtra("time-zone", zoneId);
- phone.getContext().sendStickyBroadcast(intent);
- }
+ /**
+ * @return true if phone is camping on a technology
+ * that could support voice and data simultaneously.
+ */
+ boolean isConcurrentVoiceAndData() {
- private void saveNitzTime(long time) {
- mSavedTime = time;
- mSavedAtTime = SystemClock.elapsedRealtime();
- // Send out a sticky broadcast so the system can determine if
- // the time was set by the carrier...
- Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
- intent.putExtra("time", time);
- phone.getContext().sendStickyBroadcast(intent);
+ // Note: it needs to be confirmed which CDMA network types
+ // can support voice and data calls concurrently.
+ // For the time-being, the return value will be false.
+ return false;
}
- 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) {
- AlarmManager alarm =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
- alarm.setTimeZone(mSavedTimeZone);
- SystemClock.setCurrentTimeMillis(mSavedTime
- + (SystemClock.elapsedRealtime() - mSavedAtTime));
- }
+ protected void log(String s) {
+ Log.d(LOG_TAG, "[CdmaServiceStateTracker] " + s);
}
+
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java b/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java
new file mode 100644
index 000000000000..65b733645358
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java
@@ -0,0 +1,312 @@
+/*
+ * 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.cdma;
+
+import android.content.Context;
+import android.os.*;
+import android.util.Log;
+
+import com.android.internal.telephony.*;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ *
+ * {@hide}
+ *
+ */
+public final class FeatureCode extends Handler implements MmiCode {
+ static final String LOG_TAG = "CDMA";
+
+ //***** Constants
+
+ // Call Forwarding
+ static final String FC_CF_ACTIVATE = "72";
+ static final String FC_CF_DEACTIVATE = "73";
+ static final String FC_CF_FORWARD_TO_NUMBER = "56";
+
+ // Call Forwarding Busy Line
+ static final String FC_CFBL_ACTIVATE = "90";
+ static final String FC_CFBL_DEACTIVATE = "91";
+ static final String FC_CFBL_FORWARD_TO_NUMBER = "40";
+
+ // Call Forwarding Don't Answer
+ static final String FC_CFDA_ACTIVATE = "92";
+ static final String FC_CFDA_DEACTIVATE = "93";
+ static final String FC_CFDA_FORWARD_TO_NUMBER = "42";
+
+ // Cancel Call Waiting
+ static final String FC_CCW = "70";
+
+ // Usage Sensitive Three-way Calling
+ static final String FC_3WC = "71";
+
+ // Do Not Disturb
+ static final String FC_DND_ACTIVATE = "78";
+ static final String FC_DND_DEACTIVATE = "79";
+
+ // Who Called Me?
+ static final String FC_WHO = "51";
+
+ // Rejection of Undesired Annoying Calls
+ static final String FC_RUAC_ACTIVATE = "60";
+ static final String FC_RUAC_DEACTIVATE = "80";
+
+ // Calling Number Delivery
+ // Calling Number Identification Presentation
+ static final String FC_CNIP = "65";
+ // Calling Number Identification Restriction
+ static final String FC_CNIR = "85";
+
+
+ //***** Event Constants
+
+ static final int EVENT_SET_COMPLETE = 1;
+ static final int EVENT_CDMA_FLASH_COMPLETED = 2;
+
+
+ //***** Instance Variables
+
+ CDMAPhone phone;
+ Context context;
+
+ String action; // '*' in CDMA
+ String sc; // Service Code
+ String poundString; // Entire Flash string
+ String dialingNumber;
+
+ /** Set to true in processCode, not at newFromDialString time */
+
+ State state = State.PENDING;
+ CharSequence message;
+
+ //***** Class Variables
+
+
+ // Flash Code Pattern
+
+ static Pattern sPatternSuppService = Pattern.compile(
+ "((\\*)(\\d{2,3})(#?)([^*#]*)?)(.*)");
+/* 1 2 3 4 5 6
+
+ 1 = Full string up to and including #
+ 2 = action
+ 3 = service code
+ 4 = separator
+ 5 = dialing number
+*/
+
+ static final int MATCH_GROUP_POUND_STRING = 1;
+ static final int MATCH_GROUP_ACTION_STRING = 2;
+ static final int MATCH_GROUP_SERVICE_CODE = 3;
+ static final int MATCH_GROUP_DIALING_NUMBER = 5;
+
+
+ //***** Public Class methods
+
+ /**
+ * Some dial strings in CDMA are defined to do non-call setup
+ * things, such as set supplementary service settings (eg, call
+ * forwarding). These are generally referred to as "Feature Codes".
+ * We look to see if the dial string contains a valid Feature code (potentially
+ * with a dial string at the end as well) and return info here.
+ *
+ * If the dial string contains no Feature code, we return an instance with
+ * only "dialingNumber" set
+ *
+ * Please see also S.R0006-000-A v2.0 "Wireless Features Description"
+ */
+
+ static FeatureCode newFromDialString(String dialString, CDMAPhone phone) {
+ Matcher m;
+ FeatureCode ret = null;
+
+ m = sPatternSuppService.matcher(dialString);
+
+ // Is this formatted like a standard supplementary service code?
+ if (m.matches()) {
+ ret = new FeatureCode(phone);
+ ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
+ ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION_STRING));
+ ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
+ ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
+ }
+
+ return ret;
+ }
+
+ //***** Private Class methods
+
+ /** make empty strings be null.
+ * Java regexp returns empty strings for empty groups
+ */
+ private static String makeEmptyNull (String s) {
+ if (s != null && s.length() == 0) return null;
+
+ return s;
+ }
+
+ /** returns true of the string is empty or null */
+ private static boolean isEmptyOrNull(CharSequence s) {
+ return s == null || (s.length() == 0);
+ }
+
+ static boolean isServiceCodeCallForwarding(String sc) {
+ return sc != null &&
+ (sc.equals(FC_CF_ACTIVATE)
+ || sc.equals(FC_CF_DEACTIVATE) || sc.equals(FC_CF_FORWARD_TO_NUMBER)
+ || sc.equals(FC_CFBL_ACTIVATE) || sc.equals(FC_CFBL_DEACTIVATE)
+ || sc.equals(FC_CFBL_FORWARD_TO_NUMBER) || sc.equals(FC_CFDA_ACTIVATE)
+ || sc.equals(FC_CFDA_DEACTIVATE) || sc.equals(FC_CFDA_FORWARD_TO_NUMBER));
+ }
+
+ static boolean isServiceCodeCallWaiting(String sc) {
+ return sc != null && sc.equals(FC_CCW);
+ }
+
+ static boolean isServiceCodeThreeWayCalling(String sc) {
+ return sc != null && sc.equals(FC_3WC);
+ }
+
+ static boolean isServiceCodeAnnoyingCalls(String sc) {
+ return sc != null &&
+ (sc.equals(FC_RUAC_ACTIVATE)
+ || sc.equals(FC_RUAC_DEACTIVATE));
+ }
+
+ static boolean isServiceCodeCallingNumberDelivery(String sc) {
+ return sc != null &&
+ (sc.equals(FC_CNIP)
+ || sc.equals(FC_CNIR));
+ }
+
+ static boolean isServiceCodeDoNotDisturb(String sc) {
+ return sc != null &&
+ (sc.equals(FC_DND_ACTIVATE)
+ || sc.equals(FC_DND_DEACTIVATE));
+ }
+
+
+ //***** Constructor
+
+ FeatureCode (CDMAPhone phone) {
+ super(phone.getHandler().getLooper());
+ this.phone = phone;
+ this.context = phone.getContext();
+ }
+
+
+ //***** MmiCode implementation
+
+ public State getState() {
+ return state;
+ }
+
+ public CharSequence getMessage() {
+ return message;
+ }
+
+ // inherited javadoc suffices
+ public void cancel() {
+ //Not used here
+ }
+
+ public boolean isCancelable() {
+ Log.e(LOG_TAG, "isCancelable: not used in CDMA");
+ return false;
+ }
+
+ public boolean isUssdRequest() {
+ Log.e(LOG_TAG, "isUssdRequest: not used in CDMA");
+ return false;
+ }
+
+ /** Process a Flash Code...anything that isn't a dialing number */
+ void processCode () {
+ Log.d(LOG_TAG, "send feature code...");
+ phone.mCM.sendCDMAFeatureCode(this.poundString,
+ obtainMessage(EVENT_CDMA_FLASH_COMPLETED));
+ }
+
+ /** Called from CDMAPhone.handleMessage; not a Handler subclass */
+ public void handleMessage (Message msg) {
+ AsyncResult ar;
+
+ switch (msg.what) {
+ case EVENT_SET_COMPLETE:
+ ar = (AsyncResult) (msg.obj);
+ onSetComplete(ar);
+ break;
+ case EVENT_CDMA_FLASH_COMPLETED:
+ ar = (AsyncResult) (msg.obj);
+
+ if (ar.exception != null) {
+ state = State.FAILED;
+ message = context.getText(com.android.internal.R.string.mmiError);
+ } else {
+ state = State.COMPLETE;
+ message = context.getText(com.android.internal.R.string.mmiComplete);
+ }
+ phone.onMMIDone(this);
+ break;
+ }
+ }
+
+
+ //***** Private instance methods
+
+ private CharSequence getScString() {
+ if (sc != null) {
+ if (isServiceCodeCallForwarding(sc)) {
+ return context.getText(com.android.internal.R.string.CfMmi);
+ } else if (isServiceCodeCallWaiting(sc)) {
+ return context.getText(com.android.internal.R.string.CwMmi);
+ } else if (sc.equals(FC_CNIP)) {
+ return context.getText(com.android.internal.R.string.CnipMmi);
+ } else if (sc.equals(FC_CNIR)) {
+ return context.getText(com.android.internal.R.string.CnirMmi);
+ } else if (isServiceCodeThreeWayCalling(sc)) {
+ return context.getText(com.android.internal.R.string.ThreeWCMmi);
+ } else if (isServiceCodeAnnoyingCalls(sc)) {
+ return context.getText(com.android.internal.R.string.RuacMmi);
+ } else if (isServiceCodeCallingNumberDelivery(sc)) {
+ return context.getText(com.android.internal.R.string.CndMmi);
+ } else if (isServiceCodeDoNotDisturb(sc)) {
+ return context.getText(com.android.internal.R.string.DndMmi);
+ }
+ }
+
+ return "";
+ }
+
+ private void onSetComplete(AsyncResult ar){
+ StringBuilder sb = new StringBuilder(getScString());
+ sb.append("\n");
+
+ if (ar.exception != null) {
+ state = State.FAILED;
+ sb.append(context.getText(com.android.internal.R.string.mmiError));
+ } else {
+ state = State.FAILED;
+ sb.append(context.getText(com.android.internal.R.string.mmiError));
+ }
+
+ message = sb;
+ phone.onMMIDone(this);
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimCard.java b/telephony/java/com/android/internal/telephony/cdma/RuimCard.java
index b52504dbf6a0..9d9f47958e29 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimCard.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimCard.java
@@ -17,40 +17,42 @@
package com.android.internal.telephony.cdma;
import android.os.AsyncResult;
-import android.os.RemoteException;
import android.os.Handler;
import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
+import android.os.RemoteException;
import android.util.Log;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
+import android.app.ActivityManagerNative;
import android.content.Intent;
import android.content.res.Configuration;
-import android.app.ActivityManagerNative;
import static android.Manifest.permission.READ_PHONE_STATE;
/**
+ * Note: this class shares common code with SimCard, consider a base class to minimize code
+ * duplication.
* {@hide}
*/
-// TODO to be implemented
public final class RuimCard extends Handler implements IccCard {
static final String LOG_TAG="CDMA";
-
+
//***** Instance Variables
private static final boolean DBG = true;
private CDMAPhone phone;
-
+
private CommandsInterface.IccStatus status = null;
private boolean mDesiredPinLocked;
- private boolean mDesiredFdnEnabled;
+ private boolean mDesiredFdnEnabled;
private boolean mRuimPinLocked = true; // default to locked
private boolean mRuimFdnEnabled = false; // Default to disabled.
// Will be updated when RUIM_READY.
@@ -91,7 +93,7 @@ public final class RuimCard extends Handler implements IccCard {
updateStateProperty();
}
-
+
//***** RuimCard implementation
public State
@@ -111,6 +113,9 @@ public final class RuimCard extends Handler implements IccCard {
return State.UNKNOWN;
case RUIM_READY:
return State.READY;
+ case NV_READY:
+ case NV_NOT_READY:
+ return State.ABSENT;
}
} else {
switch (status) {
@@ -127,7 +132,17 @@ public final class RuimCard extends Handler implements IccCard {
return State.UNKNOWN;
}
-//********* TODO BEGIN: this is something for the base class
+ public void dispose() {
+ //Unregister for all events
+ phone.mCM.unregisterForRUIMLockedOrAbsent(this);
+ phone.mCM.unregisterForOffOrNotAvailable(this);
+ phone.mCM.unregisterForRUIMReady(this);
+ }
+
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "RuimCard finalized");
+ }
+
private RegistrantList absentRegistrants = new RegistrantList();
private RegistrantList pinLockedRegistrants = new RegistrantList();
private RegistrantList networkLockedRegistrants = new RegistrantList();
@@ -142,7 +157,7 @@ public final class RuimCard extends Handler implements IccCard {
r.notifyRegistrant();
}
}
-
+
public void unregisterForAbsent(Handler h) {
absentRegistrants.remove(h);
}
@@ -160,7 +175,7 @@ public final class RuimCard extends Handler implements IccCard {
public void unregisterForNetworkLocked(Handler h) {
networkLockedRegistrants.remove(h);
}
-
+
public void registerForLocked(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
@@ -174,30 +189,27 @@ public final class RuimCard extends Handler implements IccCard {
public void unregisterForLocked(Handler h) {
pinLockedRegistrants.remove(h);
}
-//********* TODO END: this is something for the base class
public void supplyPin (String pin, Message onComplete) {
- phone.mCM.supplyIccPin(pin,
- obtainMessage(EVENT_PINPUK_DONE, onComplete));
+ phone.mCM.supplyIccPin(pin, obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPuk (String puk, String newPin, Message onComplete) {
- phone.mCM.supplyIccPuk(puk, newPin,
- obtainMessage(EVENT_PINPUK_DONE, onComplete));
+ phone.mCM.supplyIccPuk(puk, newPin, obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
+
public void supplyPin2 (String pin2, Message onComplete) {
- phone.mCM.supplyIccPin2(pin2,
- obtainMessage(EVENT_PINPUK_DONE, onComplete));
+ phone.mCM.supplyIccPin2(pin2, obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
+
public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
- phone.mCM.supplyIccPuk2(puk2, newPin2,
- obtainMessage(EVENT_PINPUK_DONE, onComplete));
+ phone.mCM.supplyIccPuk2(puk2, newPin2, obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyNetworkDepersonalization (String pin, Message onComplete) {
if(DBG) log("Network Despersonalization: " + pin);
phone.mCM.supplyNetworkDepersonalization(pin,
- obtainMessage(EVENT_PINPUK_DONE, onComplete));
+ obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public boolean getIccLockEnabled() {
@@ -242,7 +254,6 @@ public final class RuimCard extends Handler implements IccCard {
if(DBG) log("Change Pin1 old: " + oldPassword + " new: " + newPassword);
phone.mCM.changeIccPin(oldPassword, newPassword,
obtainMessage(EVENT_CHANGE_RUIM_PASSWORD_DONE, onComplete));
-
}
public void changeIccFdnPassword(String oldPassword, String newPassword,
@@ -250,13 +261,10 @@ public final class RuimCard extends Handler implements IccCard {
if(DBG) log("Change Pin2 old: " + oldPassword + " new: " + newPassword);
phone.mCM.changeIccPin2(oldPassword, newPassword,
obtainMessage(EVENT_CHANGE_RUIM_PASSWORD_DONE, onComplete));
-
}
- public String getServiceProviderName () {
- // TODO: SIMRecords getServiceProvideName is not implemented yet
- return "CDMA Test Provider";
- //return phone.mSIMRecords.getServiceProvideName();
+ public String getServiceProviderName() {
+ return phone.mRuimRecords.getServiceProviderName();
}
//***** Handler implementation
@@ -271,13 +279,13 @@ public final class RuimCard extends Handler implements IccCard {
switch (msg.what) {
case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
- Log.d(LOG_TAG, "Event EVENT_RADIO_OFF_OR_NOT_AVAILABLE Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_RADIO_OFF_OR_NOT_AVAILABLE Received");
status = null;
updateStateProperty();
- broadcastSimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_NOT_READY, null);
- break;
+ broadcastRuimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_NOT_READY, null);
+ break;
case EVENT_RUIM_READY:
- Log.d(LOG_TAG, "Event EVENT_RUIM_READY Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_RUIM_READY Received");
//TODO: put facility read in SIM_READY now, maybe in REG_NW
phone.mCM.getIccStatus(obtainMessage(EVENT_GET_RUIM_STATUS_DONE));
phone.mCM.queryFacilityLock (
@@ -288,20 +296,20 @@ public final class RuimCard extends Handler implements IccCard {
obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE));
break;
case EVENT_RUIM_LOCKED_OR_ABSENT:
- Log.d(LOG_TAG, "Event EVENT_RUIM_LOCKED_OR_ABSENT Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_RUIM_LOCKED_OR_ABSENT Received");
phone.mCM.getIccStatus(obtainMessage(EVENT_GET_RUIM_STATUS_DONE));
phone.mCM.queryFacilityLock (
CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
break;
case EVENT_GET_RUIM_STATUS_DONE:
- Log.d(LOG_TAG, "Event EVENT_GET_RUIM_STATUS_DONE Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_GET_RUIM_STATUS_DONE Received");
ar = (AsyncResult)msg.obj;
getRuimStatusDone(ar);
break;
case EVENT_PINPUK_DONE:
- Log.d(LOG_TAG, "Event EVENT_PINPUK_DONE Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_PINPUK_DONE Received");
// a PIN/PUK/PIN2/PUK2/Network Personalization
// request has completed. ar.userObj is the response Message
// Repoll before returning
@@ -313,7 +321,7 @@ public final class RuimCard extends Handler implements IccCard {
obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj));
break;
case EVENT_REPOLL_STATUS_DONE:
- Log.d(LOG_TAG, "Event EVENT_REPOLL_STATUS_DONE Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_REPOLL_STATUS_DONE Received");
// Finished repolling status after PIN operation
// ar.userObj is the response messaeg
// ar.userObj.obj is already an AsyncResult with an
@@ -324,17 +332,17 @@ public final class RuimCard extends Handler implements IccCard {
((Message)ar.userObj).sendToTarget();
break;
case EVENT_QUERY_FACILITY_LOCK_DONE:
- Log.d(LOG_TAG, "Event EVENT_QUERY_FACILITY_LOCK_DONE Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_QUERY_FACILITY_LOCK_DONE Received");
ar = (AsyncResult)msg.obj;
onQueryFacilityLock(ar);
break;
case EVENT_QUERY_FACILITY_FDN_DONE:
- Log.d(LOG_TAG, "Event EVENT_QUERY_FACILITY_FDN_DONE Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_QUERY_FACILITY_FDN_DONE Received");
ar = (AsyncResult)msg.obj;
onQueryFdnEnabled(ar);
break;
case EVENT_CHANGE_FACILITY_LOCK_DONE:
- Log.d(LOG_TAG, "Event EVENT_CHANGE_FACILITY_LOCK_DONE Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_CHANGE_FACILITY_LOCK_DONE Received");
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
mRuimPinLocked = mDesiredPinLocked;
@@ -349,7 +357,7 @@ public final class RuimCard extends Handler implements IccCard {
((Message)ar.userObj).sendToTarget();
break;
case EVENT_CHANGE_FACILITY_FDN_DONE:
- Log.d(LOG_TAG, "Event EVENT_CHANGE_FACILITY_FDN_DONE Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_CHANGE_FACILITY_FDN_DONE Received");
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
@@ -365,7 +373,7 @@ public final class RuimCard extends Handler implements IccCard {
((Message)ar.userObj).sendToTarget();
break;
case EVENT_CHANGE_RUIM_PASSWORD_DONE:
- Log.d(LOG_TAG, "Event EVENT_CHANGE_RUIM_PASSWORD_DONE Received"); //TODO
+ Log.d(LOG_TAG, "Event EVENT_CHANGE_RUIM_PASSWORD_DONE Received");
ar = (AsyncResult)msg.obj;
if(ar.exception != null) {
Log.e(LOG_TAG, "Error in change sim password with exception"
@@ -382,9 +390,8 @@ public final class RuimCard extends Handler implements IccCard {
//***** Private methods
-//********* TODO BEGIN: this is something for the base class
/**
- * Interperate EVENT_QUERY_FACILITY_LOCK_DONE
+ * Interpret EVENT_QUERY_FACILITY_LOCK_DONE
* @param ar is asyncResult of Query_Facility_Locked
*/
private void onQueryFacilityLock(AsyncResult ar) {
@@ -403,7 +410,7 @@ public final class RuimCard extends Handler implements IccCard {
}
/**
- * Interperate EVENT_QUERY_FACILITY_LOCK_DONE
+ * Interpret EVENT_QUERY_FACILITY_LOCK_DONE
* @param ar is asyncResult of Query_Facility_Locked
*/
private void onQueryFdnEnabled(AsyncResult ar) {
@@ -420,8 +427,7 @@ public final class RuimCard extends Handler implements IccCard {
Log.e(LOG_TAG, "[CdmaRuimCard] Bogus facility lock response");
}
}
-//********* TODO END: this is something for the base class
-
+
private void
getRuimStatusDone(AsyncResult ar) {
if (ar.exception != null) {
@@ -431,7 +437,7 @@ public final class RuimCard extends Handler implements IccCard {
return;
}
- CommandsInterface.IccStatus newStatus
+ CommandsInterface.IccStatus newStatus
= (CommandsInterface.IccStatus) ar.result;
handleRuimStatus(newStatus);
@@ -442,7 +448,7 @@ public final class RuimCard extends Handler implements IccCard {
boolean transitionedIntoPinLocked;
boolean transitionedIntoAbsent;
boolean transitionedIntoNetworkLocked;
-
+
RuimCard.State oldState, newState;
oldState = getState();
@@ -461,24 +467,22 @@ public final class RuimCard extends Handler implements IccCard {
if (transitionedIntoPinLocked) {
if(DBG) log("Notify RUIM pin or puk locked.");
pinLockedRegistrants.notifyRegistrants();
- broadcastSimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_LOCKED,
+ broadcastRuimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_LOCKED,
(newState == State.PIN_REQUIRED) ?
INTENT_VALUE_LOCKED_ON_PIN : INTENT_VALUE_LOCKED_ON_PUK);
} else if (transitionedIntoAbsent) {
if(DBG) log("Notify RUIM missing.");
absentRegistrants.notifyRegistrants();
- broadcastSimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_ABSENT, null);
+ broadcastRuimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_ABSENT, null);
} else if (transitionedIntoNetworkLocked) {
if(DBG) log("Notify RUIM network locked.");
networkLockedRegistrants.notifyRegistrants();
- broadcastSimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_LOCKED,
+ broadcastRuimStateChangedIntent(RuimCard.INTENT_VALUE_ICC_LOCKED,
INTENT_VALUE_LOCKED_NETWORK);
}
}
- // TODO: should probably be renamed to broadcastIccStateChangedIntent in SIMRecords.java
- public void broadcastSimStateChangedIntent(String value, String reason) {
- // TODO: check if intent has to be renamed
+ public void broadcastRuimStateChangedIntent(String value, String reason) {
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.putExtra(Phone.PHONE_NAME_KEY, phone.getPhoneName());
intent.putExtra(RuimCard.INTENT_KEY_ICC_STATE, value);
@@ -488,7 +492,6 @@ public final class RuimCard extends Handler implements IccCard {
ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE);
}
- // TODO: check if this is valid for CDMA
public void updateImsiConfiguration(String imsi) {
if (imsi.length() >= 6) {
Configuration config = new Configuration();
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
index 0724b23b4963..7d392f0b0fdc 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
@@ -16,16 +16,18 @@
package com.android.internal.telephony.cdma;
-import com.android.internal.telephony.*; // TODO: Remove *
-import com.android.internal.telephony.IccException;
-import com.android.internal.telephony.IccIoResult;
-import com.android.internal.telephony.IccFileTypeMismatch;
-
import android.os.*;
import android.os.AsyncResult;
-import android.os.RegistrantList;
-import android.os.Registrant;
import android.util.Log;
+
+import com.android.internal.telephony.IccConstants;
+import com.android.internal.telephony.IccException;
+import com.android.internal.telephony.IccFileHandler;
+import com.android.internal.telephony.IccFileTypeMismatch;
+import com.android.internal.telephony.IccIoResult;
+import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.PhoneProxy;
+
import java.util.ArrayList;
/**
@@ -34,424 +36,44 @@ import java.util.ArrayList;
public final class RuimFileHandler extends IccFileHandler {
static final String LOG_TAG = "CDMA";
- //***** Instance Variables
- CDMAPhone phone;
-
-
- //***** Inner Classes
-
- static class LoadLinearFixedContext {
-
- int efid;
- int recordNum, recordSize, countRecords;
- boolean loadAll;
-
- Message onLoaded;
-
- ArrayList<byte[]> results;
-
- LoadLinearFixedContext(int efid, int recordNum, Message onLoaded) {
- this.efid = efid;
- this.recordNum = recordNum;
- this.onLoaded = onLoaded;
- this.loadAll = false;
- }
-
- LoadLinearFixedContext(int efid, Message onLoaded) {
- this.efid = efid;
- this.recordNum = 1;
- this.loadAll = true;
- this.onLoaded = onLoaded;
- }
-
- }
-
+ //***** Instance Variables
//***** Constructor
RuimFileHandler(CDMAPhone phone) {
- this.phone = phone;
- }
-
- //***** Public Methods
-
- /**
- * Load a record from a SIM Linear Fixed EF
- *
- * @param fileid EF id
- * @param recordNum 1-based (not 0-based) record number
- * @param onLoaded
- *
- * ((AsyncResult)(onLoaded.obj)).result is the byte[]
- *
- */
- protected void loadEFLinearFixed(int fileid, int recordNum, Message onLoaded) {
- Message response
- = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
- new LoadLinearFixedContext(fileid, recordNum, onLoaded));
-
- phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
- }
-
- /**
- * Load a image instance record from a SIM Linear Fixed EF-IMG
- *
- * @param recordNum 1-based (not 0-based) record number
- * @param onLoaded
- *
- * ((AsyncResult)(onLoaded.obj)).result is the byte[]
- *
- */
- public void loadEFImgLinearFixed(int recordNum, Message onLoaded) {
- Message response = obtainMessage(EVENT_READ_IMG_DONE,
- new LoadLinearFixedContext(IccConstants.EF_IMG, recordNum,
- onLoaded));
-
- phone.mCM.iccIO(COMMAND_GET_RESPONSE, IccConstants.EF_IMG, "img",
- recordNum, READ_RECORD_MODE_ABSOLUTE,
- GET_RESPONSE_EF_IMG_SIZE_BYTES, null, null, response);
+ super(phone);
}
- /**
- * get record size for a linear fixed EF
- *
- * @param fileid EF id
- * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]
- * int[0] is the record length int[1] is the total length of the EF
- * file int[3] is the number of records in the EF file So int[0] *
- * int[3] = int[1]
- */
- protected void getEFLinearRecordSize(int fileid, Message onLoaded) {
- Message response
- = obtainMessage(EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE,
- new LoadLinearFixedContext(fileid, onLoaded));
-
- phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
+ public void dispose() {
}
- /**
- * Load all records from a SIM Linear Fixed EF
- *
- * @param fileid EF id
- * @param onLoaded
- *
- * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
- *
- */
- protected void loadEFLinearFixedAll(int fileid, Message onLoaded) {
- Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
- new LoadLinearFixedContext(fileid,onLoaded));
-
- phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
+ protected void finalize() {
+ Log.d(LOG_TAG, "RuimFileHandler finalized");
}
- /**
- * Load a SIM Transparent EF
- *
- * @param fileid EF id
- * @param onLoaded
- *
- * ((AsyncResult)(onLoaded.obj)).result is the byte[]
- *
- */
+ //***** Overridden from IccFileHandler
- protected void loadEFTransparent(int fileid, Message onLoaded) {
- Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
- fileid, 0, onLoaded);
-
- phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
- }
-
- /**
- * Load a SIM Transparent EF-IMG. Used right after loadEFImgLinearFixed to
- * retrive STK's icon data.
- *
- * @param fileid EF id
- * @param onLoaded
- *
- * ((AsyncResult)(onLoaded.obj)).result is the byte[]
- *
- */
- protected void loadEFImgTransparent(int fileid, int highOffset, int lowOffset,
+ @Override
+ public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset,
int length, Message onLoaded) {
Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0,
onLoaded);
-
+
phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, "img", 0, 0,
GET_RESPONSE_EF_IMG_SIZE_BYTES, null, null, response);
}
- /**
- * Update a record in a linear fixed EF
- * @param fileid EF id
- * @param recordNum 1-based (not 0-based) record number
- * @param data must be exactly as long as the record in the EF
- * @param pin2 for CHV2 operations, otherwist must be null
- * @param onComplete onComplete.obj will be an AsyncResult
- * onComplete.obj.userObj will be a IccIoResult on success
- */
- protected void updateEFLinearFixed(int fileid, int recordNum, byte[] data,
- String pin2, Message onComplete) {
- phone.mCM.iccIO(COMMAND_UPDATE_RECORD, fileid, null,
- recordNum, READ_RECORD_MODE_ABSOLUTE, data.length,
- IccUtils.bytesToHexString(data), pin2, onComplete);
- }
-
- /**
- * Update a transparent EF
- * @param fileid EF id
- * @param data must be exactly as long as the EF
- */
- protected void updateEFTransparent(int fileid, byte[] data, Message onComplete) {
- phone.mCM.iccIO(COMMAND_UPDATE_BINARY, fileid, null,
- 0, 0, data.length,
- IccUtils.bytesToHexString(data), null, onComplete);
- }
-
- //***** Overridden from Handler
-
+ @Override
public void handleMessage(Message msg) {
- AsyncResult ar;
- IccIoResult result;
- Message response = null;
- String str;
- LoadLinearFixedContext lc;
-
- IccException iccException;
- byte data[];
- int size;
- int fileid;
- int recordNum;
- int recordSize[];
-
- try {
- switch (msg.what) {
- case EVENT_READ_IMG_DONE:
- Log.d(LOG_TAG, "Event EVENT_READ_IMG_DONE Received"); //TODO
- ar = (AsyncResult) msg.obj;
- lc = (LoadLinearFixedContext) ar.userObj;
- result = (IccIoResult) ar.result;
- response = lc.onLoaded;
-
- iccException = result.getException();
- if (iccException != null) {
- sendResult(response, result.payload, ar.exception);
- }
- break;
- case EVENT_READ_ICON_DONE:
- Log.d(LOG_TAG, "Event EVENT_READ_ICON_DONE Received"); //TODO
- ar = (AsyncResult) msg.obj;
- response = (Message) ar.userObj;
- result = (IccIoResult) ar.result;
-
- iccException = result.getException();
- if (iccException != null) {
- sendResult(response, result.payload, ar.exception);
- }
- break;
- case EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE:
- Log.d(LOG_TAG, "Event EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE Received"); //TODO
- ar = (AsyncResult)msg.obj;
- lc = (LoadLinearFixedContext) ar.userObj;
- result = (IccIoResult) ar.result;
- response = lc.onLoaded;
-
- if (ar.exception != null) {
- sendResult(response, null, ar.exception);
- break;
- }
-
- iccException = result.getException();
- if (iccException != null) {
- sendResult(response, null, iccException);
- break;
- }
- data = result.payload;
-
- if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE] ||
- EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
- throw new IccFileTypeMismatch();
- }
-
- recordSize = new int[3];
- recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
- recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
- + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
- recordSize[2] = recordSize[1] / recordSize[0];
-
- sendResult(response, recordSize, null);
- break;
- case EVENT_GET_RECORD_SIZE_DONE:
- Log.d(LOG_TAG, "Event EVENT_GET_RECORD_SIZE_DONE Received"); //TODO
- ar = (AsyncResult)msg.obj;
- lc = (LoadLinearFixedContext) ar.userObj;
- result = (IccIoResult) ar.result;
- response = lc.onLoaded;
-
- if (ar.exception != null) {
- sendResult(response, null, ar.exception);
- break;
- }
-
- iccException = result.getException();
-
- if (iccException != null) {
- sendResult(response, null, iccException);
- break;
- }
-
- data = result.payload;
- fileid = lc.efid;
- recordNum = lc.recordNum;
-
- if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
- throw new IccFileTypeMismatch();
- }
-
- if (EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
- throw new IccFileTypeMismatch();
- }
-
- lc.recordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
-
- size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
- + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
-
- lc.countRecords = size / lc.recordSize;
-
- if (lc.loadAll) {
- lc.results = new ArrayList<byte[]>(lc.countRecords);
- }
-
- phone.mCM.iccIO(COMMAND_READ_RECORD, lc.efid, null,
- lc.recordNum,
- READ_RECORD_MODE_ABSOLUTE,
- lc.recordSize, null, null,
- obtainMessage(EVENT_READ_RECORD_DONE, lc));
- break;
- case EVENT_GET_BINARY_SIZE_DONE:
- Log.d(LOG_TAG, "Event EVENT_GET_BINARY_SIZE_DONE Received"); //TODO
- ar = (AsyncResult)msg.obj;
- response = (Message) ar.userObj;
- result = (IccIoResult) ar.result;
-
- if (ar.exception != null) {
- sendResult(response, null, ar.exception);
- break;
- }
-
- iccException = result.getException();
-
- if (iccException != null) {
- sendResult(response, null, iccException);
- break;
- }
-
- data = result.payload;
-
- fileid = msg.arg1;
-
- if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
- throw new IccFileTypeMismatch();
- }
-
- if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) {
- throw new IccFileTypeMismatch();
- }
-
- size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
- + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
-
- phone.mCM.iccIO(COMMAND_READ_BINARY, fileid, null,
- 0, 0, size, null, null,
- obtainMessage(EVENT_READ_BINARY_DONE,
- fileid, 0, response));
- break;
-
- case EVENT_READ_RECORD_DONE:
- Log.d(LOG_TAG, "Event EVENT_READ_RECORD_DONE Received"); //TODO
-
- ar = (AsyncResult)msg.obj;
- lc = (LoadLinearFixedContext) ar.userObj;
- result = (IccIoResult) ar.result;
- response = lc.onLoaded;
-
- if (ar.exception != null) {
- sendResult(response, null, ar.exception);
- break;
- }
-
- iccException = result.getException();
-
- if (iccException != null) {
- sendResult(response, null, iccException);
- break;
- }
-
- if (!lc.loadAll) {
- sendResult(response, result.payload, null);
- } else {
- lc.results.add(result.payload);
-
- lc.recordNum++;
-
- if (lc.recordNum > lc.countRecords) {
- sendResult(response, lc.results, null);
- } else {
- phone.mCM.iccIO(COMMAND_READ_RECORD, lc.efid, null,
- lc.recordNum,
- READ_RECORD_MODE_ABSOLUTE,
- lc.recordSize, null, null,
- obtainMessage(EVENT_READ_RECORD_DONE, lc));
- }
- }
-
- break;
-
- case EVENT_READ_BINARY_DONE:
- Log.d(LOG_TAG, "Event EVENT_READ_BINARY_DONE Received"); //TODO
- ar = (AsyncResult)msg.obj;
- response = (Message) ar.userObj;
- result = (IccIoResult) ar.result;
-
- if (ar.exception != null) {
- sendResult(response, null, ar.exception);
- break;
- }
-
- iccException = result.getException();
-
- if (iccException != null) {
- sendResult(response, null, iccException);
- break;
- }
-
- sendResult(response, result.payload, null);
- break;
-
- }} catch (Exception exc) {
- if (response != null) {
- sendResult(response, null, exc);
- } else {
- Log.e(LOG_TAG, "uncaught exception", exc);
- }
- }
+ super.handleMessage(msg);
}
- //***** Private Methods
-
- // TODO: check if this is something for the base class
- private void sendResult(Message response, Object result, Throwable ex) {
- if (response == null) {
- return;
- }
+ protected void logd(String msg) {
+ Log.d(LOG_TAG, "[RuimFileHandler] " + msg);
+ }
- AsyncResult.forMessage(response, result, ex);
+ protected void loge(String msg) {
+ Log.e(LOG_TAG, "[RuimFileHandler] " + msg);
+ }
- response.sendToTarget();
- }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
index 02d9695e5e31..78e89d56cb92 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
@@ -1,19 +1,18 @@
/*
- * 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.
- */
-
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
package com.android.internal.telephony.cdma;
@@ -26,242 +25,77 @@ import android.os.ServiceManager;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
+import com.android.internal.telephony.AdnRecord;
+import com.android.internal.telephony.AdnRecordCache;
+import com.android.internal.telephony.IccPhoneBookInterfaceManager;
+import com.android.internal.telephony.PhoneProxy;
+
import java.util.ArrayList;
import java.util.List;
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.AdnRecordCache;
-import com.android.internal.telephony.AdnRecord;
/**
* RuimPhoneBookInterfaceManager to provide an inter-process communication to
* access ADN-like SIM records.
*/
-//
-//TODO Check if a common IccPhoneBookInterfaceManager is enough!!!!
-//
+
public class RuimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
static final String LOG_TAG = "CDMA";
- static final boolean DBG = false;
-
- private CDMAPhone phone;
- private AdnRecordCache adnCache;
- private final Object mLock = new Object();
- private int recordSize[];
- private boolean success;
- private List<AdnRecord> records;
- private static final boolean ALLOW_SIM_OP_IN_UI_THREAD = false;
-
- private static final int EVENT_GET_SIZE_DONE = 1;
- private static final int EVENT_LOAD_DONE = 2;
- private static final int EVENT_UPDATE_DONE = 3;
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
- switch (msg.what) {
- case EVENT_GET_SIZE_DONE:
- Log.d(LOG_TAG, "Event EVENT_GET_SIZE_DONE Received"); //TODO
- ar = (AsyncResult) msg.obj;
- synchronized (mLock) {
- if (ar.exception == null) {
- recordSize = (int[])ar.result;
- // recordSize[0] is the record length
- // recordSize[1] is the total length of the EF file
- // recordSize[2] is the number of records in the EF file
- log("GET_RECORD_SIZE Size " + recordSize[0] +
- " total " + recordSize[1] +
- " #record " + recordSize[2]);
- mLock.notifyAll();
- }
- }
- break;
- case EVENT_UPDATE_DONE:
- Log.d(LOG_TAG, "Event EVENT_UPDATE_DONE Received"); //TODO
- ar = (AsyncResult) msg.obj;
- synchronized (mLock) {
- success = (ar.exception == null);
- mLock.notifyAll();
- }
- break;
- case EVENT_LOAD_DONE:
- Log.d(LOG_TAG, "Event EVENT_LOAD_DONE Received"); //TODO
- ar = (AsyncResult)msg.obj;
- synchronized (mLock) {
- if (ar.exception == null) {
- records = (List<AdnRecord>)
- ((ArrayList<AdnRecord>) ar.result);
- } else {
- if(DBG) log("Cannot load ADN records");
- if (records != null) {
- records.clear();
- }
- }
- mLock.notifyAll();
- }
+ switch(msg.what) {
+ default:
+ mBaseHandler.handleMessage(msg);
break;
}
}
};
public RuimPhoneBookInterfaceManager(CDMAPhone phone) {
- this.phone = phone;
- adnCache = phone.mRuimRecords.getAdnCache();
- //publish(); //TODO REMOVE
+ super(phone);
+ adnCache = phone.mRuimRecords.getAdnCache();
+ //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
}
- private void publish() {
- // TODO T: Do we have to change the service
- // as well to "iccphonebook"?
- // defined in: device/commands/binder/Service_info.c
- ServiceManager.addService("simphonebook", this);
+ public void dispose() {
+ super.dispose();
}
- /**
- * Replace oldAdn with newAdn in ADN-like record in EF
- *
- * getAdnRecordsInEf must be called at least once before this function,
- * otherwise an error will be returned
- * throws SecurityException if no WRITE_CONTACTS permission
- *
- * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
- * @param oldTag adn tag to be replaced
- * @param oldPhoneNumber adn number to be replaced
- * Set both oldTag and oldPhoneNubmer to "" means to replace an
- * empty record, aka, insert new record
- * @param newTag adn tag to be stored
- * @param newPhoneNumber adn number ot be stored
- * Set both newTag and newPhoneNubmer to "" means to replace the old
- * record with empty one, aka, delete old record
- * @param pin2 required to update EF_FDN, otherwise must be null
- * @return true for success
- */
- public boolean
- updateAdnRecordsInEfBySearch (int efid,
- String oldTag, String oldPhoneNumber,
- String newTag, String newPhoneNumber, String pin2) {
- success = false;
- return success;
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "RuimPhoneBookInterfaceManager finalized");
}
- /**
- * Update an ADN-like EF record by record index
- *
- * This is useful for iteration the whole ADN file, such as write the whole
- * phone book or erase/format the whole phonebook
- * throws SecurityException if no WRITE_CONTACTS permission
- *
- * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
- * @param newTag adn tag to be stored
- * @param newPhoneNumber adn number to be stored
- * Set both newTag and newPhoneNubmer to "" means to replace the old
- * record with empty one, aka, delete old record
- * @param index is 1-based adn record index to be updated
- * @param pin2 required to update EF_FDN, otherwise must be null
- * @return true for success
- */
- public boolean
- updateAdnRecordsInEfByIndex(int efid, String newTag,
- String newPhoneNumber, int index, String pin2) {
- if (phone.getContext().checkCallingOrSelfPermission(
- android.Manifest.permission.WRITE_CONTACTS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(
- "Requires android.permission.WRITE_CONTACTS permission");
- }
-
- if (DBG) log("updateAdnRecordsInEfByIndex: efid=" + efid +
- " Index=" + index + " ==> " +
- "("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
- synchronized(mLock) {
- checkThread();
- success = false;
- Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
- AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
- adnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to update by index");
- }
- }
- return success;
- }
-
- /**
- * Get the capacity of records in efid
- *
- * @param efid the EF id of a ADN-like SIM
- * @return int[3] array
- * recordSizes[0] is the single record length
- * recordSizes[1] is the total length of the EF file
- * recordSizes[2] is the number of records in the EF file
- */
public int[] getAdnRecordsSize(int efid) {
- if (DBG) log("getAdnRecordsSize: efid=" + efid);
+ if (DBG) logd("getAdnRecordsSize: efid=" + efid);
synchronized(mLock) {
checkThread();
recordSize = new int[3];
- Message response = mHandler.obtainMessage(EVENT_GET_SIZE_DONE);
- ((RuimFileHandler)phone.getIccFileHandler()).getEFLinearRecordSize(efid, response);
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to load from the SIM");
- }
- }
-
- return recordSize;
- }
- /**
- * Loads the AdnRecords in efid and returns them as a
- * List of AdnRecords
- *
- * throws SecurityException if no READ_CONTACTS permission
- *
- * @param efid the EF id of a ADN-like SIM
- * @return List of AdnRecord
- */
- public List<AdnRecord> getAdnRecordsInEf(int efid) {
- if (phone.getContext().checkCallingOrSelfPermission(
- android.Manifest.permission.READ_CONTACTS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(
- "Requires android.permission.READ_CONTACTS permission");
- }
-
- if (DBG) log("getAdnRecordsInEF: efid=" + efid);
+ //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
+ Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE);
- synchronized(mLock) {
- checkThread();
- Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
- adnCache.requestLoadAllAdnLike(efid, response);
+ phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to load from the SIM");
+ logd("interrupted while trying to load from the RUIM");
}
}
- return records;
- }
- private void checkThread() {
- if (!ALLOW_SIM_OP_IN_UI_THREAD) {
- // Make sure this isn't the UI thread, since it will block
- if (mHandler.getLooper().equals(Looper.myLooper())) {
- Log.e(LOG_TAG, "query() called on the main UI thread!");
- throw new IllegalStateException(
- "You cannot call query on this provder from the main UI thread.");
- }
- }
+ return recordSize;
}
- private void log(String msg) {
+ protected void logd(String msg) {
Log.d(LOG_TAG, "[RuimPbInterfaceManager] " + msg);
}
+
+ protected void loge(String msg) {
+ Log.e(LOG_TAG, "[RuimPbInterfaceManager] " + msg);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index af8f6436dd45..c23363f713de 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -16,32 +16,29 @@
package com.android.internal.telephony.cdma;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC;
+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.RegistrantList;
-import android.os.Registrant;
import android.os.Handler;
import android.os.Message;
-import android.telephony.gsm.SmsMessage;
+import android.os.Registrant;
import android.util.Log;
-import java.util.ArrayList;
-import com.android.internal.telephony.cdma.RuimCard;
-
-import com.android.internal.telephony.IccUtils;
+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.cdma.RuimCard;
import com.android.internal.telephony.gsm.MccTable;
-import com.android.internal.telephony.gsm.SimCard;
-import com.android.internal.telephony.gsm.SimTlv;
-
// can't be used since VoiceMailConstants is not public
//import com.android.internal.telephony.gsm.VoiceMailConstants;
+import com.android.internal.telephony.IccException;
import com.android.internal.telephony.IccRecords;
-import com.android.internal.telephony.PhoneBase;
+import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.PhoneProxy;
+
/**
* {@hide}
@@ -49,68 +46,38 @@ import com.android.internal.telephony.PhoneBase;
public final class RuimRecords extends IccRecords {
static final String LOG_TAG = "CDMA";
- private static final boolean CRASH_RIL = false;
-
private static final boolean DBG = true;
//***** Instance Variables
-
- CDMAPhone phone;
- RegistrantList recordsLoadedRegistrants = new RegistrantList();
-
- int recordsToLoad; // number of pending load requests
-
- AdnRecordCache adnCache;
-
- boolean recordsRequested = false; // true if we've made requests for the sim records
-
String imsi_m;
String mdn = null; // My mobile number
String h_sid;
String h_nid;
- String iccid;
-
- int mncLength = 0; // 0 is used to indicate that the value
// is not initialized
-
+
//***** Event Constants
private static final int EVENT_RUIM_READY = 1;
private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
- // TODO: check if needed for CDMA
- //private static final int EVENT_GET_IMSI_DONE = 3;
-
private static final int EVENT_GET_DEVICE_IDENTITY_DONE = 4;
private static final int EVENT_GET_ICCID_DONE = 5;
-
- // TODO: find synonyms for CDMA
-// private static final int EVENT_GET_AD_DONE = 9; // Admin data on SIM
-// private static final int EVENT_GET_MSISDN_DONE = 10;
private static final int EVENT_GET_CDMA_SUBSCRIPTION_DONE = 10;
-
private static final int EVENT_UPDATE_DONE = 14;
-
- // TODO: check if EF_CST should be used instead in CDMA
- //private static final int EVENT_GET_SST_DONE = 17;
-
- // TODO: probably needed in CDMA as well
+ private static final int EVENT_GET_SST_DONE = 17;
private static final int EVENT_GET_ALL_SMS_DONE = 18;
private static final int EVENT_MARK_SMS_READ_DONE = 19;
-
- // TODO: check for CDMA
- private static final int EVENT_SMS_ON_SIM = 21;
+
+ private static final int EVENT_SMS_ON_RUIM = 21;
private static final int EVENT_GET_SMS_DONE = 22;
-
+
private static final int EVENT_RUIM_REFRESH = 31;
-
+
//***** Constructor
- RuimRecords(CDMAPhone phone) {
- super(phone);
- this.phone = phone;
+ RuimRecords(CDMAPhone p) {
+ super(p);
- // TODO: additional constructor and implementation needed in AdnRecordCache
adnCache = new AdnRecordCache(phone);
recordsRequested = false; // No load request is made till SIM ready
@@ -119,47 +86,44 @@ public final class RuimRecords extends IccRecords {
recordsToLoad = 0;
- phone.mCM.registerForRUIMReady(this, EVENT_RUIM_READY, null);
- phone.mCM.registerForOffOrNotAvailable(
- this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- // TODO: check if needed
- //phone.mCM.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
- phone.mCM.setOnIccRefresh(this, EVENT_RUIM_REFRESH, null);
+ p.mCM.registerForRUIMReady(this, EVENT_RUIM_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();
+ onRadioOffOrNotAvailable();
}
-
- public AdnRecordCache getAdnCache() {
- return adnCache;
+
+ public void dispose() {
+ //Unregister for all events
+ phone.mCM.unregisterForRUIMReady(this);
+ phone.mCM.unregisterForOffOrNotAvailable( this);
+ phone.mCM.unSetOnIccRefresh(this);
}
-
+
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "RuimRecords finalized");
+ }
+
protected void onRadioOffOrNotAvailable() {
-// TODO: missing implementation, maybe some parts will be moved to a super class
-// Example:
-// super.onRadioOffOrNotAvailable();
-//
-// phone.setSystemProperty(PROPERTY_LINE1_VOICE_MAIL_WAITING, null);
-// phone.setSystemProperty(PROPERTY_SIM_OPERATOR_NUMERIC, null);
-// phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ALPHA, null);
-// phone.setSystemProperty(PROPERTY_SIM_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
-// // true only when fresh set of read requests are made.
-// recordsRequested = false;
+ countVoiceMessages = 0;
+ mncLength = 0;
+ iccid = null;
+
+ adnCache.reset();
+
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null);
+ phone.setSystemProperty(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
+ // true only when fresh set of read requests are made.
+ recordsRequested = false;
}
//***** Public Methods
- public void registerForRecordsLoaded(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- recordsLoadedRegistrants.add(r);
-
- if (recordsToLoad == 0 && recordsRequested == true) {
- r.notifyRegistrant(new AsyncResult(null, null, null));
- }
- }
/** Returns null if RUIM is not yet ready */
public String getIMSI_M() {
@@ -170,9 +134,16 @@ public final class RuimRecords extends IccRecords {
return mdn;
}
- // TODO: change STK to CDMA specific term
+ public void setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete){
+ // In CDMA this is Operator/OEM dependent
+ AsyncResult.forMessage((onComplete)).exception =
+ new IccException("setVoiceMailNumber not implemented");
+ onComplete.sendToTarget();
+ Log.e(LOG_TAG, "method setVoiceMailNumber is not implemented");
+ }
+
/**
- * Called by STK Service when REFRESH is received.
+ * Called by CCAT Service when REFRESH is received.
* @param fileChanged indicates whether any files changed
* @param fileList if non-null, a list of EF files that changed
*/
@@ -183,9 +154,8 @@ public final class RuimRecords extends IccRecords {
// just re-fetch all RUIM records that we cache.
fetchRuimRecords();
}
- }
+ }
- // TODO: this is something for the base class, change function name to getICCOperatorNumeric
/** Returns the 5 or 6 digit MCC/MNC of the operator that
* provided the RUIM card. Returns null of RUIM is not yet ready
*/
@@ -197,7 +167,7 @@ public final class RuimRecords extends IccRecords {
if (mncLength != 0) {
// Length = length of MCC + length of MNC
// TODO: change spec name
- // length of mcc = 3 (TS 23.003 Section 2.2)
+ // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3)
return imsi_m.substring(0, 3 + mncLength);
}
@@ -211,15 +181,6 @@ public final class RuimRecords extends IccRecords {
return imsi_m.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
}
- public void setVoiceCallForwardingFlag(int line, boolean enable) {
- // TODO T: implement or use abstract method
- }
-
- public void setVoiceMailNumber(String alphaTag, String voiceNumber,
- Message onComplete){
- // TODO T: implement or use abstract method
- }
-
//***** Overridden from Handler
public void handleMessage(Message msg) {
AsyncResult ar;
@@ -230,158 +191,87 @@ public final class RuimRecords extends IccRecords {
try { switch (msg.what) {
case EVENT_RUIM_READY:
- Log.d(LOG_TAG, "Event EVENT_RUIM_READY Received"); //TODO
onRuimReady();
break;
case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
- Log.d(LOG_TAG, "Event EVENT_RADIO_OFF_OR_NOT_AVAILABLE Received"); //TODO
onRadioOffOrNotAvailable();
- break;
-
+ break;
+
case EVENT_GET_DEVICE_IDENTITY_DONE:
- Log.d(LOG_TAG, "Event EVENT_GET_DEVICE_IDENTITY_DONE Received"); //TODO
- // TODO: might be deleted
+ Log.d(LOG_TAG, "Event EVENT_GET_DEVICE_IDENTITY_DONE Received");
break;
/* IO events */
-
- // TODO: maybe substituted by RIL_REQUEST_CDMA_SUBSCRIPTION (MDN)
-// case EVENT_GET_MSISDN_DONE:
-// isRecordLoadResponse = true;
-//
-// ar = (AsyncResult)msg.obj;
-//
-// if (ar.exception != null) {
-// Log.d(LOG_TAG, "Invalid or missing EF[MSISDN]");
-// break;
-// }
-//
-// adn = (AdnRecord)ar.result;
-//
-// msisdn = adn.getNumber();
-// msisdnTag = adn.getAlphaTag();
-//
-// Log.d(LOG_TAG, "MSISDN: " + msisdn);
-// break;
-
+
case EVENT_GET_CDMA_SUBSCRIPTION_DONE:
- Log.d(LOG_TAG, "Event EVENT_GET_CDMA_SUBSCRIPTION_DONE Received"); //TODO
ar = (AsyncResult)msg.obj;
String localTemp[] = (String[])ar.result;
if (ar.exception != null) {
break;
}
-
+
mdn = localTemp[0];
h_sid = localTemp[1];
h_nid = localTemp[2];
-
+
Log.d(LOG_TAG, "MDN: " + mdn);
-
+
break;
case EVENT_GET_ICCID_DONE:
- Log.d(LOG_TAG, "Event EVENT_GET_ICCID_DONE Received"); //TODO
isRecordLoadResponse = true;
ar = (AsyncResult)msg.obj;
data = (byte[])ar.result;
-
+
if (ar.exception != null) {
break;
- }
+ }
iccid = IccUtils.bcdToString(data, 0, data.length);
-
+
Log.d(LOG_TAG, "iccid: " + iccid);
break;
case EVENT_UPDATE_DONE:
- Log.d(LOG_TAG, "Event EVENT_UPDATE_DONE Received"); //TODO
ar = (AsyncResult)msg.obj;
if (ar.exception != null) {
Log.i(LOG_TAG, "RuimRecords update failed", ar.exception);
}
break;
- // TODO: handled by SMS use cases
-// case EVENT_GET_ALL_SMS_DONE:
-// isRecordLoadResponse = true;
-//
-// ar = (AsyncResult)msg.obj;
-// if (ar.exception != null)
-// break;
-//
-// handleSmses((ArrayList) ar.result);
-// break;
-//
-// case EVENT_MARK_SMS_READ_DONE:
-// Log.i("ENF", "marked read: sms " + msg.arg1);
-// break;
-//
-//
-// case EVENT_SMS_ON_SIM:
-// isRecordLoadResponse = false;
-//
-// ar = (AsyncResult)msg.obj;
-//
-// int[] index = (int[])ar.result;
-//
-// if (ar.exception != null || index.length != 1) {
-// Log.e(LOG_TAG, "[SIMRecords] Error on SMS_ON_SIM with exp "
-// + ar.exception + " length " + index.length);
-// } else {
-// Log.d(LOG_TAG, "READ EF_SMS RECORD index=" + index[0]);
-// phone.mSIMFileHandler.loadEFLinearFixed(EF_SMS,index[0],obtainMessage(EVENT_GET_SMS_DONE));
-// }
-// break;
-//
-// case EVENT_GET_SMS_DONE:
-// isRecordLoadResponse = false;
-// ar = (AsyncResult)msg.obj;
-// if (ar.exception == null) {
-// handleSms((byte[])ar.result);
-// } else {
-// Log.e(LOG_TAG, "[SIMRecords] Error on GET_SMS with exp "
-// + ar.exception);
-// }
-// break;
+ case EVENT_GET_ALL_SMS_DONE:
+ case EVENT_MARK_SMS_READ_DONE:
+ case EVENT_SMS_ON_RUIM:
+ case EVENT_GET_SMS_DONE:
+ Log.w(LOG_TAG, "Event not supported: " + msg.what);
+ break;
// TODO: probably EF_CST should be read instead
-// case EVENT_GET_SST_DONE:
-// isRecordLoadResponse = true;
-//
-// ar = (AsyncResult)msg.obj;
-// data = (byte[])ar.result;
-//
-// if (ar.exception != null) {
-// break;
-// }
-//
-// //Log.d(LOG_TAG, "SST: " + IccUtils.bytesToHexString(data));
-// break;
+ case EVENT_GET_SST_DONE:
+ Log.d(LOG_TAG, "Event EVENT_GET_SST_DONE Received");
+ break;
case EVENT_RUIM_REFRESH:
- Log.d(LOG_TAG, "Event EVENT_RUIM_REFRESH Received"); //TODO
isRecordLoadResponse = false;
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
- //TODO: handleRuimRefresh((int[])(ar.result));
+ handleRuimRefresh((int[])(ar.result));
}
break;
}}catch (RuntimeException exc) {
// I don't want these exceptions to be fatal
- Log.w(LOG_TAG, "Exception parsing SIM record", exc);
- } finally {
+ Log.w(LOG_TAG, "Exception parsing RUIM record", exc);
+ } finally {
// Count up record load responses even if they are fails
if (isRecordLoadResponse) {
- //TODO: onRecordLoaded();
+ onRecordLoaded();
}
}
- }
+ }
protected void onRecordLoaded() {
// One record loaded successfully or failed, In either case
@@ -395,93 +285,91 @@ public final class RuimRecords extends IccRecords {
recordsToLoad = 0;
}
}
-
+
protected void onAllRecordsLoaded() {
- // TODO: implementation is missing
+ Log.d(LOG_TAG, "RuimRecords: record load complete");
+
+ // Further records that can be inserted are Operator/OEM dependent
+
+ recordsLoadedRegistrants.notifyRegistrants(
+ new AsyncResult(null, null, null));
+ ((CDMAPhone) phone).mRuimCard.broadcastRuimStateChangedIntent(
+ 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
*/
-
- // TODO: broadcastSimStateChangedIntent will probably be renamed
- phone.mRuimCard.broadcastSimStateChangedIntent(
+
+ ((CDMAPhone) phone).mRuimCard.broadcastRuimStateChangedIntent(
RuimCard.INTENT_VALUE_ICC_READY, null);
fetchRuimRecords();
-
- // TODO: add a function here
+
phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
-
+
}
-
+
private void fetchRuimRecords() {
recordsRequested = true;
Log.v(LOG_TAG, "RuimRecords:fetchRuimRecords " + recordsToLoad);
-
- // TODO: IMSI needed to get mcc and mnc
-// phone.mCM.getIMSI(obtainMessage(EVENT_GET_IMSI_DONE));
-// recordsToLoad++;
- ((RuimFileHandler)phone.getIccFileHandler()).loadEFTransparent(EF_ICCID,
- obtainMessage(EVENT_GET_ICCID_DONE));
+ phone.getIccFileHandler().loadEFTransparent(EF_ICCID,
+ obtainMessage(EVENT_GET_ICCID_DONE));
recordsToLoad++;
- // TODO: IMSI_M(MIN)/MDN, RIL_REQUEST_DEVICE_IDENTITY
- // FIXME should examine EF[MSISDN]'s capability configuration
- // to determine which is the voice/data/fax line
-// new AdnRecordLoader(phone).loadFromEF(EF_MSISDN, EF_EXT1, 1,
-// obtainMessage(EVENT_GET_MSISDN_DONE));
-// recordsToLoad++;
-
- // TODO: probably done by RIL_REQUEST_DEVICE_IDENTITY
-// phone.mSIMFileHandler.loadEFTransparent(EF_AD,
-// obtainMessage(EVENT_GET_AD_DONE));
-// recordsToLoad++;
-
- // TODO: check if if CDMA Service Table 0x6F32 should be read instead
-// phone.mSIMFileHandler.loadEFTransparent(EF_SST,
-// obtainMessage(EVENT_GET_SST_DONE));
-// recordsToLoad++;
-
- // TODO: SMS handling in CDMA
- // XXX should seek instead of examining them all
-// if (false) { // XXX
-// phone.mSIMFileHandler.loadEFLinearFixedAll(EF_SMS,
-// obtainMessage(EVENT_GET_ALL_SMS_DONE));
-// recordsToLoad++;
-// }
-
- // TODO: check later in SMS use case
-// if (CRASH_RIL) {
-// String sms = "0107912160130310f20404d0110041007030208054832b0120ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
-// byte[] ba = IccUtils.hexStringToBytes(sms);
-//
-// phone.mSIMFileHandler.updateEFLinearFixed(EF_SMS, 1, ba, null,
-// obtainMessage(EVENT_MARK_SMS_READ_DONE, 1));
-// }
+ // Further records that can be inserted are Operator/OEM dependent
}
-
- private void log(String s) {
- Log.d(LOG_TAG, "[RuimRecords] " + s);
- }
-
@Override
protected int getDisplayRule(String plmn) {
- // TODO Auto-generated method stub
+ // TODO together with spn
return 0;
}
@Override
public void setVoiceMessageWaiting(int line, int countWaiting) {
- // TODO Auto-generated method stub
-
+ Log.i(LOG_TAG, "RuimRecords: setVoiceMessageWaiting not supported.");
+ }
+
+ private void handleRuimRefresh(int[] result) {
+ if (result == null || result.length == 0) {
+ return;
+ }
+
+ switch ((result[0])) {
+ case CommandsInterface.SIM_REFRESH_FILE_UPDATED:
+ adnCache.reset();
+ fetchRuimRecords();
+ break;
+ case CommandsInterface.SIM_REFRESH_INIT:
+ // need to reload all files (that we care about)
+ fetchRuimRecords();
+ break;
+ case CommandsInterface.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),
+ * ServiceStateTracker will call setRadioPower when it receives the
+ * RADIO_STATE_CHANGED notification for the power off. And if the
+ * desired power state has changed in the interim, we don't want to
+ * override it with an unconditional power on.
+ */
+ break;
+ default:
+ // unknown refresh operation
+ break;
+ }
}
+
+ protected void log(String s) {
+ Log.d(LOG_TAG, "[RuimRecords] " + s);
+ }
+
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
index 2be41edd2b67..9439359fe735 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,31 +17,31 @@
package com.android.internal.telephony.cdma;
-import android.app.PendingIntent;
import android.content.Context;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
-import android.os.ServiceManager;
-import android.telephony.gsm.SmsManager;
import android.util.Log;
+import com.android.internal.telephony.IccConstants;
+import com.android.internal.telephony.IccSmsInterfaceManager;
+import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.PhoneProxy;
+import com.android.internal.telephony.SmsRawData;
+
import java.util.ArrayList;
import java.util.List;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.gsm.SmsRawData; //TODO remove after moving to telephony
+import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
/**
- * SimSmsInterfaceManager to provide an inter-process communication to
- * access Sms in Sim.
+ * RuimSmsInterfaceManager to provide an inter-process communication to
+ * access Sms in Ruim.
*/
public class RuimSmsInterfaceManager extends IccSmsInterfaceManager {
static final String LOG_TAG = "CDMA";
- static final boolean DBG = false;
+ static final boolean DBG = true;
- private CDMAPhone mPhone;
private final Object mLock = new Object();
private boolean mSuccess;
private List<SmsRawData> mSms;
@@ -56,7 +56,6 @@ public class RuimSmsInterfaceManager extends IccSmsInterfaceManager {
switch (msg.what) {
case EVENT_UPDATE_DONE:
- Log.d(LOG_TAG, "Event EVENT_UPDATE_DONE Received"); //TODO
ar = (AsyncResult) msg.obj;
synchronized (mLock) {
mSuccess = (ar.exception == null);
@@ -64,7 +63,6 @@ public class RuimSmsInterfaceManager extends IccSmsInterfaceManager {
}
break;
case EVENT_LOAD_DONE:
- Log.d(LOG_TAG, "Event EVENT_LOAD_DONE Received"); //TODO
ar = (AsyncResult)msg.obj;
synchronized (mLock) {
if (ar.exception == null) {
@@ -83,79 +81,112 @@ public class RuimSmsInterfaceManager extends IccSmsInterfaceManager {
};
public RuimSmsInterfaceManager(CDMAPhone phone) {
- this.mPhone = phone;
- //ServiceManager.addService("isms", this);
+ super(phone);
+ mDispatcher = new CdmaSMSDispatcher(phone);
}
- private void enforceReceiveAndSend(String message) {
- Context context = mPhone.getContext();
+ public void dispose() {
+ }
- context.enforceCallingPermission(
- "android.permission.RECEIVE_SMS", message);
- context.enforceCallingPermission(
- "android.permission.SEND_SMS", message);
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "RuimSmsInterfaceManager finalized");
}
/**
* Update the specified message on the RUIM.
+ *
+ * @param index record index of message to update
+ * @param status new message status (STATUS_ON_ICC_READ,
+ * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
+ * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
+ * @param pdu the raw PDU to store
+ * @return success or not
+ *
*/
public boolean
- updateMessageOnSimEf(int index, int status, byte[] pdu) {
- //TODO
- mSuccess = false;
+ updateMessageOnIccEf(int index, int status, byte[] pdu) {
+ if (DBG) log("updateMessageOnIccEf: index=" + index +
+ " status=" + status + " ==> " +
+ "("+ pdu + ")");
+ enforceReceiveAndSend("Updating message on RUIM");
+ synchronized(mLock) {
+ mSuccess = false;
+ Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
+
+ if (status == STATUS_ON_ICC_FREE) {
+ // Special case FREE: call deleteSmsOnRuim instead of
+ // manipulating the RUIM record
+ mPhone.mCM.deleteSmsOnRuim(index, response);
+ } else {
+ byte[] record = makeSmsRecordData(status, pdu);
+ mPhone.getIccFileHandler().updateEFLinearFixed(
+ IccConstants.EF_SMS, index, record, null, response);
+ }
+ try {
+ mLock.wait();
+ } catch (InterruptedException e) {
+ log("interrupted while trying to update by index");
+ }
+ }
return mSuccess;
}
/**
* Copy a raw SMS PDU to the RUIM.
+ *
+ * @param pdu the raw PDU to store
+ * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
+ * STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
+ * @return success or not
+ *
*/
- public boolean copyMessageToSimEf(int status, byte[] pdu, byte[] smsc) {
- //TODO
- mSuccess = false;
+ public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
+ //NOTE smsc not used in RUIM
+ if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
+ "pdu=("+ pdu + ")");
+ enforceReceiveAndSend("Copying message to RUIM");
+ synchronized(mLock) {
+ mSuccess = false;
+ Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
+
+ mPhone.mCM.writeSmsToRuim(status, IccUtils.bytesToHexString(pdu),
+ response);
+
+ try {
+ mLock.wait();
+ } catch (InterruptedException e) {
+ log("interrupted while trying to update by index");
+ }
+ }
return mSuccess;
}
/**
* Retrieves all messages currently stored on RUIM.
*/
- public List<SmsRawData> getAllMessagesFromSimEf() {
- //TODO
- return null;
- }
+ public List<SmsRawData> getAllMessagesFromIccEf() {
+ if (DBG) log("getAllMessagesFromEF");
- /**
- * Send a Raw PDU SMS
- */
- public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent) {
- //TODO
- }
-
- /**
- * Send a multi-part text based SMS.
- */
- public void sendMultipartText(String destinationAddress, String scAddress, List<String> parts,
- List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
- //TODO
- }
-
- /**
- * Generates an EF_SMS record from status and raw PDU.
- */
- private byte[] makeSmsRecordData(int status, byte[] pdu) {
- //TODO
- return null;
- }
+ Context context = mPhone.getContext();
- /**
- * create SmsRawData lists from all sms record byte[]
- */
- private ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) {
- //TODO
- return null;
+ context.enforceCallingPermission(
+ "android.permission.RECEIVE_SMS",
+ "Reading messages from RUIM");
+ synchronized(mLock) {
+ Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
+ mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response);
+
+ try {
+ mLock.wait();
+ } catch (InterruptedException e) {
+ log("interrupted while trying to load from the RUIM");
+ }
+ }
+ return mSms;
}
- private void log(String msg) {
+ protected void log(String msg) {
Log.d(LOG_TAG, "[RuimSmsInterfaceManager] " + msg);
}
}
+
diff --git a/telephony/java/com/android/internal/telephony/cdma/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/SMSDispatcher.java
deleted file mode 100644
index 21546d89ddfd..000000000000
--- a/telephony/java/com/android/internal/telephony/cdma/SMSDispatcher.java
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.AlertDialog;
-import android.app.PendingIntent.CanceledException;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.DialogInterface;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Telephony;
-import android.provider.Telephony.Sms.Intents;
-import android.telephony.gsm.SmsMessage;
-import android.telephony.gsm.SmsManager;
-import android.telephony.ServiceState;
-import android.util.Config;
-
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.util.HexDump;
-import android.util.Log;
-import android.view.WindowManager;
-
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Random;
-
-import com.android.internal.R;
-
-final class SMSDispatcher extends Handler {
- private static final String TAG = "CDMA";
-
- /** Default checking period for SMS sent without uesr permit */
- private static final int DEFAULT_SMS_CHECK_PERIOD = 3600000;
-
- /** Default number of SMS sent in checking period without uesr permit */
- private static final int DEFAULT_SMS_MAX_ALLOWED = 100;
-
- /** Default timeout for SMS sent query */
- private static final int DEFAULT_SMS_TIMOUEOUT = 6000;
-
- private static final String MMS_MIME_TYPE = "application/vnd.wap.mms-message";
-
- private static final String[] RAW_PROJECTION = new String[] {
- "pdu",
- "sequence",
- };
-
-//TODO static final int MAIL_SEND_SMS = 1;
-
- static final int EVENT_NEW_SMS = 1;
-
- static final int EVENT_SEND_SMS_COMPLETE = 2;
-
- /** Retry sending a previously failed SMS message */
- static final int EVENT_SEND_RETRY = 3;
-
- /** Status report received */
- static final int EVENT_NEW_SMS_STATUS_REPORT = 5;
-
- /** SIM storage is full */
- static final int EVENT_RUIM_FULL = 6;
-
- /** SMS confirm required */
- static final int EVENT_POST_ALERT = 7;
-
- /** Send the user confirmed SMS */
- static final int EVENT_SEND_CONFIRMED_SMS = 8;
-
- /** Alert is timeout */
- static final int EVENT_ALERT_TIMEOUT = 9;
-
- private final CDMAPhone mPhone;
-
- private final Context mContext;
-
- private final ContentResolver mResolver;
-
- private final CommandsInterface mCm;
-
- private final Uri mRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw");
-
- /** 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; // ms
-
- /**
- * Message reference for a CONCATENATED_8_BIT_REFERENCE or
- * CONCATENATED_16_BIT_REFERENCE message set. Should be
- * incremented for each set of concatenated messages.
- */
- private static int sConcatenatedRef;
-
- private SmsCounter mCounter;
-
- private SmsTracker mSTracker;
-
- /**
- * Implement the per-application based SMS control, which only allows
- * a limit on the number of SMS/MMS messages an app can send in checking
- * period.
- */
- private class SmsCounter {
- private int mCheckPeriod;
- private int mMaxAllowed;
- private HashMap<String, ArrayList<Long>> mSmsStamp;
-
- /**
- * Create SmsCounter
- * @param mMax is the number of SMS allowed without user permit
- * @param mPeriod is the checking period
- */
- SmsCounter(int mMax, int mPeriod) {
- mMaxAllowed = mMax;
- mCheckPeriod = mPeriod;
- mSmsStamp = new HashMap<String, ArrayList<Long>> ();
- }
-
- boolean check(String appName) {
- if (!mSmsStamp.containsKey(appName)) {
- mSmsStamp.put(appName, new ArrayList<Long>());
- }
-
- return isUnderLimit(mSmsStamp.get(appName));
- }
-
- private boolean isUnderLimit(ArrayList<Long> sent) {
- Long ct = System.currentTimeMillis();
-
- Log.d(TAG, "SMS send size=" + sent.size() + "time=" + ct);
-
- while (sent.size() > 0 && (ct - sent.get(0)) > mCheckPeriod ) {
- sent.remove(0);
- }
-
- if (sent.size() < mMaxAllowed) {
- sent.add(ct);
- return true;
- }
- return false;
- }
- }
-
- SMSDispatcher(CDMAPhone phone) {
- mPhone = phone;
- mContext = phone.getContext();
- mResolver = mContext.getContentResolver();
- mCm = phone.mCM;
- mSTracker = null;
- mCounter = new SmsCounter(DEFAULT_SMS_MAX_ALLOWED,
- DEFAULT_SMS_CHECK_PERIOD);
-
- //mCm.setOnNewSMS(this, EVENT_NEW_SMS, null);
- //mCm.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null);
- //mCm.setOnSimSmsFull(this, EVENT_SIM_FULL, null);
- //TODO CommandsInterface method for setOnRuimSmsFull
-
- // Don't always start message ref at 0.
- sConcatenatedRef = new Random().nextInt(256);
- }
-
- /* TODO: Need to figure out how to keep track of status report routing in a
- * persistent manner. If the phone process restarts (reboot or crash),
- * we will lose this list and any status reports that come in after
- * will be dropped.
- */
- /** Sent messages awaiting a delivery status report. */
- private final ArrayList<SmsTracker> deliveryPendingList = new ArrayList<SmsTracker>();
-
- /**
- * Handles events coming from the phone stack. Overridden from handler.
- *
- * @param msg the message to handle
- */
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case EVENT_NEW_SMS:
- // A new SMS has been received by the device
-// if (Config.LOGD) {
- Log.d(TAG, "New SMS Message Received"); //TODO
-// }
-
-/* SmsMessage sms;
-
- ar = (AsyncResult) msg.obj;
-
- // FIXME unit test leaves cm == null. this should change
- if (mCm != null) {
- // FIXME only acknowledge on store
- mCm.acknowledgeLastIncomingSMS(true, null);
- }
-
- if (ar.exception != null) {
- Log.e(TAG, "Exception processing incoming SMS",
- ar.exception);
- return;
- }
-
- sms = (SmsMessage) ar.result;
- dispatchMessage(sms); */
-
- break;
-
- case EVENT_SEND_SMS_COMPLETE:
- // An outbound SMS has been sucessfully transferred, or failed.
-// handleSendComplete((AsyncResult) msg.obj);
- Log.d(TAG, "Event EVENT_SEND_SMS_COMPLETE Received"); //TODO
- break;
-
- case EVENT_SEND_RETRY:
-// sendSms((SmsTracker) msg.obj);
- Log.d(TAG, "Event EVENT_SEND_RETRY Received"); //TODO
- break;
-
- case EVENT_NEW_SMS_STATUS_REPORT:
-// handleStatusReport((AsyncResult)msg.obj);
- Log.d(TAG, "Event EVENT_NEW_SMS_STATUS_REPORT Received"); //TODO
- break;
-
- case EVENT_RUIM_FULL:
-// handleSimFull();
- Log.d(TAG, "Event EVENT_SIM_FULL Received"); //TODO
- break;
-
- case EVENT_POST_ALERT:
-// handleReachSentLimit((SmsTracker)(msg.obj));
- Log.d(TAG, "Event EVENT_POST_ALERT Received"); //TODO
- break;
-
- case EVENT_ALERT_TIMEOUT:
-/* ((AlertDialog)(msg.obj)).dismiss();
- msg.obj = null;
- mSTracker = null; */
- Log.d(TAG, "Event EVENT_ALERT_TIMEOUT Received"); //TODO
- break;
-
- case EVENT_SEND_CONFIRMED_SMS:
-/* if (mSTracker!=null) {
- Log.d(TAG, "Ready to send SMS again.");
- sendSms(mSTracker);
- mSTracker = null;
- } */
- Log.d(TAG, "Event EVENT_SEND_CONFIRMED_SMS Received"); //TODO
- break;
- }
- }
-
- /**
- * Called when SIM_FULL message is received from the RIL. Notifies interested
- * parties that SIM storage for SMS messages is full.
- */
- private void handleSimFull() {
- //TODO
-// // broadcast SIM_FULL intent
-// Intent intent = new Intent(Intents.SIM_FULL_ACTION);
-// mPhone.getContext().sendBroadcast(intent, "android.permission.RECEIVE_SMS");
- }
-
- /**
- * Called when a status report is received. This should correspond to
- * a previously successful SEND.
- *
- * @param ar AsyncResult passed into the message handler. ar.result should
- * be a String representing the status report PDU, as ASCII hex.
- */
- private void handleStatusReport(AsyncResult ar) {
- //TODO
-/* String pduString = (String) ar.result;
- SmsMessage sms = SmsMessage.newFromCDS(pduString);
-
- if (sms != null) {
- int messageRef = sms.messageRef;
- for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
- SmsTracker tracker = deliveryPendingList.get(i);
- if (tracker.mMessageRef == messageRef) {
- // Found it. Remove from list and broadcast.
- deliveryPendingList.remove(i);
- PendingIntent intent = tracker.mDeliveryIntent;
- Intent fillIn = new Intent();
- fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
- try {
- intent.send(mContext, Activity.RESULT_OK, fillIn);
- } catch (CanceledException ex) {}
-
- // Only expect to see one tracker matching this messageref
- break;
- }
- }
- }
-
- if (mCm != null) {
- mCm.acknowledgeLastIncomingSMS(true, null);
- } */
- }
-
- /**
- * Called when SMS send completes. Broadcasts a sentIntent on success.
- * On failure, either sets up retries or broadcasts a sentIntent with
- * the failure in the result code.
- *
- * @param ar AsyncResult passed into the message handler. ar.result should
- * an SmsResponse instance if send was successful. ar.userObj
- * should be an SmsTracker instance.
- */
- private void handleSendComplete(AsyncResult ar) {
- //TODO
-/* SmsTracker tracker = (SmsTracker) ar.userObj;
- PendingIntent sentIntent = tracker.mSentIntent;
-
- if (ar.exception == null) {
- if (Config.LOGD) {
- Log.d(TAG, "SMS send complete. Broadcasting "
- + "intent: " + sentIntent);
- }
-
- if (tracker.mDeliveryIntent != null) {
- // Expecting a status report. Add it to the list.
- int messageRef = ((SmsResponse)ar.result).messageRef;
- tracker.mMessageRef = messageRef;
- deliveryPendingList.add(tracker);
- }
-
- if (sentIntent != null) {
- try {
- sentIntent.send(Activity.RESULT_OK);
- } catch (CanceledException ex) {}
- }
- } else {
- if (Config.LOGD) {
- Log.d(TAG, "SMS send failed");
- }
-
- int ss = mPhone.getServiceState().getState();
-
- if (ss != ServiceState.STATE_IN_SERVICE) {
- handleNotInService(ss, tracker);
- } else if ((((CommandException)(ar.exception)).getCommandError()
- == CommandException.Error.SMS_FAIL_RETRY) &&
- tracker.mRetryCount < MAX_SEND_RETRIES) {
- // Retry after a delay if needed.
- // TODO: According to TS 23.040, 9.2.3.6, we should resend
- // with the same TP-MR as the failed message, and
- // TP-RD set to 1. However, we don't have a means of
- // knowing the MR for the failed message (EF_SMSstatus
- // may or may not have the MR corresponding to this
- // message, depending on the failure). Also, in some
- // implementations this retry is handled by the baseband.
- tracker.mRetryCount++;
- Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker);
- sendMessageDelayed(retryMsg, SEND_RETRY_DELAY);
- } else if (tracker.mSentIntent != null) {
- // Done retrying; return an error to the app.
- try {
- tracker.mSentIntent.send(SmsManager.RESULT_ERROR_GENERIC_FAILURE);
- } catch (CanceledException ex) {}
- }
- } */
- }
-
- /**
- * Handles outbound message when the phone is not in service.
- *
- * @param ss Current service state. Valid values are:
- * OUT_OF_SERVICE
- * EMERGENCY_ONLY
- * POWER_OFF
- * @param tracker An SmsTracker for the current message.
- */
- private void handleNotInService(int ss, SmsTracker tracker) {
- //TODO
-/* if (tracker.mSentIntent != null) {
- try {
- if (ss == ServiceState.STATE_POWER_OFF) {
- tracker.mSentIntent.send(SmsManager.RESULT_ERROR_RADIO_OFF);
- } else {
- tracker.mSentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE);
- }
- } catch (CanceledException ex) {}
- } */
- }
-
- /**
- * Dispatches an incoming SMS messages.
- *
- * @param sms the incoming message from the phone
- */
- /* package */ void dispatchMessage(SmsMessage sms) {
- //TODO
-/* boolean handled = false;
-
- // Special case the message waiting indicator messages
- if (sms.isMWISetMessage()) {
- 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()) {
- mPhone.updateMessageWaitingIndicator(false);
-
- if (sms.isMwiDontStore()) {
- handled = true;
- }
-
- if (Config.LOGD) {
- Log.d(TAG,
- "Received voice mail indicator clear SMS shouldStore="
- + !handled);
- }
- }
-
- if (handled) {
- return;
- }
-
- // 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()) {
- 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;
-
- 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;
-
- break;
- }
-
- case SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT: {
- byte[] data = element.getData();
-
- destPort = (data[0] & 0xff) << 8;
- destPort |= (data[1] & 0xff);
-
- break;
- }
- }
- }
- }
-
- if (referenceNumber == -1) {
- // notify everyone of the message if it isn't partial
- byte[][] pdus = new byte[1][];
- pdus[0] = sms.getPdu();
-
- if (destPort != -1) {
- if (destPort == SmsHeader.PORT_WAP_PUSH) {
- dispatchWapPdu(sms.getUserData());
- }
- // The message was sent to a port, so concoct a URI for it
- dispatchPortAddressedPdus(pdus, destPort);
- } else {
- // It's a normal message, dispatch it
- dispatchPdus(pdus);
- }
- } else {
- // Process the message part
- processMessagePart(sms, referenceNumber, sequence, count, destPort);
- } */
- }
-
- /**
- * If this is the last part send the parts out to the application, otherwise
- * the part is stored for later processing.
- */
- private void processMessagePart(SmsMessage sms, int referenceNumber,
- int sequence, int count, int destinationPort) {
- //TODO
-/* // Lookup all other related parts
- StringBuilder where = new StringBuilder("reference_number =");
- where.append(referenceNumber);
- where.append(" AND address = ?");
- String[] whereArgs = new String[] {sms.getOriginatingAddress()};
-
- byte[][] pdus = null;
- Cursor cursor = null;
- try {
- cursor = mResolver.query(mRawUri, RAW_PROJECTION, where.toString(), whereArgs, null);
- int cursorCount = cursor.getCount();
- if (cursorCount != count - 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);
- }
- mResolver.insert(mRawUri, values);
-
- return;
- }
-
- // All the parts are in place, deal with them
- int pduColumn = cursor.getColumnIndex("pdu");
- int sequenceColumn = cursor.getColumnIndex("sequence");
-
- pdus = new byte[count][];
- for (int i = 0; i < cursorCount; i++) {
- cursor.moveToNext();
- int cursorSequence = (int)cursor.getLong(sequenceColumn);
- pdus[cursorSequence - 1] = HexDump.hexStringToByteArray(
- cursor.getString(pduColumn));
- }
- // This one isn't in the DB, so add it
- pdus[sequence - 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.
- } finally {
- if (cursor != null) cursor.close();
- }
-
- // 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);
- }
-
- // Handle the PUSH
- dispatchWapPdu(output.toByteArray());
- break;
- }
-
- case -1:
- // 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;
- } */
- }
-
- /**
- * Dispatches standard PDUs to interested applications
- *
- * @param pdus The raw PDUs making up the message
- */
- private void dispatchPdus(byte[][] pdus) {
- //TODO
-/* Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);
- intent.putExtra("pdus", pdus);
- mPhone.getContext().sendBroadcast(
- intent, "android.permission.RECEIVE_SMS"); */
- }
-
- /**
- * Dispatches port addressed PDUs to interested applications
- *
- * @param pdus The raw PDUs making up the message
- * @param port The destination port of the messages
- */
- private void dispatchPortAddressedPdus(byte[][] pdus, int port) {
- //TODO
-/* 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"); */
- }
-
- /**
- * Dispatches inbound messages that are in the WAP PDU format. See
- * 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
- */
- private void dispatchWapPdu(byte[] pdu) {
- //TODO
- }
-
- /**
- * Send a multi-part text based SMS.
- *
- * @param destinationAddress the address to send the message to
- * @param scAddress is the service center address or null to use
- * the current default SMSC
- * @param parts an <code>ArrayList</code> of strings that, in order,
- * comprise the original message
- * @param sentIntents if not null, an <code>ArrayList</code> of
- * <code>PendingIntent</code>s (one for each message part) that is
- * broadcast when the corresponding message part has been sent.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:
- * <code>RESULT_ERROR_GENERIC_FAILURE</code>
- * <code>RESULT_ERROR_RADIO_OFF</code>
- * <code>RESULT_ERROR_NULL_PDU</code>.
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applicaitons,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntents if not null, an <code>ArrayList</code> of
- * <code>PendingIntent</code>s (one for each message part) that is
- * broadcast when the corresponding message part has been delivered
- * to the recipient. The raw pdu of the status report is in the
- * extended data ("pdu").
- */
- void sendMultipartText(String destinationAddress, String scAddress, ArrayList<String> parts,
- ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
- //TODO
-/*
- 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;
-
- if (sentIntents != null && sentIntents.size() > i) {
- sentIntent = sentIntents.get(i);
- }
- if (deliveryIntents != null && deliveryIntents.size() > i) {
- deliveryIntent = deliveryIntents.get(i);
- }
-
- SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
- parts.get(i), deliveryIntent != null, header.toByteArray());
-
- sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
- } */
- }
-
- /**
- * Send a SMS
- *
- * @param smsc the SMSC to send the message through, or NULL for the
- * defatult SMSC
- * @param pdu the raw PDU to send
- * @param sentIntent if not NULL this <code>Intent</code> is
- * broadcast when the message is sucessfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:
- * <code>RESULT_ERROR_GENERIC_FAILURE</code>
- * <code>RESULT_ERROR_RADIO_OFF</code>
- * <code>RESULT_ERROR_NULL_PDU</code>.
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applicaitons,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>Intent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- */
- void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent) {
- //TODO
-/* if (pdu == null) {
- if (sentIntent != null) {
- try {
- sentIntent.send(SmsManager.RESULT_ERROR_NULL_PDU);
- } catch (CanceledException ex) {}
- }
- return;
- }
-
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put("smsc", smsc);
- map.put("pdu", pdu);
-
- SmsTracker tracker = new SmsTracker(map, sentIntent,
- deliveryIntent);
- int ss = mPhone.getServiceState().getState();
-
- if (ss != ServiceState.STATE_IN_SERVICE) {
- handleNotInService(ss, tracker);
- } else {
- String appName = getAppNameByIntent(sentIntent);
- if (mCounter.check(appName)) {
- sendSms(tracker);
- } else {
- sendMessage(obtainMessage(EVENT_POST_ALERT, tracker));
- }
- } */
- }
-
- /**
- * Post an alert while SMS needs user confirm.
- *
- * An SmsTracker for the current message.
- */
- private void handleReachSentLimit(SmsTracker tracker) {
- //TODO
-/*
- Resources r = Resources.getSystem();
-
- String appName = getAppNameByIntent(tracker.mSentIntent);
-
- AlertDialog d = new AlertDialog.Builder(mContext)
- .setTitle(r.getString(R.string.sms_control_title))
- .setMessage(appName + " " + r.getString(R.string.sms_control_message))
- .setPositiveButton(r.getString(R.string.sms_control_yes), mListener)
- .setNegativeButton(r.getString(R.string.sms_control_no), null)
- .create();
-
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- d.show();
-
- mSTracker = tracker;
- sendMessageDelayed ( obtainMessage(EVENT_ALERT_TIMEOUT, d),
- DEFAULT_SMS_TIMOUEOUT); */
- }
-
- private String getAppNameByIntent(PendingIntent intent) {
- //TODO
-/* Resources r = Resources.getSystem();
- return (intent != null) ? intent.getTargetPackage()
- : r.getString(R.string.sms_control_default_app_name); */
- String ret = "to be implemented";
- return ret;
- }
-
- /**
- * Send the message along to the radio.
- *
- * @param tracker holds the SMS message to send
- */
- private void sendSms(SmsTracker tracker) {
- //TODO
-/* HashMap map = tracker.mData;
-
- byte smsc[] = (byte[]) map.get("smsc");
- byte pdu[] = (byte[]) map.get("pdu");
-
- Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
- mCm.sendSMS(IccUtils.bytesToHexString(smsc),
- IccUtils.bytesToHexString(pdu), reply); */
- }
-
- /**
- * Keeps track of an SMS that has been sent to the RIL, until it it has
- * successfully been sent, or we're done trying.
- *
- */
- static class SmsTracker {
- //TODO
- HashMap mData;
- int mRetryCount;
- int mMessageRef;
-
- PendingIntent mSentIntent;
- PendingIntent mDeliveryIntent;
-
- SmsTracker(HashMap data, PendingIntent sentIntent,
- PendingIntent deliveryIntent) {
- mData = data;
- mSentIntent = sentIntent;
- mDeliveryIntent = deliveryIntent;
- mRetryCount = 0;
- }
-
- }
-
- private DialogInterface.OnClickListener mListener =
- new DialogInterface.OnClickListener() {
-
- public void onClick(DialogInterface dialog, int which) {
- if (which == DialogInterface.BUTTON1) {
- Log.d(TAG, "click YES to send out sms");
- //sendMessage(obtainMessage(EVENT_SEND_CONFIRMED_SMS)); //TODO
- }
- }
- };
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
new file mode 100644
index 000000000000..921b6633c6d3
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -0,0 +1,905 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma;
+
+import android.pim.Time;
+import android.os.Parcel;
+import android.util.Config;
+import android.util.Log;
+import com.android.internal.telephony.EncodeException;
+import com.android.internal.telephony.GsmAlphabet;
+import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.SmsHeader;
+import com.android.internal.telephony.SmsMessageBase;
+import com.android.internal.telephony.cdma.sms.BearerData;
+import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
+import com.android.internal.telephony.cdma.sms.SmsDataCoding;
+import com.android.internal.telephony.cdma.sms.SmsEnvelope;
+import com.android.internal.telephony.cdma.sms.UserData;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Random;
+
+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;
+import static android.telephony.SmsMessage.MessageClass;
+import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_NONE;
+import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_TEMPORARY;
+import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_PERMANENT;
+import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_DELIVER;
+import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_SUBMIT;
+import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_CANCELLATION;
+import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_DELIVERY_ACK;
+import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_USER_ACK;
+import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_READ_ACK;
+import static com.android.internal.telephony.cdma.sms.CdmaSmsAddress.SMS_ADDRESS_MAX;
+import static com.android.internal.telephony.cdma.sms.CdmaSmsAddress.SMS_SUBADDRESS_MAX;
+import static com.android.internal.telephony.cdma.sms.SmsEnvelope.SMS_BEARER_DATA_MAX;
+import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_7BIT_ASCII;
+import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_GSM_7BIT_ALPHABET;
+import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_IA5;
+import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_OCTET;
+import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_UNICODE_16;
+
+/**
+ * A Short Message Service message.
+ *
+ */
+public class SmsMessage extends SmsMessageBase {
+ static final String LOG_TAG = "CDMA";
+
+ /**
+ * Status of a previously submitted SMS.
+ * This field applies to SMS Delivery Acknowledge messages. 0 indicates success;
+ * Here, the error class is defined by the bits from 9-8, the status code by the bits from 7-0.
+ * See C.S0015-B, v2.0, 4.5.21 for a detailed description of possible values.
+ */
+ private int status;
+
+ /** The next message ID for the BearerData. Shall be a random value on first use.
+ * (See C.S0015-B, v2.0, 4.3.1.5)
+ */
+ private static int nextMessageId = 0;
+
+ /** Specifies if this is the first SMS message submit */
+ private static boolean firstSMS = true;
+
+ /** Specifies if a return of an acknowledgment is requested for send SMS */
+ private static final int RETURN_NO_ACK = 0;
+ private static final int RETURN_ACK = 1;
+
+ private SmsEnvelope mEnvelope;
+ private BearerData mBearerData;
+
+ public static class SubmitPdu extends SubmitPduBase {
+ }
+
+ /**
+ * Create an SmsMessage from a raw PDU.
+ * Note: In CDMA the PDU is just a byte representation of the received Sms.
+ */
+ public static SmsMessage createFromPdu(byte[] pdu) {
+ SmsMessage msg = new SmsMessage();
+
+ try {
+ msg.parsePdu(pdu);
+ return msg;
+ } catch (RuntimeException ex) {
+ Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
+ return null;
+ }
+ }
+
+ /**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+ public static SmsMessage newFromCMT(String[] lines) {
+ Log.w(LOG_TAG, "newFromCMT: is not supported in CDMA mode.");
+ return null;
+ }
+
+ /**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+ public static SmsMessage newFromCMTI(String line) {
+ Log.w(LOG_TAG, "newFromCMTI: is not supported in CDMA mode.");
+ return null;
+ }
+
+ /**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+ public static SmsMessage newFromCDS(String line) {
+ Log.w(LOG_TAG, "newFromCDS: is not supported in CDMA mode.");
+ return null;
+ }
+
+ /**
+ * Create a "raw" CDMA SmsMessage from a Parcel that was forged in ril.cpp.
+ * Note: Only primitive fields are set.
+ */
+ public static SmsMessage newFromParcel(Parcel p) {
+ // Note: Parcel.readByte actually reads one Int and masks to byte
+ SmsMessage msg = new SmsMessage();
+ SmsEnvelope env = new SmsEnvelope();
+ CdmaSmsAddress addr = new CdmaSmsAddress();
+ byte[] data;
+ byte count;
+ int countInt;
+
+ //currently not supported by the modem-lib: env.mMessageType
+ env.teleService = p.readInt(); //p_cur->uTeleserviceID
+
+ if (0 != p.readByte()) { //p_cur->bIsServicePresent
+ env.messageType = SmsEnvelope.MESSAGE_TYPE_BROADCAST;
+ }
+ else {
+ if (SmsEnvelope.TELESERVICE_NOT_SET == env.teleService) {
+ // assume type ACK
+ env.messageType = SmsEnvelope.MESSAGE_TYPE_ACKNOWLEDGE;
+ } else {
+ env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
+ }
+ }
+ env.serviceCategory = p.readInt(); //p_cur->uServicecategory
+
+ // address
+ addr.digitMode = (byte) (0xFF & p.readInt()); //p_cur->sAddress.digit_mode
+ addr.numberMode = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_mode
+ addr.ton = p.readInt(); //p_cur->sAddress.number_type
+ addr.numberPlan = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_plan
+ count = p.readByte(); //p_cur->sAddress.number_of_digits
+ addr.numberOfDigits = count;
+ data = new byte[count];
+ //p_cur->sAddress.digits[digitCount]
+ for (int index=0; index < count; index++) {
+ data[index] = p.readByte();
+ }
+ addr.origBytes = data;
+
+ // ignore subaddress
+ p.readInt(); //p_cur->sSubAddress.subaddressType
+ p.readInt(); //p_cur->sSubAddress.odd
+ count = p.readByte(); //p_cur->sSubAddress.number_of_digits
+ //p_cur->sSubAddress.digits[digitCount] :
+ for (int index=0; index < count; index++) {
+ p.readByte();
+ }
+
+ /* currently not supported by the modem-lib:
+ env.bearerReply
+ env.replySeqNo
+ env.errorClass
+ env.causeCode
+ */
+
+ // bearer data
+ countInt = p.readInt(); //p_cur->uBearerDataLen
+ if (countInt >0) {
+ data = new byte[countInt];
+ //p_cur->aBearerData[digitCount] :
+ for (int index=0; index < countInt; index++) {
+ data[index] = p.readByte();
+ }
+ env.bearerData = data;
+ // BD gets further decoded when accessed in SMSDispatcher
+ }
+
+ // link the the filled objects to the SMS
+ env.origAddress = addr;
+ msg.originatingAddress = addr;
+ msg.mEnvelope = env;
+
+ // create byte stream representation for transportation through the layers.
+ msg.createPdu();
+
+ return msg;
+ }
+
+ /**
+ * Create an SmsMessage from an SMS EF record.
+ *
+ * @param index Index of SMS record. This should be index in ArrayList
+ * returned by RuimSmsInterfaceManager.getAllMessagesFromIcc + 1.
+ * @param data Record data.
+ * @return An SmsMessage representing the record.
+ *
+ * @hide
+ */
+ public static SmsMessage createFromEfRecord(int index, byte[] data) {
+ try {
+ SmsMessage msg = new SmsMessage();
+
+ msg.indexOnIcc = index;
+
+ // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT,
+ // or STORED_UNSENT
+ // See 3GPP2 C.S0023 3.4.27
+ if ((data[0] & 1) == 0) {
+ Log.w(LOG_TAG, "SMS parsing failed: Trying to parse a free record");
+ return null;
+ } else {
+ msg.statusOnIcc = data[0] & 0x07;
+ }
+
+ // Second byte is the MSG_LEN, length of the message
+ // See 3GPP2 C.S0023 3.4.27
+ int size = data[1];
+
+ // Note: Data may include trailing FF's. That's OK; message
+ // should still parse correctly.
+ byte[] pdu = new byte[size];
+ System.arraycopy(data, 2, pdu, 0, size);
+ // the message has to be parsed before it can be displayed
+ // see gsm.SmsMessage
+ return msg;
+ } catch (RuntimeException ex) {
+ Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
+ return null;
+ }
+
+ }
+
+ /**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+ public static int getTPLayerLengthForPDU(String pdu) {
+ Log.w(LOG_TAG, "getTPLayerLengthForPDU: is not supported in CDMA mode.");
+ return 0;
+ }
+
+ /**
+ * Get an SMS-SUBMIT PDU for a destination address and a message
+ *
+ * @param scAddress Service Centre address. Null means use default.
+ * @param destinationAddress Address of the recipient.
+ * @param message String representation of the message payload.
+ * @param statusReportRequested Indicates whether a report is requested for this message.
+ * @param headerData Array containing the data for the User Data Header, preceded
+ * by the Element Identifiers.
+ * @return a <code>SubmitPdu</code> containing the encoded SC
+ * address, if applicable, and the encoded message.
+ * Returns null on encode error.
+ * @hide
+ */
+ public static SubmitPdu getSubmitPdu(String scAddress,
+ String destinationAddress, String message,
+ boolean statusReportRequested, byte[] headerData) {
+
+ SmsMessage sms = new SmsMessage();
+ SubmitPdu ret = new SubmitPdu();
+ UserData uData = new UserData();
+ SmsHeader smsHeader;
+
+ // Perform null parameter checks.
+ if (message == null || destinationAddress == null) {
+ return null;
+ }
+
+ // ** Set UserData + SmsHeader **
+ try {
+ // First, try encoding it with the GSM alphabet
+ int septetCount = GsmAlphabet.countGsmSeptets(message, true);
+ // User Data (and length)
+
+ uData.userData = message.getBytes();
+
+ if (uData.userData.length > MAX_USER_DATA_SEPTETS) {
+ // Message too long
+ return null;
+ }
+
+ // desired TP-Data-Coding-Scheme
+ uData.userDataEncoding = UserData.UD_ENCODING_GSM_7BIT_ALPHABET;
+
+ // paddingBits not needed for UD_ENCODING_GSM_7BIT_ALPHABET
+
+ // sms header
+ if(headerData != null) {
+ smsHeader = SmsHeader.parse(headerData);
+ uData.userDataHeader = smsHeader;
+ } else {
+ // no user data header available!
+ }
+
+ } catch (EncodeException ex) {
+ byte[] textPart;
+ // Encoding to the 7-bit alphabet failed. Let's see if we can
+ // send it as a UCS-2 encoded message
+
+ try {
+ textPart = message.getBytes("utf-16be");
+ } catch (UnsupportedEncodingException uex) {
+ Log.e(LOG_TAG, "Implausible UnsupportedEncodingException ", uex);
+ return null;
+ }
+
+ uData.userData = textPart;
+
+ if (uData.userData.length > MAX_USER_DATA_BYTES) {
+ // Message too long
+ return null;
+ }
+
+ // TP-Data-Coding-Scheme
+ uData.userDataEncoding = UserData.UD_ENCODING_UNICODE_16;
+
+ // sms header
+ if(headerData != null) {
+ smsHeader = SmsHeader.parse(headerData);
+ uData.userDataHeader = smsHeader;
+ } else {
+ // no user data header available!
+ }
+ }
+
+ byte[] data = sms.getEnvelope(destinationAddress, statusReportRequested, uData,
+ (headerData != null), (null == headerData));
+
+ if (null == data) return null;
+
+ ret.encodedMessage = data;
+ ret.encodedScAddress = null;
+ return ret;
+ }
+
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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
+ * 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 destinationAddress, short destinationPort, byte[] data,
+ boolean statusReportRequested) {
+
+ SmsMessage sms = new SmsMessage();
+ SubmitPdu ret = new SubmitPdu();
+ UserData uData = new UserData();
+ SmsHeader smsHeader = new SmsHeader();
+
+ if (data.length > (MAX_USER_DATA_BYTES - 7 /* UDH size */)) {
+ Log.e(LOG_TAG, "SMS data message may only contain "
+ + (MAX_USER_DATA_BYTES - 7) + " bytes");
+ return null;
+ }
+
+ 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.add(
+ new SmsHeader.Element(SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT, destPort));
+
+ smsHeader.nbrOfHeaders = smsHeader.getElements().size();
+ uData.userDataHeader = smsHeader;
+
+ // TP-Data-Coding-Scheme
+ // No class, 8 bit data
+ uData.userDataEncoding = UserData.UD_ENCODING_OCTET;
+ uData.userData = data;
+
+ byte[] msgData = sms.getEnvelope(destinationAddress, statusReportRequested, uData,
+ true, true);
+
+ ret.encodedMessage = msgData;
+ ret.encodedScAddress = null;
+ return ret;
+ }
+
+ 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);
+ }
+
+ }
+
+ /**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+ public int getProtocolIdentifier() {
+ Log.w(LOG_TAG, "getProtocolIdentifier: is not supported in CDMA mode.");
+ // (3GPP TS 23.040): "no interworking, but SME to SME protocol":
+ return 0;
+ }
+
+ /**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+ public boolean isReplace() {
+ Log.w(LOG_TAG, "isReplace: is not supported in CDMA mode.");
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+ public boolean isCphsMwiMessage() {
+ Log.w(LOG_TAG, "isCphsMwiMessage: is not supported in CDMA mode.");
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isMWIClearMessage() {
+ if ((mBearerData != null) && (0 == mBearerData.numberOfMessages)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isMWISetMessage() {
+ if ((mBearerData != null) && (mBearerData.numberOfMessages >0)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isMwiDontStore() {
+ if ((mBearerData != null) && (mBearerData.numberOfMessages >0)
+ && (null == mBearerData.userData)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the status for a previously submitted message.
+ * For not interfering with status codes from GSM, this status code is
+ * shifted to the bits 31-16.
+ */
+ public int getStatus() {
+ return(status<<16);
+ }
+
+ /**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+ public boolean isStatusReportMessage() {
+ Log.w(LOG_TAG, "isStatusReportMessage: is not supported in CDMA mode.");
+ return false;
+ }
+
+ /**
+ * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
+ */
+ public boolean isReplyPathPresent() {
+ Log.w(LOG_TAG, "isReplyPathPresent: is not supported in CDMA mode.");
+ return false;
+ }
+
+ /**
+ * Returns the teleservice type of the message.
+ * @return the teleservice:
+ * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_NOT_SET},
+ * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WMT},
+ * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WEMT},
+ * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_VMN},
+ * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WAP}
+ */
+ public int getTeleService() {
+ return mEnvelope.teleService;
+ }
+
+ /**
+ * Decodes pdu to an empty SMS object.
+ * In the CDMA case the pdu is just an internal byte stream representation
+ * of the SMS Java-object.
+ * @see #createPdu()
+ */
+ private void parsePdu(byte[] pdu) {
+ ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
+ DataInputStream dis = new DataInputStream(new BufferedInputStream(bais));
+ byte length;
+ SmsEnvelope env = new SmsEnvelope();
+ CdmaSmsAddress addr = new CdmaSmsAddress();
+
+ try {
+ env.messageType = dis.readInt();
+ env.teleService = dis.readInt();
+ env.serviceCategory = dis.readInt();
+
+ addr.digitMode = dis.readByte();
+ addr.numberMode = dis.readByte();
+ addr.ton = dis.readByte();
+ addr.numberPlan = dis.readByte();
+
+ length = dis.readByte();
+ addr.numberOfDigits = length;
+ addr.origBytes = new byte[length];
+ dis.read(addr.origBytes, 0, length); // digits
+
+ env.bearerReply = dis.readInt();
+ // CauseCode values:
+ env.replySeqNo = dis.readByte();
+ env.errorClass = dis.readByte();
+ env.causeCode = dis.readByte();
+
+ //encoded BearerData:
+ length = dis.readByte();
+ env.bearerData = new byte[length];
+ dis.read(env.bearerData, 0, length);
+ dis.close();
+ } catch (Exception ex) {
+ Log.e(LOG_TAG, "createFromPdu: conversion from byte array to object failed: " + ex);
+ }
+
+ // link the filled objects to this SMS
+ originatingAddress = addr;
+ env.origAddress = addr;
+ mEnvelope = env;
+
+ parseSms();
+ }
+
+ /**
+ * Parses a SMS message from its BearerData stream. (mobile-terminated only)
+ */
+ protected void parseSms() {
+ mBearerData = SmsDataCoding.decodeCdmaSms(mEnvelope.bearerData);
+ messageRef = mBearerData.messageID;
+
+ // TP-Message-Type-Indicator
+ // (See 3GPP2 C.S0015-B, v2, 4.5.1)
+ int messageType = mBearerData.messageType;
+
+ switch (messageType) {
+ case MESSAGE_TYPE_USER_ACK:
+ case MESSAGE_TYPE_READ_ACK:
+ case MESSAGE_TYPE_DELIVER:
+ // Deliver (mobile-terminated only)
+ parseSmsDeliver();
+ break;
+ case MESSAGE_TYPE_DELIVERY_ACK:
+ parseSmsDeliveryAck();
+ break;
+
+ default:
+ // the rest of these
+ throw new RuntimeException("Unsupported message type: " + messageType);
+ }
+ }
+
+ /**
+ * 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 (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) {
+ status = mBearerData.errorClass << 8;
+ status |= mBearerData.messageStatus;
+ }
+
+ parseUserData(mBearerData.userData);
+
+ }
+
+ /**
+ * Parses the User Data of an SMS.
+ */
+ private void parseUserData(UserData uData) {
+ int encodingType;
+
+ if (null == uData) {
+ return;
+ }
+
+ encodingType = uData.userDataEncoding;
+
+ // insert DCS-decoding here when type is supported by ril-library
+
+ userData = uData.userData;
+ userDataHeader = uData.userDataHeader;
+
+ switch (encodingType) {
+ case UD_ENCODING_GSM_7BIT_ALPHABET:
+ case UD_ENCODING_UNICODE_16:
+ // user data was already decoded by wmsts-library
+ messageBody = new String(userData);
+ break;
+
+ // data and unsupported encodings:
+ case UD_ENCODING_OCTET:
+ default:
+ messageBody = null;
+ break;
+ }
+
+ if (Config.LOGV) Log.v(LOG_TAG, "SMS message body (raw): '" + messageBody + "'");
+
+ if (messageBody != null) {
+ parseMessageBody();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MessageClass getMessageClass() {
+ if (BearerData.DISPLAY_IMMEDIATE == mBearerData.displayMode ) {
+ return MessageClass.CLASS_0;
+ } else {
+ return MessageClass.UNKNOWN;
+ }
+ }
+
+ /**
+ * Creates BearerData and Envelope from parameters for a Submit SMS.
+ * @return byte stream for SubmitPdu.
+ */
+ private byte[] getEnvelope(String destinationAddress, boolean statusReportRequested,
+ UserData userData, boolean hasHeaders, boolean useNewId) {
+
+ BearerData mBearerData = new BearerData();
+ SmsEnvelope env = new SmsEnvelope();
+ CdmaSmsAddress mSmsAddress = new CdmaSmsAddress();
+
+ // ** set SmsAddress **
+ mSmsAddress.digitMode = CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR;
+ try {
+ mSmsAddress.origBytes = destinationAddress.getBytes("UTF-8");
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "doGetSubmitPdu: conversion of destinationAddress from string to byte[]"
+ + " failed: " + e.getMessage());
+ return null;
+ }
+ mSmsAddress.numberOfDigits = (byte)mSmsAddress.origBytes.length;
+ mSmsAddress.numberMode = CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK;
+ // see C.S0015-B, v2.0, 3.4.3.3
+ mSmsAddress.numberPlan = CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY;
+ mSmsAddress.ton = CdmaSmsAddress.TON_INTERNATIONAL_OR_IP;
+
+ // ** set BearerData **
+ mBearerData.userData = userData;
+ mBearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT;
+
+ if (useNewId) {
+ setNextMessageId();
+ }
+ mBearerData.messageID = nextMessageId;
+
+ // Set the reply options (See C.S0015-B, v2.0, 4.5.11)
+ if(statusReportRequested) {
+ mBearerData.deliveryAckReq = true;
+ } else {
+ mBearerData.deliveryAckReq = false;
+ }
+ // Currently settings applications do not support this
+ mBearerData.userAckReq = false;
+ mBearerData.readAckReq = false;
+ mBearerData.reportReq = false;
+
+ // Set the display mode (See C.S0015-B, v2.0, 4.5.16)
+ mBearerData.displayMode = BearerData.DISPLAY_DEFAULT;
+
+ // number of messages: not needed for encoding!
+
+ // indicate whether a user data header is available
+ mBearerData.hasUserDataHeader = hasHeaders;
+
+ // ** encode BearerData **
+ byte[] encodedBearerData = null;
+ try {
+ encodedBearerData = SmsDataCoding.encodeCdmaSms(mBearerData);
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "doGetSubmitPdu: EncodeCdmaSMS function in JNI interface failed: "
+ + e.getMessage());
+ return null;
+ }
+
+ // ** SmsEnvelope **
+ env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
+ env.teleService = SmsEnvelope.TELESERVICE_WEMT;
+ env.destAddress = mSmsAddress;
+ env.bearerReply = RETURN_ACK;
+ env.bearerData = encodedBearerData;
+ mEnvelope = env;
+
+ // get byte array output stream from SmsAddress object and SmsEnvelope member.
+ return serialize(mSmsAddress);
+ }
+
+ /**
+ * Set the nextMessageId to a random value between 0 and 65536
+ * See C.S0015-B, v2.0, 4.3.1.5
+ */
+ private void setNextMessageId() {
+ // Message ID, modulo 65536
+ if(firstSMS) {
+ Random generator = new Random();
+ nextMessageId = generator.nextInt(65536);
+ firstSMS = false;
+ } else {
+ nextMessageId = ++nextMessageId & 0xFFFF;
+ }
+ }
+
+ /**
+ * Creates ByteArrayOutputStream from CdmaSmsAddress and SmsEnvelope objects
+ *
+ * @param address CdmaSmsAddress object
+ * @return ByteArrayOutputStream
+ */
+ private byte[] serialize(CdmaSmsAddress destAddress) {
+ SmsEnvelope env = mEnvelope;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
+ DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
+
+ try {
+ dos.writeInt(env.teleService);
+ dos.writeInt(0); //servicePresent
+ dos.writeInt(0); //serviceCategory
+ dos.write(destAddress.digitMode);
+ dos.write(destAddress.numberMode);
+ dos.write(destAddress.ton); // number_type
+ dos.write(destAddress.numberPlan);
+ dos.write(destAddress.numberOfDigits);
+ dos.write(destAddress.origBytes, 0, destAddress.origBytes.length); // digits
+ // Subaddress is not supported.
+ dos.write(0); //subaddressType
+ dos.write(0); //subaddr_odd
+ dos.write(0); //subaddr_nbr_of_digits
+ dos.write(env.bearerData.length);
+ dos.write(env.bearerData, 0, env.bearerData.length);
+ dos.close();
+ return baos.toByteArray();
+ } catch(IOException ex) {
+ Log.e(LOG_TAG, "serialize: conversion from object to data output stream failed: " + ex);
+ return null;
+ }
+ }
+
+ /**
+ * Creates byte array (pseudo pdu) from SMS object.
+ * Note: Do not call this method more than once per object!
+ */
+ private void createPdu() {
+ SmsEnvelope env = mEnvelope;
+ CdmaSmsAddress addr = env.origAddress;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
+ DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
+
+ try {
+ dos.writeInt(env.messageType);
+ dos.writeInt(env.teleService);
+ dos.writeInt(env.serviceCategory);
+
+ dos.writeByte(addr.digitMode);
+ dos.writeByte(addr.numberMode);
+ dos.writeByte(addr.ton);
+ dos.writeByte(addr.numberPlan);
+ dos.writeByte(addr.numberOfDigits);
+ dos.write(addr.origBytes, 0, addr.origBytes.length); // digits
+
+ dos.writeInt(env.bearerReply);
+ // CauseCode values:
+ dos.writeByte(env.replySeqNo);
+ dos.writeByte(env.errorClass);
+ dos.writeByte(env.causeCode);
+ //encoded BearerData:
+ dos.writeByte(env.bearerData.length);
+ dos.write(env.bearerData, 0, env.bearerData.length);
+ dos.close();
+
+ mPdu = baos.toByteArray();
+ } catch (IOException ex) {
+ Log.e(LOG_TAG, "createPdu: conversion from object to byte array failed: " + ex);
+ }
+ }
+
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java b/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java
new file mode 100644
index 000000000000..f27f79cd9ebe
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java
@@ -0,0 +1,46 @@
+/*
+ * 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.cdma;
+
+public class TtyIntent {
+
+ private static final String TAG = "TtyIntent";
+
+
+ /** Event for TTY mode change */
+
+ /**
+ * Broadcast intent action indicating that the TTY has either been
+ * enabled or disabled. An intent extra provides this state as a boolean,
+ * where {@code true} means enabled.
+ * @see #TTY_ENABLED
+ *
+ * {@hide}
+ */
+ public static final String TTY_ENABLED_CHANGE_ACTION =
+ "com.android.internal.telephony.cdma.intent.action.TTY_ENABLED_CHANGE";
+
+ /**
+ * The lookup key for a boolean that indicates whether TTY mode is enabled or
+ * disabled. {@code true} means TTY mode is enabled. Retrieve it with
+ * {@link android.content.Intent#getBooleanExtra(String,boolean)}.
+ *
+ * {@hide}
+ */
+ public static final String TTY_ENABLED = "ttyEnabled";
+
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/package.html b/telephony/java/com/android/internal/telephony/cdma/package.html
new file mode 100644
index 000000000000..cf1ad4a046bf
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/package.html
@@ -0,0 +1,6 @@
+<HTML>
+<BODY>
+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
new file mode 100644
index 000000000000..fec95297f76d
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma.sms;
+
+public final class BearerData{
+
+ // For completeness the following fields are listed, though not used yet.
+ /**
+ * Supported priority modes for CDMA SMS messages
+ * (See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1)
+ */
+ //public static final int PRIORITY_NORMAL = 0x0;
+ //public static final int PRIORITY_INTERACTIVE = 0x1;
+ //public static final int PRIORITY_URGENT = 0x2;
+ //public static final int PRIORITY_EMERGENCY = 0x3;
+
+ /**
+ * Supported privacy modes for CDMA SMS messages
+ * (See 3GPP2 C.S0015-B, v2.0, table 4.5.10-1)
+ */
+ //public static final int PRIVACY_NOT_RESTRICTED = 0x0;
+ //public static final int PRIVACY_RESTRICTED = 0x1;
+ //public static final int PRIVACY_CONFIDENTIAL = 0x2;
+ //public static final int PRIVACY_SECRET = 0x3;
+
+ /**
+ * Supported alert modes for CDMA SMS messages
+ * (See 3GPP2 C.S0015-B, v2.0, table 4.5.13-1)
+ */
+ //public static final int ALERT_DEFAULT = 0x0;
+ //public static final int ALERT_LOW_PRIO = 0x1;
+ //public static final int ALERT_MEDIUM_PRIO = 0x2;
+ //public static final int ALERT_HIGH_PRIO = 0x3;
+
+ /**
+ * Supported display modes for CDMA SMS messages
+ * (See 3GPP2 C.S0015-B, v2.0, table 4.5.16-1)
+ */
+ public static final int DISPLAY_IMMEDIATE = 0x0;
+ public static final int DISPLAY_DEFAULT = 0x1;
+ public static final int DISPLAY_USER = 0x2;
+
+ /**
+ * Supported message types for CDMA SMS messages
+ * (See 3GPP2 C.S0015-B, v2.0, table 4.5.1-1)
+ */
+ public static final int MESSAGE_TYPE_DELIVER = 0x01;
+ public static final int MESSAGE_TYPE_SUBMIT = 0x02;
+ public static final int MESSAGE_TYPE_CANCELLATION = 0x03;
+ public static final int MESSAGE_TYPE_DELIVERY_ACK = 0x04;
+ public static final int MESSAGE_TYPE_USER_ACK = 0x05;
+ public static final int MESSAGE_TYPE_READ_ACK = 0x06;
+ public static final int MESSAGE_TYPE_DELIVER_REPORT = 0x07;
+ public static final int MESSAGE_TYPE_SUBMIT_REPORT = 0x08;
+
+ /**
+ * SMS Message Status Codes
+ * (See 3GPP2 C.S0015-B, v2.0, table 4.5.21-1)
+ */
+ /* no-error codes */
+ public static final int ERROR_NONE = 0x00;
+ public static final int STATUS_ACCEPTED = 0x00;
+ public static final int STATUS_DEPOSITED_TO_INTERNET = 0x01;
+ public static final int STATUS_DELIVERED = 0x02;
+ public static final int STATUS_CANCELLED = 0x03;
+ /* temporary-error and permanent-error codes */
+ public static final int ERROR_TEMPORARY = 0x02;
+ public static final int STATUS_NETWORK_CONGESTION = 0x04;
+ public static final int STATUS_NETWORK_ERROR = 0x05;
+ public static final int STATUS_UNKNOWN_ERROR = 0x1F;
+ /* permanent-error codes */
+ public static final int ERROR_PERMANENT = 0x03;
+ public static final int STATUS_CANCEL_FAILED = 0x06;
+ public static final int STATUS_BLOCKED_DESTINATION = 0x07;
+ public static final int STATUS_TEXT_TOO_LONG = 0x08;
+ public static final int STATUS_DUPLICATE_MESSAGE = 0x09;
+ public static final int STATUS_INVALID_DESTINATION = 0x0A;
+ public static final int STATUS_MESSAGE_EXPIRED = 0x0D;
+ /* undefined-status codes */
+ public static final int ERROR_UNDEFINED = 0xFF;
+ public static final int STATUS_UNDEFINED = 0xFF;
+
+ /** Bit-mask indicating used fields for SmsDataCoding */
+ public int mask;
+
+ /**
+ * 4-bit value indicating the message type in accordance to
+ * table 4.5.1-1
+ * (See 3GPP2 C.S0015-B, v2, 4.5.1)
+ */
+ public byte messageType;
+
+ /**
+ * 16-bit value indicating the message ID, which increments modulo 65536.
+ * (Special rules apply for WAP-messages.)
+ * (See 3GPP2 C.S0015-B, v2, 4.5.1)
+ */
+ public int messageID;
+
+ /**
+ * 1-bit value that indicates whether a User Data Header is present.
+ * (See 3GPP2 C.S0015-B, v2, 4.5.1)
+ */
+ public boolean hasUserDataHeader;
+
+ /**
+ * provides the information for the user data
+ * (e.g. padding bits, user data, user data header, etc)
+ * (See 3GPP2 C.S.0015-B, v2, 4.5.2)
+ */
+ public UserData userData;
+
+ //public UserResponseCode userResponseCode;
+
+ /**
+ * 6-byte-field, see 3GPP2 C.S0015-B, v2, 4.5.4
+ * year, month, day, hours, minutes, seconds;
+ */
+ public byte[] timeStamp;
+
+ //public SmsTime validityPeriodAbsolute;
+ //public SmsRelTime validityPeriodRelative;
+ //public SmsTime deferredDeliveryTimeAbsolute;
+ //public SmsRelTime deferredDeliveryTimeRelative;
+ //public byte priority;
+ //public byte privacy;
+
+ /**
+ * Reply Option
+ * 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;
+ public boolean readAckReq;
+ 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)
+ */
+ public int numberOfMessages;
+
+ //public int alert;
+ //public int language;
+
+ /**
+ * 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)
+ */
+ public CdmaSmsAddress callbackNumber;
+
+ /**
+ * 2-bit value that is used to indicate to the mobile station when to display
+ * the received message.
+ * (See 3GPP2 C.S0015-B, v2, 4.5.16)
+ */
+ public byte displayMode = DISPLAY_DEFAULT;
+
+ /**
+ * First component of the Message status, that indicates if an error has occurred
+ * and whether the error is considered permanent or temporary.
+ * (See 3GPP2 C.S0015-B, v2, 4.5.21)
+ */
+ public int errorClass = ERROR_UNDEFINED;
+
+ /**
+ * Second component of the Message status, that indicates if an error has occurred
+ * and the cause of the error.
+ * (See 3GPP2 C.S0015-B, v2, 4.5.21)
+ */
+ public int messageStatus = STATUS_UNDEFINED;
+
+}
+
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
new file mode 100644
index 000000000000..1643cab46b01
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma.sms;
+
+import com.android.internal.telephony.SmsAddress;
+
+public class CdmaSmsAddress extends SmsAddress {
+ /**
+ * digit mode indicators
+ * (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;
+
+ /**
+ * number mode indicators
+ * (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;
+
+ /**
+ * number types for data networks
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
+ */
+ static public final int TON_UNKNOWN = 0x00;
+ static public final int TON_INTERNATIONAL_OR_IP = 0x01;
+ static public final int TON_NATIONAL_OR_EMAIL = 0x02;
+ static public final int TON_NETWORK = 0x03;
+ static public final int TON_SUBSCRIBER = 0x04;
+ static public final int TON_ALPHANUMERIC = 0x05;
+ static public final int TON_ABBREVIATED = 0x06;
+ static public final int TON_RESERVED = 0x07;
+
+ /**
+ * 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)
+ */
+ static public final int NUMBERING_PLAN_UNKNOWN = 0x0;
+ static public final int NUMBERING_PLAN_ISDN_TELEPHONY = 0x1;
+ //static protected final int NUMBERING_PLAN_DATA = 0x3;
+ //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;
+
+ /**
+ * 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)
+ */
+ 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(){
+ }
+
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java
new file mode 100644
index 000000000000..6ba7463a3047
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma.sms;
+
+import com.android.internal.telephony.SmsHeader;
+
+/*
+ * The SMSDataCoding class encodes and decodes CDMA SMS messages.
+ */
+public class SmsDataCoding {
+ private final static String TAG = "CDMA_SMS_JNI";
+
+ private final static int CDMA_SMS_WMS_MASK_BD_NULL = 0x00000000;
+ private final static int CDMA_SMS_WMS_MASK_BD_MSG_ID = 0x00000001;
+ private final static int CDMA_SMS_WMS_MASK_BD_USER_DATA = 0x00000002;
+// private final static int CDMA_SMS_WMS_MASK_BD_USER_RESP = 0x00000004;
+ private final static int CDMA_SMS_WMS_MASK_BD_MC_TIME = 0x00000008;
+// private final static int CDMA_SMS_WMS_MASK_BD_VALID_ABS = 0x00000010;
+// private final static int CDMA_SMS_WMS_MASK_BD_VALID_REL = 0x00000020;
+// private final static int CDMA_SMS_WMS_MASK_BD_DEFER_ABS = 0x00000040;
+// private final static int CDMA_SMS_WMS_MASK_BD_DEFER_REL = 0x00000080;
+// private final static int CDMA_SMS_WMS_MASK_BD_PRIORITY = 0x00000100;
+// private final static int CDMA_SMS_WMS_MASK_BD_PRIVACY = 0x00000200;
+// private final static int CDMA_SMS_WMS_MASK_BD_REPLY_OPTION = 0x00000400;
+ private final static int CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS = 0x00000800;
+// private final static int CDMA_SMS_WMS_MASK_BD_ALERT = 0x00001000;
+// private final static int CDMA_SMS_WMS_MASK_BD_LANGUAGE = 0x00002000;
+ private final static int CDMA_SMS_WMS_MASK_BD_CALLBACK = 0x00004000;
+ private final static int CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE = 0x00008000;
+// private final static int CDMA_SMS_WMS_MASK_BD_SCPT_DATA = 0x00010000;
+// private final static int CDMA_SMS_WMS_MASK_BD_SCPT_RESULT = 0x00020000;
+// private final static int CDMA_SMS_WMS_MASK_BD_DEPOSIT_INDEX = 0x00040000;
+// private final static int CDMA_SMS_WMS_MASK_BD_DELIVERY_STATUS = 0x00080000;
+// private final static int CDMA_SMS_WMS_MASK_BD_IP_ADDRESS = 0x10000000;
+// private final static int CDMA_SMS_WMS_MASK_BD_RSN_NO_NOTIFY = 0x20000000;
+// private final static int CDMA_SMS_WMS_MASK_BD_OTHER = 0x40000000;
+
+ /**
+ * Successful operation.
+ */
+ private static final int JNI_CDMA_SMS_SUCCESS = 0;
+
+ /**
+ * General failure.
+ */
+ private static final int JNI_CDMA_SMS_FAILURE = 1;
+
+ /**
+ * Data length is out of length.
+ */
+ private static final int JNI_CDMA_SMS_DATA_LEN_OUT_OF_RANGE = 2;
+
+ /**
+ * Class name unknown.
+ */
+ private static final int JNI_CDMA_SMS_CLASS_UNKNOWN = 3;
+
+ /**
+ * Field ID unknown.
+ */
+ private static final int JNI_CDMA_SMS_FIELD_ID_UNKNOWN = 4;
+
+ /**
+ * Memory allocation failed.
+ */
+ private static final int JNI_CDMA_SMS_OUT_OF_MEMORY = 5;
+
+ /**
+ * Encode SMS.
+ *
+ * @param bearerData an instance of BearerData.
+ *
+ * @return the encoded SMS as byte[].
+ */
+ public static byte[] encodeCdmaSms(BearerData bearerData) {
+ byte[] encodedSms;
+
+ if( nativeCdmaSmsConstructClientBD() == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+
+ // check bearer data and generate bit mask
+ generateBearerDataBitMask(bearerData);
+ encodedSms = startEncoding(bearerData);
+
+ if( nativeCdmaSmsDestructClientBD() == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+ return encodedSms;
+ }
+
+ /**
+ * Decode SMS.
+ *
+ * @param SmsData the encoded SMS.
+ *
+ * @return an instance of BearerData.
+ */
+ public static BearerData decodeCdmaSms(byte[] SmsData) {
+ BearerData bearerData;
+
+ if( nativeCdmaSmsConstructClientBD() == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+
+ bearerData = startDecoding(SmsData);
+
+ if( nativeCdmaSmsDestructClientBD() == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+ return bearerData;
+ }
+
+ private static void generateBearerDataBitMask(BearerData bearerData) {
+ // initial
+ bearerData.mask = CDMA_SMS_WMS_MASK_BD_NULL;
+
+ // check message type
+ if (bearerData.messageType != 0){
+ bearerData.mask |= CDMA_SMS_WMS_MASK_BD_MSG_ID;
+ }
+
+ // check mUserData
+ if (bearerData.userData != null){
+ bearerData.mask |= CDMA_SMS_WMS_MASK_BD_USER_DATA;
+ }
+
+ // check mTimeStamp
+ if (bearerData.timeStamp != null){
+ bearerData.mask |= CDMA_SMS_WMS_MASK_BD_MC_TIME;
+ }
+
+ // check mNumberOfMessages
+ if (bearerData.numberOfMessages > 0){
+ bearerData.mask |= CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS;
+ }
+
+ // check mCallbackNumber
+ if(bearerData.callbackNumber != null){
+ bearerData.mask |= CDMA_SMS_WMS_MASK_BD_CALLBACK;
+ }
+
+ // check DisplayMode
+ if(bearerData.displayMode == BearerData.DISPLAY_DEFAULT ||
+ bearerData.displayMode == BearerData.DISPLAY_IMMEDIATE ||
+ bearerData.displayMode == BearerData.DISPLAY_USER){
+ bearerData.mask |= CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE;
+ }
+ }
+
+ private static byte[] startEncoding(BearerData bearerData) {
+ int m_id;
+ byte[] m_data;
+ int dataLength;
+ byte[] encodedSms;
+ int nbrOfHeaders = 0;
+
+ if( nativeCdmaSmsSetBearerDataPrimitives(bearerData) == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+
+ if ((bearerData.mask & CDMA_SMS_WMS_MASK_BD_USER_DATA) == CDMA_SMS_WMS_MASK_BD_USER_DATA){
+ if( nativeCdmaSmsSetUserData(bearerData.userData) == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+
+ if (bearerData.userData.userDataHeader != null){
+ nbrOfHeaders = bearerData.userData.userDataHeader.nbrOfHeaders;
+ }
+
+ for (int i = 0; i < nbrOfHeaders; i++) {
+ m_id = bearerData.userData.userDataHeader.getElements().get(i).getID();
+ m_data = bearerData.userData.userDataHeader.getElements().get(i).getData();
+ dataLength = m_data.length;
+ if( nativeCdmaSmsSetUserDataHeader(m_id, m_data, dataLength, i)
+ == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+ }
+ }
+
+ if ((bearerData.mask & CDMA_SMS_WMS_MASK_BD_CALLBACK) == CDMA_SMS_WMS_MASK_BD_CALLBACK) {
+ if( nativeCdmaSmsSetSmsAddress(bearerData.callbackNumber) == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+ }
+
+ /* call native method to encode SMS */
+ encodedSms = nativeCdmaSmsEncodeSms();
+
+ return encodedSms;
+ }
+
+ private static BearerData startDecoding(byte[] SmsData) {
+ BearerData bData = new BearerData();
+ byte[] udhData;
+
+ /* call native method to decode SMS */
+ if( nativeCdmaSmsDecodeSms(SmsData) == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+
+ if( nativeCdmaSmsGetBearerDataPrimitives(bData) == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+
+ if ((bData.mask & CDMA_SMS_WMS_MASK_BD_USER_DATA) == CDMA_SMS_WMS_MASK_BD_USER_DATA) {
+ bData.userData = new UserData();
+ if( nativeCdmaSmsGetUserData(bData.userData) == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+
+ udhData = nativeCdmaSmsGetUserDataHeader();
+ if (udhData != null) {
+ bData.userData.userDataHeader = SmsHeader.parse(udhData);
+ }
+ }
+
+ if ((bData.mask & CDMA_SMS_WMS_MASK_BD_CALLBACK) == CDMA_SMS_WMS_MASK_BD_CALLBACK) {
+ bData.callbackNumber = new CdmaSmsAddress();
+ if( nativeCdmaSmsGetSmsAddress(bData.callbackNumber) == JNI_CDMA_SMS_FAILURE){
+ return null;
+ }
+ }
+
+ return bData;
+ }
+
+ // native methods
+
+ /**
+ * native method: Allocate memory for clientBD structure
+ *
+ * @return #JNI_CDMA_SMS_SUCCESS if succeed.
+ * #JNI_CDMA_SMS_FAILURE if fail.
+ */
+ private static native int nativeCdmaSmsConstructClientBD();
+
+ /**
+ * native method: Free memory used for clientBD structure
+ *
+ * @return #JNI_CDMA_SMS_SUCCESS if succeed.
+ * #JNI_CDMA_SMS_FAILURE if fail.
+ */
+ private static native int nativeCdmaSmsDestructClientBD();
+
+ /**
+ * native method: fill clientBD structure with bearerData primitives
+ *
+ * @param bearerData an instance of BearerData.
+ *
+ * @return #JNI_CDMA_SMS_SUCCESS if succeed.
+ * #JNI_CDMA_SMS_FAILURE if fail.
+ */
+ private static native int nativeCdmaSmsSetBearerDataPrimitives(BearerData bearerData);
+
+ /**
+ * native method: fill bearerData primitives with clientBD variables
+ *
+ * @param bearerData an instance of BearerData.
+ *
+ * @return #JNI_CDMA_SMS_SUCCESS if succeed.
+ * #JNI_CDMA_SMS_FAILURE if fail.
+ */
+ private static native int nativeCdmaSmsGetBearerDataPrimitives(BearerData bearerData);
+
+ /**
+ * native method: fill clientBD.user_data with UserData primitives
+ *
+ * @param userData an instance of UserData.
+ *
+ * @return #JNI_CDMA_SMS_SUCCESS if succeed.
+ * #JNI_CDMA_SMS_FAILURE if fail.
+ */
+ private static native int nativeCdmaSmsSetUserData(UserData userData);
+
+ /**
+ * native method: fill UserData primitives with clientBD.user_data
+ *
+ * @param userData an instance of UserData.
+ *
+ * @return #JNI_CDMA_SMS_SUCCESS if succeed.
+ * #JNI_CDMA_SMS_FAILURE if fail.
+ */
+ private static native int nativeCdmaSmsGetUserData(UserData userData);
+
+ /**
+ * native method: fill clientBD.user_data.headers with UserDataHeader primitives
+ *
+ * @param ID ID of element.
+ * @param data element data.
+ * @param dataLength data length
+ * @param index index of element
+ *
+ * @return #JNI_CDMA_SMS_SUCCESS if succeed.
+ * #JNI_CDMA_SMS_FAILURE if fail.
+ */
+ private static native int nativeCdmaSmsSetUserDataHeader(
+ int ID, byte[] data, int dataLength, int index);
+
+ /**
+ * native method: fill UserDataHeader primitives with clientBD.user_data.headers
+ *
+ * @return user data headers
+ */
+ private static native byte[] nativeCdmaSmsGetUserDataHeader();
+
+ /**
+ * native method: fill clientBD.callback with SmsAddress primitives
+ *
+ * @param smsAddr an instance of SmsAddress.
+ *
+ * @return #JNI_CDMA_SMS_SUCCESS if succeed.
+ * #JNI_CDMA_SMS_FAILURE if fail.
+ */
+ private static native int nativeCdmaSmsSetSmsAddress(CdmaSmsAddress smsAddr);
+
+ /**
+ * native method: fill SmsAddress primitives with clientBD.callback
+ *
+ * @param smsAddr an instance of SmsAddress.
+ *
+ * @return #JNI_CDMA_SMS_SUCCESS if succeed.
+ * #JNI_CDMA_SMS_FAILURE if fail.
+ */
+ private static native int nativeCdmaSmsGetSmsAddress(CdmaSmsAddress smsAddr);
+
+ /**
+ * native method: call encoding functions and get encoded SMS
+ *
+ * @return the encoded SMS
+ */
+ private static native byte[] nativeCdmaSmsEncodeSms();
+
+ /**
+ * native method: call decode functions
+ *
+ * @param encodedSMS encoded SMS.
+ *
+ * @return #JNI_CDMA_SMS_SUCCESS if succeed.
+ * #JNI_CDMA_SMS_FAILURE if fail.
+ */
+ private static native int nativeCdmaSmsDecodeSms(byte[] encodedSMS);
+
+ /**
+ * Load the shared library to link the native methods.
+ */
+ static {
+ try {
+ System.loadLibrary("cdma_sms_jni");
+ }
+ catch (UnsatisfiedLinkError ule) {
+ System.err.println("WARNING: Could not load cdma_sms_jni.so");
+ }
+ }
+}
+
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
new file mode 100644
index 000000000000..f80e8c091b7d
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma.sms;
+
+
+public final class SmsEnvelope{
+ /**
+ * Message Types
+ * (See 3GPP2 C.S0015-B 3.4.1)
+ */
+ static public final int MESSAGE_TYPE_POINT_TO_POINT = 0x00;
+ static public final int MESSAGE_TYPE_BROADCAST = 0x01;
+ static public final int MESSAGE_TYPE_ACKNOWLEDGE = 0x02;
+
+ /**
+ * Supported Teleservices
+ * (See 3GPP2 N.S0005 and TIA-41)
+ */
+ static public final int TELESERVICE_NOT_SET = 0x0000;
+ static public final int TELESERVICE_WMT = 0x1002;
+ static public final int TELESERVICE_VMN = 0x1003;
+ static public final int TELESERVICE_WAP = 0x1004;
+ static public final int TELESERVICE_WEMT = 0x1005;
+
+ // ServiceCategories for Cell Broadcast, see 3GPP2 C.R1001 table 9.3.1-1
+ //static public final int SERVICECATEGORY_EMERGENCY = 0x0010;
+ //...
+
+ /**
+ * maximum lengths for fields as defined in ril_cdma_sms.h
+ */
+ static public final int SMS_BEARER_DATA_MAX = 255;
+
+ /**
+ * Provides the type of a SMS message like point to point, broadcast or acknowledge
+ */
+ public int messageType;
+
+ /**
+ * The 16-bit Teleservice parameter identifies which upper layer service access point is sending
+ * or receiving the message.
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.1)
+ */
+ public int teleService = TELESERVICE_NOT_SET;
+
+ /**
+ * The 16-bit service category parameter identifies the type of service provided
+ * by the SMS message.
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.2)
+ */
+ public int serviceCategory;
+
+ /**
+ * The origination address identifies the originator of the SMS message.
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
+ */
+ public CdmaSmsAddress origAddress;
+
+ /**
+ * The destination address identifies the target of the SMS message.
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
+ */
+ public CdmaSmsAddress destAddress;
+
+ /**
+ * The 6-bit bearer reply parameter is used to request the return of a
+ * SMS Acknowledge Message.
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.5)
+ */
+ public int bearerReply;
+
+ /**
+ * Cause Code values:
+ * The cause code parameters are an indication whether an SMS error has occurred and if so,
+ * whether the condition is considered temporary or permanent.
+ * ReplySeqNo 6-bit value,
+ * ErrorClass 2-bit value,
+ * CauseCode 0-bit or 8-bit value
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.6)
+ */
+ public byte replySeqNo;
+ public byte errorClass;
+ public byte causeCode;
+
+ /**
+ * encoded bearer data
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.7)
+ */
+ public byte[] bearerData;
+
+ public SmsEnvelope() {
+ // nothing to see here
+ }
+
+}
+
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
new file mode 100644
index 000000000000..e7614694eae7
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma.sms;
+
+import com.android.internal.telephony.SmsHeader;
+
+public class UserData{
+
+ /**
+ * Supported user data encoding types
+ * (See 3GPP2 C.R1001-F, v1.0, table 9.1-1)
+ */
+ public static final int UD_ENCODING_OCTET = 0x00;
+ //public static final int UD_ENCODING_EXTENDED_PROTOCOL = 0x01;
+ public static final int UD_ENCODING_7BIT_ASCII = 0x02;
+ public static final int UD_ENCODING_IA5 = 0x03;
+ public static final int UD_ENCODING_UNICODE_16 = 0x04;
+ //public static final int UD_ENCODING_SHIFT_JIS = 0x05;
+ //public static final int UD_ENCODING_KOREAN = 0x06;
+ //public static final int UD_ENCODING_LATIN_HEBREW = 0x07;
+ //public static final int UD_ENCODING_LATIN = 0x08;
+ public static final int UD_ENCODING_GSM_7BIT_ALPHABET = 0x09;
+ //public static final int UD_ENCODING_GSM_DCS = 0x0A;
+
+ /**
+ * Contains the data header of the user data
+ */
+ public SmsHeader userDataHeader;
+
+ /**
+ * Contains the data encoding type for the SMS message
+ */
+ public int userDataEncoding;
+
+ // needed when encoding is IS91 or DCS (not supported yet):
+ //public int messageType;
+
+ /**
+ * Number of invalid bits in the last byte of data.
+ */
+ public int paddingBits;
+
+ /**
+ * Contains the user data of a SMS message
+ * (See 3GPP2 C.S0015-B, v2, 4.5.2)
+ */
+ public byte[] userData;
+
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/package.html b/telephony/java/com/android/internal/telephony/cdma/sms/package.html
new file mode 100644
index 000000000000..48e10340cb86
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/package.html
@@ -0,0 +1,6 @@
+<HTML>
+<BODY>
+Provides CDMA-specific features for text/data/PDU SMS messages
+@hide
+</BODY>
+</HTML>
diff --git a/telephony/java/com/android/internal/telephony/gsm/ApnSetting.java b/telephony/java/com/android/internal/telephony/gsm/ApnSetting.java
index 2f9141191f0e..4b1c1e4c143a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/ApnSetting.java
+++ b/telephony/java/com/android/internal/telephony/gsm/ApnSetting.java
@@ -16,7 +16,8 @@
package com.android.internal.telephony.gsm;
-import com.android.internal.telephony.*;
+import com.android.internal.telephony.Phone;
+
/**
* This class represents a apn setting for create PDP link
*/
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index fe2739265b59..c9e3496bb738 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -16,9 +16,6 @@
package com.android.internal.telephony.gsm;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
-import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
@@ -32,27 +29,33 @@ import android.os.Registrant;
import android.os.RegistrantList;
import android.os.SystemProperties;
import android.preference.PreferenceManager;
+import android.provider.Settings;
import android.provider.Telephony;
-import com.android.internal.telephony.*;
-import com.android.internal.telephony.gsm.stk.Service;
-
-import com.android.internal.telephony.test.SimulatedRadioControl;
-import android.text.TextUtils;
-import android.util.Log;
-import static com.android.internal.telephony.CommandsInterface.*;
-import static com.android.internal.telephony.TelephonyProperties.*;
-import android.net.Uri;
-import android.telephony.PhoneNumberUtils;
import android.telephony.CellLocation;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.text.TextUtils;
import android.util.Log;
+import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE;
+import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
+import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE;
+import static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION;
+import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL;
+import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL_CONDITIONAL;
+import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY;
+import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE;
+import static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY;
+import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
+import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
+
import com.android.internal.telephony.CallForwardInfo;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.DataConnection;
+import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
@@ -61,6 +64,7 @@ import com.android.internal.telephony.MmiCode;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.PhoneNotifier;
+import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.PhoneSubInfo;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.gsm.stk.Service;
@@ -81,10 +85,8 @@ public class GSMPhone extends PhoneBase {
// from this file will go into the radio log rather than the main
// log. (Use "adb logcat -b radio" to see them.)
static final String LOG_TAG = "GSM";
- private static final boolean LOCAL_DEBUG = false;
+ private static final boolean LOCAL_DEBUG = true;
- // Key used to read/write "disable data connection on boot" pref (used for testing)
- public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
// Key used to read/write current ciphering state
public static final String CIPHERING_KEY = "ciphering_key";
@@ -92,12 +94,12 @@ public class GSMPhone extends PhoneBase {
GsmCallTracker mCT;
GsmServiceStateTracker mSST;
- SMSDispatcher mSMS;
- DataConnectionTracker mDataConnection;
+ GsmSMSDispatcher mSMS;
+ GsmDataConnectionTracker mDataConnection;
SIMRecords mSIMRecords;
SimCard mSimCard;
Service mStkService;
- //MyHandler h;
+ MyHandler h;
ArrayList <GsmMmiCode> mPendingMMIs = new ArrayList<GsmMmiCode>();
SimPhoneBookInterfaceManager mSimPhoneBookIntManager;
SimSmsInterfaceManager mSimSmsIntManager;
@@ -129,7 +131,6 @@ public class GSMPhone extends PhoneBase {
public
GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) {
super(notifier, context, unitTestMode);
-
h = new MyHandler();
mCM = ci;
@@ -140,10 +141,10 @@ public class GSMPhone extends PhoneBase {
mCM.setPhoneType(RILConstants.GSM_PHONE);
mCT = new GsmCallTracker(this);
mSST = new GsmServiceStateTracker (this);
- mSMS = new SMSDispatcher(this);
+ mSMS = new GsmSMSDispatcher(this);
mIccFileHandler = new SIMFileHandler(this);
mSIMRecords = new SIMRecords(this);
- mDataConnection = new DataConnectionTracker (this);
+ mDataConnection = new GsmDataConnectionTracker (this);
mSimCard = new SimCard(this);
if (!unitTestMode) {
mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this);
@@ -152,11 +153,10 @@ public class GSMPhone extends PhoneBase {
}
mStkService = Service.getInstance(mCM, mSIMRecords, mContext,
(SIMFileHandler)mIccFileHandler, mSimCard);
-
+
mCM.registerForAvailable(h, EVENT_RADIO_AVAILABLE, null);
mSIMRecords.registerForRecordsLoaded(h, EVENT_SIM_RECORDS_LOADED, null);
- mCM.registerForOffOrNotAvailable(h, EVENT_RADIO_OFF_OR_NOT_AVAILABLE,
- null);
+ mCM.registerForOffOrNotAvailable(h, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mCM.registerForOn(h, EVENT_RADIO_ON, null);
mCM.setOnUSSD(h, EVENT_USSD, null);
mCM.setOnSuppServiceNotification(h, EVENT_SSN, null);
@@ -182,7 +182,7 @@ public class GSMPhone extends PhoneBase {
mCM.resetRadio(null);
sock.close();
} catch (IOException ex) {
- Log.w(LOG_TAG,
+ Log.w(LOG_TAG,
"Exception accepting socket", ex);
}
}
@@ -196,11 +196,63 @@ public class GSMPhone extends PhoneBase {
Log.w(LOG_TAG, "Failure to open com.android.internal.telephony.debug socket", ex);
}
}
+
+ //Change the system setting
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.CURRENT_ACTIVE_PHONE, RILConstants.GSM_PHONE);
+ }
+
+ public void dispose() {
+ synchronized(PhoneProxy.lockForRadioTechnologyChange) {
+ //Unregister from all former registered events
+ mCM.unregisterForAvailable(h); //EVENT_RADIO_AVAILABLE
+ mSIMRecords.unregisterForRecordsLoaded(h); //EVENT_SIM_RECORDS_LOADED
+ mCM.unregisterForOffOrNotAvailable(h); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE
+ mCM.unregisterForOn(h); //EVENT_RADIO_ON
+ mSST.unregisterForNetworkAttach(h); //EVENT_REGISTERED_TO_NETWORK
+ mCM.unSetOnUSSD(h);
+ mCM.unSetOnSuppServiceNotification(h);
+ mCM.unSetOnCallRing(h);
+
+ mPendingMMIs.clear();
+
+ //Force all referenced classes to unregister their former registered events
+ mStkService.dispose();
+ mCT.dispose();
+ mDataConnection.dispose();
+ mSST.dispose();
+ mIccFileHandler.dispose(); // instance of SimFileHandler
+ mSIMRecords.dispose();
+ mSimCard.dispose();
+ mSimPhoneBookIntManager.dispose();
+ mSimSmsIntManager.dispose();
+ mSubInfo.dispose();
+ }
+ }
+
+ public void removeReferences() {
+ this.mSimulatedRadioControl = null;
+ this.mStkService = null;
+ this.mSimPhoneBookIntManager = null;
+ this.mSimSmsIntManager = null;
+ this.mSMS = null;
+ this.mSubInfo = null;
+ this.mSIMRecords = null;
+ this.mIccFileHandler = null;
+ this.mSimCard = null;
+ this.mDataConnection = null;
+ this.mCT = null;
+ this.mSST = null;
+ }
+
+ protected void finalize() {
+ if(LOCAL_DEBUG) Log.d(LOG_TAG, "GSMPhone finalized");
}
-
+
+
//***** Overridden from Phone
- public ServiceState
+ public ServiceState
getServiceState() {
return mSST.ss;
}
@@ -209,7 +261,7 @@ public class GSMPhone extends PhoneBase {
return mSST.cellLoc;
}
- public Phone.State
+ public Phone.State
getState() {
return mCT.state;
}
@@ -264,25 +316,25 @@ public class GSMPhone extends PhoneBase {
// but no data will flow
ret = DataState.DISCONNECTED;
} else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */
- switch (mDataConnection.state) {
- case FAILED:
- case IDLE:
- ret = DataState.DISCONNECTED;
- break;
+ switch (mDataConnection.getState()) {
+ case FAILED:
+ case IDLE:
+ ret = DataState.DISCONNECTED;
+ break;
- case CONNECTED:
- if ( mCT.state != Phone.State.IDLE
- && !mSST.isConcurrentVoiceAndData())
- ret = DataState.SUSPENDED;
- else
- ret = DataState.CONNECTED;
- break;
-
- case INITING:
- case CONNECTING:
- case SCANNING:
- ret = DataState.CONNECTING;
- break;
+ case CONNECTED:
+ if ( mCT.state != Phone.State.IDLE
+ && !mSST.isConcurrentVoiceAndData())
+ ret = DataState.SUSPENDED;
+ else
+ ret = DataState.CONNECTED;
+ break;
+
+ case INITING:
+ case CONNECTING:
+ case SCANNING:
+ ret = DataState.CONNECTING;
+ break;
}
}
@@ -293,19 +345,18 @@ public class GSMPhone extends PhoneBase {
DataActivityState ret = DataActivityState.NONE;
if (mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE) {
- switch (mDataConnection.activity) {
-
- case DATAIN:
- ret = DataActivityState.DATAIN;
- break;
+ switch (mDataConnection.getActivity()) {
+ case DATAIN:
+ ret = DataActivityState.DATAIN;
+ break;
- case DATAOUT:
- ret = DataActivityState.DATAOUT;
- break;
+ case DATAOUT:
+ ret = DataActivityState.DATAOUT;
+ break;
- case DATAINANDOUT:
- ret = DataActivityState.DATAINANDOUT;
- break;
+ case DATAINANDOUT:
+ ret = DataActivityState.DATAINANDOUT;
+ break;
}
}
@@ -338,11 +389,11 @@ public class GSMPhone extends PhoneBase {
/**
* Notifiy registrants of a RING event.
*/
- void notifyIncomingRing() {
+ void notifyIncomingRing() {
AsyncResult ar = new AsyncResult(null, this, null);
mIncomingRingRegistrants.notifyRegistrants(ar);
}
-
+
/*package*/ void
notifyDisconnect(Connection cn) {
mDisconnectRegistrants.notifyResult(cn);
@@ -351,7 +402,7 @@ public class GSMPhone extends PhoneBase {
void notifyUnknownConnection() {
mUnknownConnectionRegistrants.notifyResult(this);
}
-
+
void notifySuppServiceFailed(SuppService code) {
mSuppServiceFailedRegistrants.notifyResult(code);
}
@@ -372,32 +423,22 @@ public class GSMPhone extends PhoneBase {
}
/*package*/ void
- notifyDataConnection(String reason) {
- mNotifier.notifyDataConnection(this, reason);
- }
-
- /*package*/ void
notifyDataConnectionFailed(String reason) {
mNotifier.notifyDataConnectionFailed(this, reason);
}
/*package*/ void
- notifyDataActivity() {
- mNotifier.notifyDataActivity(this);
- }
-
- /*package*/ void
updateMessageWaitingIndicator(boolean mwi) {
// this also calls notifyMessageWaitingIndicator()
mSIMRecords.setVoiceMessageWaiting(1, mwi ? -1 : 0);
}
- /*package*/ void
+ public void
notifyMessageWaitingIndicator() {
mNotifier.notifyMessageWaitingChanged(this);
}
- /*package*/ void
+ public void
notifyCallForwardingIndicator() {
mNotifier.notifyCallForwardingChanged(this);
}
@@ -406,7 +447,7 @@ public class GSMPhone extends PhoneBase {
/**
* {@inheritDoc}
*/
- protected final void
+ public final void
setSystemProperty(String property, String value) {
super.setSystemProperty(property, value);
}
@@ -422,12 +463,12 @@ public class GSMPhone extends PhoneBase {
if (mSsnRegistrants.size() == 0) mCM.setSuppServiceNotifications(false, null);
}
- public void
+ public void
acceptCall() throws CallStateException {
mCT.acceptCall();
}
- public void
+ public void
rejectCall() throws CallStateException {
mCT.rejectCall();
}
@@ -437,7 +478,6 @@ public class GSMPhone extends PhoneBase {
mCT.switchWaitingOrHoldingAndActive();
}
-
public boolean canConference() {
return mCT.canConference();
}
@@ -451,7 +491,6 @@ public class GSMPhone extends PhoneBase {
}
public void clearDisconnected() {
-
mCT.clearDisconnected();
}
@@ -468,12 +507,12 @@ public class GSMPhone extends PhoneBase {
return mCT.foregroundCall;
}
- public GsmCall
+ public GsmCall
getBackgroundCall() {
return mCT.backgroundCall;
}
- public GsmCall
+ public GsmCall
getRingingCall() {
return mCT.ringingCall;
}
@@ -559,7 +598,7 @@ public class GSMPhone extends PhoneBase {
char ch = dialString.charAt(1);
int callIndex = ch - '0';
GsmConnection conn = mCT.getConnectionByIndex(call, callIndex);
-
+
// gsm index starts at 1, up to 5 connections in a call,
if (conn != null && callIndex >= 1 && callIndex <= GsmCallTracker.MAX_CONNECTIONS) {
if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 2: separate call "+
@@ -704,7 +743,7 @@ public class GSMPhone extends PhoneBase {
if (handleInCallMmiCommands(newDialString)) {
return null;
}
-
+
GsmMmiCode mmi = GsmMmiCode.newFromDialString(newDialString, this);
if (LOCAL_DEBUG) Log.d(LOG_TAG,
"dialing w/ mmi '" + mmi + "'...");
@@ -725,15 +764,15 @@ public class GSMPhone extends PhoneBase {
public boolean handlePinMmi(String dialString) {
GsmMmiCode mmi = GsmMmiCode.newFromDialString(dialString, this);
-
+
if (mmi != null && mmi.isPinCommand()) {
mPendingMMIs.add(mmi);
mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
mmi.processCode();
return true;
}
-
- return false;
+
+ return false;
}
public void sendUssdResponse(String ussdMessge) {
@@ -742,11 +781,11 @@ public class GSMPhone extends PhoneBase {
mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
mmi.sendUssd(ussdMessge);
}
-
+
public void
sendDtmf(char c) {
if (!PhoneNumberUtils.is12Key(c)) {
- Log.e(LOG_TAG,
+ Log.e(LOG_TAG,
"sendDtmf called with invalid character '" + c + "'");
} else {
if (mCT.state == Phone.State.OFFHOOK) {
@@ -790,7 +829,7 @@ public class GSMPhone extends PhoneBase {
com.android.internal.R.string.defaultVoiceMailAlphaTag).toString();
}
- return ret;
+ return ret;
}
public String getDeviceId() {
@@ -805,7 +844,7 @@ public class GSMPhone extends PhoneBase {
Log.e(LOG_TAG, "[GSMPhone] getEsn() is a CDMA method");
return "0";
}
-
+
public String getMeid() {
Log.e(LOG_TAG, "[GSMPhone] getMeid() is a CDMA method");
return "0";
@@ -845,7 +884,37 @@ public class GSMPhone extends PhoneBase {
Message onComplete) {
mSIMRecords.setVoiceMailNumber(alphaTag, voiceMailNumber, onComplete);
}
-
+
+ private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) {
+ switch (commandInterfaceCFReason) {
+ case CF_REASON_UNCONDITIONAL:
+ case CF_REASON_BUSY:
+ case CF_REASON_NO_REPLY:
+ case CF_REASON_NOT_REACHABLE:
+ case CF_REASON_ALL:
+ case CF_REASON_ALL_CONDITIONAL:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private boolean isValidCommandInterfaceCFAction (int commandInterfaceCFAction) {
+ switch (commandInterfaceCFAction) {
+ case CF_ACTION_DISABLE:
+ case CF_ACTION_ENABLE:
+ case CF_ACTION_REGISTRATION:
+ case CF_ACTION_ERASURE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ protected boolean isCfEnable(int action) {
+ return (action == CF_ACTION_ENABLE) || (action == CF_ACTION_REGISTRATION);
+ }
+
public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) {
if (LOCAL_DEBUG) Log.d(LOG_TAG, "requesting call forwarding query.");
@@ -859,11 +928,35 @@ public class GSMPhone extends PhoneBase {
}
}
+ public void setCallForwardingOption(int commandInterfaceCFAction,
+ int commandInterfaceCFReason,
+ String dialingNumber,
+ int timerSeconds,
+ Message onComplete) {
+ if ( (isValidCommandInterfaceCFAction(commandInterfaceCFAction)) &&
+ (isValidCommandInterfaceCFReason(commandInterfaceCFReason))) {
+
+ Message resp;
+ if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) {
+ resp = h.obtainMessage(EVENT_SET_CALL_FORWARD_DONE,
+ isCfEnable(commandInterfaceCFAction) ? 1 : 0, 0, onComplete);
+ } else {
+ resp = onComplete;
+ }
+ mCM.setCallForward(commandInterfaceCFAction,
+ commandInterfaceCFReason,
+ CommandsInterface.SERVICE_CLASS_VOICE,
+ dialingNumber,
+ timerSeconds,
+ resp);
+ }
+ }
+
public void getOutgoingCallerIdDisplay(Message onComplete) {
mCM.getCLIR(onComplete);
}
-
- public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
+
+ public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
Message onComplete) {
mCM.setCLIR(commandInterfaceCLIRMode,
h.obtainMessage(EVENT_SET_CLIR_COMPLETE, commandInterfaceCLIRMode, 0, onComplete));
@@ -872,13 +965,13 @@ public class GSMPhone extends PhoneBase {
public void getCallWaiting(Message onComplete) {
mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
}
-
+
public void setCallWaiting(boolean enable, Message onComplete) {
mCM.setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
}
-
+
public boolean
- getSimRecordsLoaded() {
+ getIccRecordsLoaded() {
return mSIMRecords.getRecordsLoaded();
}
@@ -886,86 +979,97 @@ public class GSMPhone extends PhoneBase {
return mSimCard;
}
- public void
+ public void
getAvailableNetworks(Message response) {
mCM.getAvailableNetworks(response);
}
/**
- * Small container class used to hold information relevant to
+ * Small container class used to hold information relevant to
* the carrier selection process. operatorNumeric can be ""
- * if we are looking for automatic selection.
+ * if we are looking for automatic selection.
*/
private static class NetworkSelectMessage {
public Message message;
public String operatorNumeric;
}
-
- public void
+
+ public void
setNetworkSelectionModeAutomatic(Message response) {
// wrap the response message in our own message along with
- // an empty string (to indicate automatic selection) for the
+ // an empty string (to indicate automatic selection) for the
// operator's id.
NetworkSelectMessage nsm = new NetworkSelectMessage();
nsm.message = response;
nsm.operatorNumeric = "";
-
+
// get the message
Message msg = h.obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
- if (LOCAL_DEBUG)
+ if (LOCAL_DEBUG)
Log.d(LOG_TAG, "wrapping and sending message to connect automatically");
mCM.setNetworkSelectionModeAutomatic(msg);
}
- public void
+ public void
selectNetworkManually(com.android.internal.telephony.gsm.NetworkInfo network,
- Message response) {
+ Message response) {
// wrap the response message in our own message along with
// the operator's id.
NetworkSelectMessage nsm = new NetworkSelectMessage();
nsm.message = response;
nsm.operatorNumeric = network.operatorNumeric;
-
+
// get the message
Message msg = h.obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
mCM.setNetworkSelectionModeManual(network.operatorNumeric, msg);
}
-
+
public void
getNeighboringCids(Message response) {
mCM.getNeighboringCids(response);
}
-
+
public void setOnPostDialCharacter(Handler h, int what, Object obj) {
mPostDialHandler = new Registrant(h, what, obj);
}
-
public void setMute(boolean muted) {
mCT.setMute(muted);
}
-
+
public boolean getMute() {
return mCT.getMute();
}
-
- public void invokeOemRilRequestRaw(byte[] data, Message response) {
- mCM.invokeOemRilRequestRaw(data, response);
+ /**
+ * @deprecated
+ */
+ public void getPdpContextList(Message response) {
+ getDataCallList(response);
}
- public void invokeOemRilRequestStrings(String[] strings, Message response) {
- mCM.invokeOemRilRequestStrings(strings, response);
+ public void getDataCallList(Message response) {
+ mCM.getDataCallList(response);
}
- public void getPdpContextList(Message response) {
- mCM.getPDPContextList(response);
+ /**
+ * @deprecated
+ */
+ public List<PdpConnection> getCurrentPdpList() {
+ ArrayList<DataConnection> connections = new ArrayList<DataConnection>();
+ ArrayList<PdpConnection> pdp_list = new ArrayList<PdpConnection>();
+
+ for(int n = 0; n < connections.size(); n++) {
+ pdp_list.add((PdpConnection) connections.get(n));
+ }
+
+ return pdp_list;
}
- public List<PdpConnection> getCurrentPdpList () {
- return mDataConnection.getAllPdps();
+ public List<DataConnection> getCurrentDataConnectionList () {
+ return mDataConnection.getAllDataConnections();
}
public void updateServiceLocation(Message response) {
@@ -980,14 +1084,6 @@ public class GSMPhone extends PhoneBase {
mSST.disableLocationUpdates();
}
- public void setBandMode(int bandMode, Message response) {
- mCM.setBandMode(bandMode, response);
- }
-
- public void queryAvailableBandMode(Message response) {
- mCM.queryAvailableBandMode(response);
- }
-
public boolean getDataRoamingEnabled() {
return mDataConnection.getDataOnRoamingEnabled();
}
@@ -1056,7 +1152,7 @@ public class GSMPhone extends PhoneBase {
*/
/*package*/ void
onMMIDone(GsmMmiCode mmi) {
- /* Only notify complete if it's on the pending list.
+ /* Only notify complete if it's on the pending list.
* Otherwise, it's already been handled (eg, previously canceled).
* The exception is cancellation of an incoming USSD-REQUEST, which is
* not on the list.
@@ -1068,7 +1164,7 @@ public class GSMPhone extends PhoneBase {
}
- private void
+ private void
onNetworkInitiatedUssd(GsmMmiCode mmi) {
mMmiCompleteRegistrants.notifyRegistrants(
new AsyncResult(null, mmi, null));
@@ -1080,14 +1176,14 @@ public class GSMPhone extends PhoneBase {
onIncomingUSSD (int ussdMode, String ussdMessage) {
boolean isUssdError;
boolean isUssdRequest;
-
- isUssdRequest
+
+ isUssdRequest
= (ussdMode == CommandsInterface.USSD_MODE_REQUEST);
- isUssdError
+ isUssdError
= (ussdMode != CommandsInterface.USSD_MODE_NOTIFY
&& ussdMode != CommandsInterface.USSD_MODE_REQUEST);
-
+
// See comments in GsmMmiCode.java
// USSD requests aren't finished until one
// of these two events happen
@@ -1114,7 +1210,7 @@ public class GSMPhone extends PhoneBase {
// also, discard if there is no message to present
if (!isUssdError && ussdMessage != null) {
GsmMmiCode mmi;
- mmi = GsmMmiCode.newNetworkInitiatedUssd(ussdMessage,
+ mmi = GsmMmiCode.newNetworkInitiatedUssd(ussdMessage,
isUssdRequest,
GSMPhone.this);
onNetworkInitiatedUssd(mmi);
@@ -1122,6 +1218,17 @@ public class GSMPhone extends PhoneBase {
}
}
+ /**
+ * Make sure the network knows our preferred setting.
+ */
+ protected void syncClirSetting() {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ int clirSetting = sp.getInt(CLIR_KEY, -1);
+ if (clirSetting >= 0) {
+ mCM.setCLIR(clirSetting, null);
+ }
+ }
+
//***** Inner Classes
class MyHandler extends Handler {
@@ -1197,11 +1304,10 @@ public class GSMPhone extends PhoneBase {
if (ar.exception != null) {
break;
}
-
+
mImeiSv = (String)ar.result;
break;
-
case EVENT_USSD:
ar = (AsyncResult)msg.obj;
@@ -1216,7 +1322,7 @@ public class GSMPhone extends PhoneBase {
}
break;
- case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
+ case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
// Some MMI requests (eg USSD) are not completed
// within the course of a CommandsInterface request
// If the radio shuts off or resets while one of these
@@ -1225,10 +1331,10 @@ public class GSMPhone extends PhoneBase {
for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) {
if (mPendingMMIs.get(i).isPendingUSSD()) {
mPendingMMIs.get(i).onUssdFinishedError();
- }
+ }
}
break;
-
+
case EVENT_SSN:
ar = (AsyncResult)msg.obj;
SuppServiceNotification not = (SuppServiceNotification) ar.result;
@@ -1258,15 +1364,15 @@ public class GSMPhone extends PhoneBase {
onComplete.sendToTarget();
}
break;
-
+
case EVENT_CALL_RING:
ar = (AsyncResult)msg.obj;
if (ar.exception == null) {
notifyIncomingRing();
}
break;
-
- // handle the select network completion callbacks.
+
+ // handle the select network completion callbacks.
case EVENT_SET_NETWORK_MANUAL_COMPLETE:
case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE:
handleSetSelectNetwork((AsyncResult) msg.obj);
@@ -1286,34 +1392,34 @@ public class GSMPhone extends PhoneBase {
}
}
}
-
+
/**
* Used to track the settings upon completion of the network change.
*/
private void handleSetSelectNetwork(AsyncResult ar) {
- // look for our wrapper within the asyncresult, skip the rest if it
- // is null.
+ // look for our wrapper within the asyncresult, skip the rest if it
+ // is null.
if (!(ar.userObj instanceof NetworkSelectMessage)) {
if (LOCAL_DEBUG) Log.d(LOG_TAG, "unexpected result from user object.");
return;
}
-
+
NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
-
+
// found the object, now we send off the message we had originally
- // attached to the request.
+ // attached to the request.
if (nsm.message != null) {
if (LOCAL_DEBUG) Log.d(LOG_TAG, "sending original message to recipient");
AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
nsm.message.sendToTarget();
}
-
+
// open the shared preferences editor, and write the value.
// nsm.operatorNumeric is "" if we're in automatic.selection.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor editor = sp.edit();
editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric);
-
+
// commit and log the result.
if (! editor.commit()) {
Log.e(LOG_TAG, "failed to commit network selection preference");
@@ -1321,6 +1427,22 @@ public class GSMPhone extends PhoneBase {
}
+ /**
+ * Saves CLIR setting so that we can re-apply it as necessary
+ * (in case the RIL resets it across reboots).
+ */
+ public void saveClirSetting(int commandInterfaceCLIRMode) {
+ // open the shared preferences editor, and write the value.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putInt(CLIR_KEY, commandInterfaceCLIRMode);
+
+ // commit and log the result.
+ if (! editor.commit()) {
+ Log.e(LOG_TAG, "failed to commit CLIR preference");
+ }
+ }
+
private void handleCfuQueryResult(CallForwardInfo[] infos) {
if (infos == null || infos.length == 0) {
// Assume the default is not active
@@ -1342,7 +1464,7 @@ public class GSMPhone extends PhoneBase {
* simulates various data connection states. This messes with
* DataConnectionTracker's internal states, but doesn't actually change
* the underlying radio connection states.
- *
+ *
* @param state Phone.DataState enum.
*/
public void simulateDataConnection(Phone.DataState state) {
@@ -1390,16 +1512,29 @@ public class GSMPhone extends PhoneBase {
/**
* {@inheritDoc}
- */
- protected Handler getHandler(){
+ */
+ public Handler getHandler(){
return h;
}
-
+
/**
* {@inheritDoc}
- */
- protected IccFileHandler getIccFileHandler(){
- return this.mIccFileHandler;
+ */
+ public IccFileHandler getIccFileHandler(){
+ return this.mIccFileHandler;
}
+
+ public void activateCellBroadcastSms(int activate, Message response) {
+ Log.e(LOG_TAG, "Error! This functionality is not implemented for GSM.");
+ }
+
+ public void getCellBroadcastSmsConfig(Message response) {
+ Log.e(LOG_TAG, "Error! This functionality is not implemented for GSM.");
+ }
+
+ public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){
+ Log.e(LOG_TAG, "Error! This functionality is not implemented for GSM.");
+ }
+
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCall.java b/telephony/java/com/android/internal/telephony/gsm/GsmCall.java
index 85529f581d12..1fe22bb06c43 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCall.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmCall.java
@@ -16,7 +16,12 @@
package com.android.internal.telephony.gsm;
-import com.android.internal.telephony.*;
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.CallStateException;
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.DriverCall;
+import com.android.internal.telephony.Phone;
+
import java.util.ArrayList;
import java.util.List;
@@ -29,7 +34,7 @@ class GsmCall extends Call {
/*package*/ ArrayList<Connection> connections = new ArrayList<Connection>();
/*package*/ GsmCallTracker owner;
-
+
/***************************** Class Methods *****************************/
static State
@@ -44,7 +49,7 @@ class GsmCall extends Call {
default: throw new RuntimeException ("illegal call state:" + dcState);
}
}
-
+
/****************************** Constructors *****************************/
/*package*/
@@ -52,6 +57,9 @@ class GsmCall extends Call {
this.owner = owner;
}
+ public void dispose() {
+ }
+
/************************** Overridden from Call *************************/
public List<Connection>
@@ -60,7 +68,7 @@ class GsmCall extends Call {
return connections;
}
- public Phone
+ public Phone
getPhone() {
//TODO
return null;
@@ -75,7 +83,7 @@ class GsmCall extends Call {
* background call exists, the background call will be resumed
* because an AT+CHLD=1 will be sent
*/
- public void
+ public void
hangup() throws CallStateException {
owner.hangup(this);
}
@@ -110,20 +118,20 @@ class GsmCall extends Call {
/* If only disconnected connections remain, we are disconnected*/
boolean hasOnlyDisconnectedConnections = true;
-
+
for (int i = 0, s = connections.size() ; i < s; i ++) {
- if (connections.get(i).getState()
+ if (connections.get(i).getState()
!= State.DISCONNECTED
) {
hasOnlyDisconnectedConnections = false;
break;
- }
+ }
}
if (hasOnlyDisconnectedConnections) {
- state = State.DISCONNECTED;
+ state = State.DISCONNECTED;
}
- }
+ }
}
@@ -140,9 +148,9 @@ class GsmCall extends Call {
update (GsmConnection conn, DriverCall dc) {
State newState;
boolean changed = false;
-
+
newState = stateFromDCState(dc.state);
-
+
if (newState != state) {
state = newState;
changed = true;
@@ -163,7 +171,7 @@ class GsmCall extends Call {
//***** Called from GsmCallTracker
- /**
+ /**
* Called when this Call is being hung up locally (eg, user pressed "end")
* Note that at this point, the hangup request has been dispatched to the radio
* but no response has yet been received so update() has not yet been called
@@ -178,7 +186,7 @@ class GsmCall extends Call {
cn.onHangupLocal();
}
}
-
+
/**
* Called when it's time to clean up disconnected Connection objects
*/
@@ -186,11 +194,11 @@ class GsmCall extends Call {
clearDisconnected() {
for (int i = connections.size() - 1 ; i >= 0 ; i--) {
GsmConnection cn = (GsmConnection)connections.get(i);
-
+
if (cn.getState() == State.DISCONNECTED) {
connections.remove(i);
}
- }
+ }
if (connections.size() == 0) {
state = State.IDLE;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
index 4a8e88a050bc..9f018ad0a6ea 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
@@ -16,24 +16,23 @@
package com.android.internal.telephony.gsm;
+import android.os.*;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
+import android.util.Log;
+
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CallTracker;
import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.gsm.CallFailCause;
-import com.android.internal.telephony.gsm.CommandException;
import com.android.internal.telephony.DriverCall;
+import com.android.internal.telephony.gsm.CallFailCause;
import com.android.internal.telephony.gsm.GsmCall;
import com.android.internal.telephony.gsm.GsmConnection;
import com.android.internal.telephony.gsm.GSMPhone;
+import com.android.internal.telephony.Phone;
import com.android.internal.telephony.*;
-import android.os.*;
-import android.util.Log;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-
import java.util.List;
import java.util.ArrayList;
@@ -45,24 +44,23 @@ public final class GsmCallTracker extends CallTracker {
private static final boolean REPEAT_POLLING = false;
private static final boolean DBG_POLL = false;
-
+
//***** Constants
static final int MAX_CONNECTIONS = 7; // only 7 connections allowed in GSM
static final int MAX_CONNECTIONS_PER_CALL = 5; // only 5 connections allowed per call
//***** Instance Variables
-
GsmConnection connections[] = new GsmConnection[MAX_CONNECTIONS];
RegistrantList voiceCallEndedRegistrants = new RegistrantList();
RegistrantList voiceCallStartedRegistrants = new RegistrantList();
// connections dropped durin last poll
- ArrayList<GsmConnection> droppedDuringPoll
- = new ArrayList<GsmConnection>(MAX_CONNECTIONS);
+ ArrayList<GsmConnection> droppedDuringPoll
+ = new ArrayList<GsmConnection>(MAX_CONNECTIONS);
- GsmCall ringingCall = new GsmCall(this);
+ GsmCall ringingCall = new GsmCall(this);
// A call that is ringing or (call) waiting
GsmCall foregroundCall = new GsmCall(this);
GsmCall backgroundCall = new GsmCall(this);
@@ -93,6 +91,33 @@ public final class GsmCallTracker extends CallTracker {
cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
}
+ public void dispose() {
+ //Unregister for all events
+ cm.unregisterForCallStateChanged(this);
+ cm.unregisterForOn(this);
+ cm.unregisterForNotAvailable(this);
+
+ for(GsmConnection c : connections) {
+ try {
+ if(c != null) hangup(c);
+ } catch (CallStateException ex) {
+ Log.e(LOG_TAG, "unexpected error on hangup during dispose");
+ }
+ }
+
+ try {
+ if(pendingMO != null) hangup(pendingMO);
+ } catch (CallStateException ex) {
+ Log.e(LOG_TAG, "unexpected error on hangup during dispose");
+ }
+
+ clearDisconnected();
+ }
+
+ protected void finalize() {
+ Log.d(LOG_TAG, "GsmCallTracker finalized");
+ }
+
//***** Instance Methods
//***** Public Methods
@@ -101,11 +126,19 @@ public final class GsmCallTracker extends CallTracker {
voiceCallStartedRegistrants.add(r);
}
+ public void unregisterForVoiceCallStarted(Handler h) {
+ voiceCallStartedRegistrants.remove(h);
+ }
+
public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
voiceCallEndedRegistrants.add(r);
}
+ public void unregisterForVoiceCallEnded(Handler h) {
+ voiceCallEndedRegistrants.remove(h);
+ }
+
private void
fakeHoldForegroundBeforeDial() {
List<Connection> connCopy;
@@ -143,13 +176,13 @@ public final class GsmCallTracker extends CallTracker {
// for the newly dialed connection
switchWaitingOrHoldingAndActive();
- // Fake local state so that
+ // 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() != GsmCall.State.IDLE) {
//we should have failed in !canDial() above before we get here
throw new CallStateException("cannot dial in current state");
@@ -165,22 +198,22 @@ public final class GsmCallTracker extends CallTracker {
pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
// handlePollCalls() will notice this call not present
- // and will mark it as dropped.
+ // and will mark it as dropped.
pollCallsWhenSafe();
} else {
// Always unmute when initiating a new call
setMute(false);
- cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
+ cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
}
updatePhoneState();
phone.notifyCallStateChanged();
-
+
return pendingMO;
}
-
+
Connection
dial (String dialString) throws CallStateException {
return dial(dialString, CommandsInterface.CLIR_DEFAULT);
@@ -191,7 +224,7 @@ public final class GsmCallTracker extends CallTracker {
// FIXME if SWITCH fails, should retry with ANSWER
// in case the active/holding call disappeared and this
// is no longer call waiting
-
+
if (ringingCall.getState() == GsmCall.State.INCOMING) {
Log.i("phone", "acceptCall: incoming...");
// Always unmute when answering a new call
@@ -236,7 +269,7 @@ public final class GsmCallTracker extends CallTracker {
explicitCallTransfer() throws CallStateException {
cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
}
-
+
void
clearDisconnected() {
internalClearDisconnected();
@@ -245,7 +278,7 @@ public final class GsmCallTracker extends CallTracker {
phone.notifyCallStateChanged();
}
- boolean
+ boolean
canConference() {
return foregroundCall.getState() == GsmCall.State.ACTIVE
&& backgroundCall.getState() == GsmCall.State.HOLDING
@@ -274,16 +307,14 @@ public final class GsmCallTracker extends CallTracker {
}
//***** Private Instance Methods
-
+
private void
internalClearDisconnected() {
ringingCall.clearDisconnected();
foregroundCall.clearDisconnected();
- backgroundCall.clearDisconnected();
+ backgroundCall.clearDisconnected();
}
-
-
/**
* Obtain a message to use for signalling "invoke getCurrentCalls() when
* this operation and all other pending operations are complete
@@ -312,26 +343,24 @@ public final class GsmCallTracker extends CallTracker {
private void
operationComplete() {
pendingOperations--;
-
+
if (DBG_POLL) log("operationComplete: pendingOperations=" +
pendingOperations + ", needsPoll=" + needsPoll);
if (pendingOperations == 0 && needsPoll) {
lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
- cm.getCurrentCalls(lastRelevantPoll);
+ cm.getCurrentCalls(lastRelevantPoll);
} else if (pendingOperations < 0) {
// this should never happen
Log.e(LOG_TAG,"GsmCallTracker.pendingOperations < 0");
pendingOperations = 0;
}
}
-
-
private void
updatePhoneState() {
Phone.State oldState = state;
-
+
if (ringingCall.isRinging()) {
state = Phone.State.RINGING;
} else if (pendingMO != null ||
@@ -339,7 +368,7 @@ public final class GsmCallTracker extends CallTracker {
state = Phone.State.OFFHOOK;
} else {
state = Phone.State.IDLE;
- }
+ }
if (state == Phone.State.IDLE && oldState != state) {
voiceCallEndedRegistrants.notifyRegistrants(
@@ -377,7 +406,7 @@ public final class GsmCallTracker extends CallTracker {
boolean needsPollDelay = false;
boolean unknownConnectionAppeared = false;
- for (int i = 0, curDC = 0, dcSize = polledCalls.size()
+ for (int i = 0, curDC = 0, dcSize = polledCalls.size()
; i < connections.length; i++) {
GsmConnection conn = connections[i];
DriverCall dc = null;
@@ -434,7 +463,7 @@ public final class GsmCallTracker extends CallTracker {
// which is neither a ringing call or one we created.
// Either we've crashed and re-attached to an existing
// call, or something else (eg, SIM) initiated the call.
-
+
Log.i(LOG_TAG,"Phantom call appeared " + dc);
// If it's a connected call, set the connect time so that
@@ -451,8 +480,8 @@ public final class GsmCallTracker extends CallTracker {
hasNonHangupStateChanged = true;
} else if (conn != null && dc == null) {
// Connection missing in CLCC response that we were
- // tracking.
- droppedDuringPoll.add(conn);
+ // tracking.
+ droppedDuringPoll.add(conn);
// Dropped connections are removed from the CallTracker
// list but kept in the GsmCall list
connections[i] = null;
@@ -460,7 +489,7 @@ public final class GsmCallTracker extends CallTracker {
// Connection in CLCC response does not match what
// we were tracking. Assume dropped call and new call
- droppedDuringPoll.add(conn);
+ droppedDuringPoll.add(conn);
connections[i] = new GsmConnection (dc, this, i);
if (connections[i].getCall() == ringingCall) {
@@ -496,11 +525,11 @@ public final class GsmCallTracker extends CallTracker {
// This is the first poll after an ATD.
// We expect the pending call to appear in the list
// If it does not, we land here
- if (pendingMO != null) {
- Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
+ if (pendingMO != null) {
+ Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
+ foregroundCall.getState());
- droppedDuringPoll.add(pendingMO);
+ droppedDuringPoll.add(pendingMO);
pendingMO = null;
hangupPendingMO = false;
}
@@ -521,7 +550,7 @@ public final class GsmCallTracker extends CallTracker {
if (conn.cause == Connection.DisconnectCause.LOCAL) {
cause = Connection.DisconnectCause.INCOMING_REJECTED;
} else {
- cause = Connection.DisconnectCause.INCOMING_MISSED;
+ cause = Connection.DisconnectCause.INCOMING_MISSED;
}
if (Phone.DEBUG_PHONE) {
@@ -584,7 +613,7 @@ public final class GsmCallTracker extends CallTracker {
private void
dumpState() {
List l;
-
+
Log.i(LOG_TAG,"Phone State:" + state);
Log.i(LOG_TAG,"Ringing call: " + ringingCall.toString());
@@ -615,7 +644,7 @@ public final class GsmCallTracker extends CallTracker {
/*package*/ void
hangup (GsmConnection conn) throws CallStateException {
if (conn.owner != this) {
- throw new CallStateException ("GsmConnection " + conn
+ throw new CallStateException ("GsmConnection " + conn
+ "does not belong to GsmCallTracker " + this);
}
@@ -624,14 +653,14 @@ public final class GsmCallTracker extends CallTracker {
// GSM index assigned yet
if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
- hangupPendingMO = true;
+ hangupPendingMO = true;
} else {
- try {
+ try {
cm.hangupConnection (conn.getGSMIndex(), obtainCompleteMessage());
} catch (CallStateException ex) {
// Ignore "connection not found"
// Call may have hung up already
- Log.w(LOG_TAG,"GsmCallTracker WARN: hangup() on absent connection "
+ Log.w(LOG_TAG,"GsmCallTracker WARN: hangup() on absent connection "
+ conn);
}
}
@@ -642,16 +671,16 @@ public final class GsmCallTracker extends CallTracker {
/*package*/ void
separate (GsmConnection conn) throws CallStateException {
if (conn.owner != this) {
- throw new CallStateException ("GsmConnection " + conn
+ throw new CallStateException ("GsmConnection " + conn
+ "does not belong to GsmCallTracker " + this);
}
try {
- cm.separateConnection (conn.getGSMIndex(),
+ cm.separateConnection (conn.getGSMIndex(),
obtainCompleteMessage(EVENT_SEPARATE_RESULT));
} catch (CallStateException ex) {
// Ignore "connection not found"
// Call may have hung up already
- Log.w(LOG_TAG,"GsmCallTracker WARN: separate() on absent connection "
+ Log.w(LOG_TAG,"GsmCallTracker WARN: separate() on absent connection "
+ conn);
}
}
@@ -663,13 +692,13 @@ public final class GsmCallTracker extends CallTracker {
desiredMute = mute;
cm.setMute(desiredMute, null);
}
-
+
/*package*/ boolean
getMute() {
return desiredMute;
}
-
+
//***** Called from GsmCall
/* package */ void
@@ -775,10 +804,10 @@ public final class GsmCallTracker extends CallTracker {
//****** Overridden from Handler
- public void
+ public void
handleMessage (Message msg) {
AsyncResult ar;
-
+
switch (msg.what) {
case EVENT_POLL_CALLS_RESULT:
ar = (AsyncResult)msg.obj;
@@ -812,7 +841,7 @@ public final class GsmCallTracker extends CallTracker {
int causeCode;
ar = (AsyncResult)msg.obj;
- operationComplete();
+ operationComplete();
if (ar.exception != null) {
// An exception occurred...just treat the disconnect
@@ -823,7 +852,7 @@ public final class GsmCallTracker extends CallTracker {
} else {
causeCode = ((int[])ar.result)[0];
}
-
+
for (int i = 0, s = droppedDuringPoll.size()
; i < s ; i++
) {
@@ -853,7 +882,7 @@ public final class GsmCallTracker extends CallTracker {
}
}
- private void log(String msg) {
+ protected void log(String msg) {
Log.d(LOG_TAG, "[GsmCallTracker] " + msg);
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
index 2a46f77e616d..997777e6f370 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
@@ -16,18 +16,19 @@
package com.android.internal.telephony.gsm;
-import com.android.internal.telephony.*;
+import android.os.AsyncResult;
import android.os.Handler;
-import android.os.Registrant;
import android.os.Looper;
import android.os.Message;
-import android.os.AsyncResult;
+import android.os.Registrant;
import android.os.SystemClock;
-import android.util.Log;
import android.util.Config;
+import android.util.Log;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
+import com.android.internal.telephony.*;
+
/**
* {@hide}
*/
@@ -41,9 +42,9 @@ public class GsmConnection extends Connection {
String address; // MAY BE NULL!!!
String dialString; // outgoing calls only
- String postDialString; // outgoing calls only
+ String postDialString; // outgoing calls only
boolean isIncoming;
- boolean disconnected;
+ boolean disconnected;
int index; // index in GsmCallTracker.connections[], -1 if unassigned
// The GSM index is 1 + this
@@ -63,7 +64,7 @@ public class GsmConnection extends Connection {
*/
long connectTimeReal;
long duration;
- long holdingStartTime; // The time when the Connection last transitioned
+ long holdingStartTime; // The time when the Connection last transitioned
// into HOLDING
int nextPostDialChar; // index into postDialString
@@ -91,6 +92,7 @@ public class GsmConnection extends Connection {
public void
handleMessage(Message msg) {
+
switch (msg.what) {
case EVENT_NEXT_POST_DIAL:
case EVENT_DTMF_DONE:
@@ -140,7 +142,10 @@ public class GsmConnection extends Connection {
this.parent = parent;
parent.attachFake(this, GsmCall.State.DIALING);
}
-
+
+ public void dispose() {
+ }
+
static boolean
equalsHandlesNulls (Object a, Object b) {
return (a == null) ? (b == null) : a.equals (b);
@@ -159,7 +164,7 @@ public class GsmConnection extends Connection {
// no control over when they begin, so we might as well
String cAddress = PhoneNumberUtils.stringFromStringAndTOA(c.number, c.TOA);
- return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
+ return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
}
public String
@@ -168,10 +173,9 @@ public class GsmConnection extends Connection {
}
public String getAddress() {
- return address;
+ return address;
}
-
public GsmCall getCall() {
return parent;
}
@@ -218,13 +222,13 @@ public class GsmConnection extends Connection {
public GsmCall.State getState() {
if (disconnected) {
return GsmCall.State.DISCONNECTED;
- } else {
+ } else {
return super.getState();
}
}
public void hangup() throws CallStateException {
- if (!disconnected) {
+ if (!disconnected) {
owner.hangup(this);
} else {
throw new CallStateException ("disconnected");
@@ -232,7 +236,7 @@ public class GsmConnection extends Connection {
}
public void separate() throws CallStateException {
- if (!disconnected) {
+ if (!disconnected) {
owner.separate(this);
} else {
throw new CallStateException ("disconnected");
@@ -245,7 +249,7 @@ public class GsmConnection extends Connection {
public void proceedAfterWaitChar() {
if (postDialState != PostDialState.WAIT) {
- Log.w(LOG_TAG, "GsmConnection.proceedAfterWaitChar(): Expected "
+ Log.w(LOG_TAG, "GsmConnection.proceedAfterWaitChar(): Expected "
+ "getPostDialState() to be WAIT but was " + postDialState);
return;
}
@@ -254,10 +258,10 @@ public class GsmConnection extends Connection {
processNextPostDialChar();
}
-
+
public void proceedAfterWildChar(String str) {
if (postDialState != PostDialState.WILD) {
- Log.w(LOG_TAG, "GsmConnection.proceedAfterWaitChar(): Expected "
+ Log.w(LOG_TAG, "GsmConnection.proceedAfterWaitChar(): Expected "
+ "getPostDialState() to be WILD but was " + postDialState);
return;
}
@@ -294,22 +298,22 @@ public class GsmConnection extends Connection {
postDialString = buf.toString();
nextPostDialChar = 0;
if (Phone.DEBUG_PHONE) {
- log("proceedAfterWildChar: new postDialString is " +
+ log("proceedAfterWildChar: new postDialString is " +
postDialString);
}
processNextPostDialChar();
}
}
-
+
public void cancelPostDial() {
postDialState = PostDialState.CANCELLED;
}
- /**
+ /**
* Called when this Connection is being hung up locally (eg, user pressed "end")
* Note that at this point, the hangup request has been dispatched to the radio
- * but no response has yet been received so update() has not yet been called
+ * but no response has yet been received so update() has not yet been called
*/
void
onHangupLocal() {
@@ -322,7 +326,7 @@ public class GsmConnection extends Connection {
* See 22.001 Annex F.4 for mapping of cause codes
* to local tones
*/
-
+
switch (causeCode) {
case CallFailCause.USER_BUSY:
return DisconnectCause.BUSY;
@@ -345,7 +349,7 @@ public class GsmConnection extends Connection {
return DisconnectCause.FDN_BLOCKED;
case CallFailCause.ERROR_UNSPECIFIED:
- case CallFailCause.NORMAL_CLEARING:
+ case CallFailCause.NORMAL_CLEARING:
default:
GSMPhone phone = owner.phone;
int serviceState = phone.getServiceState().getState();
@@ -355,7 +359,7 @@ public class GsmConnection extends Connection {
|| serviceState == ServiceState.STATE_EMERGENCY_ONLY ) {
return DisconnectCause.OUT_OF_SERVICE;
} else if (phone.getIccCard().getState() != SimCard.State.READY) {
- return DisconnectCause.SIM_ERROR;
+ return DisconnectCause.ICC_ERROR;
} else {
return DisconnectCause.NORMAL;
}
@@ -371,10 +375,10 @@ public class GsmConnection extends Connection {
/*package*/ void
onDisconnect(DisconnectCause cause) {
this.cause = cause;
-
- if (!disconnected) {
+
+ if (!disconnected) {
index = -1;
-
+
disconnectTime = System.currentTimeMillis();
duration = SystemClock.elapsedRealtime() - connectTimeReal;
disconnected = true;
@@ -385,7 +389,7 @@ public class GsmConnection extends Connection {
owner.phone.notifyDisconnect(this);
if (parent != null) {
- parent.connectionDisconnected(this);
+ parent.connectionDisconnected(this);
}
}
}
@@ -506,21 +510,21 @@ public class GsmConnection extends Connection {
} 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
+ // "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...."
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),
+ 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
+ // "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),
+ h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
PAUSE_DELAY_MILLIS);
}
} else if (c == PhoneNumberUtils.WAIT) {
@@ -536,7 +540,7 @@ public class GsmConnection extends Connection {
public String
getRemainingPostDialString() {
- if (postDialState == PostDialState.CANCELLED
+ if (postDialState == PostDialState.CANCELLED
|| postDialState == PostDialState.COMPLETE
|| postDialString == null
|| postDialString.length() <= nextPostDialChar
@@ -546,7 +550,7 @@ public class GsmConnection extends Connection {
return postDialString.substring(nextPostDialChar);
}
-
+
private void
processNextPostDialChar() {
char c = 0;
@@ -565,7 +569,7 @@ public class GsmConnection extends Connection {
c = 0;
} else {
boolean isValid;
-
+
postDialState = PostDialState.STARTED;
c = postDialString.charAt(nextPostDialChar++);
@@ -585,7 +589,8 @@ public class GsmConnection extends Connection {
Message notifyMessage;
- if (postDialHandler != null && (notifyMessage = postDialHandler.messageForRegistrant()) != null) {
+ if (postDialHandler != null
+ && (notifyMessage = postDialHandler.messageForRegistrant()) != null) {
// The AsyncResult.result is the Connection object
PostDialState state = postDialState;
AsyncResult ar = AsyncResult.forMessage(notifyMessage);
@@ -598,15 +603,6 @@ public class GsmConnection extends Connection {
//Log.v("GSM", "##### processNextPostDialChar: send msg to postDialHandler, arg1=" + c);
notifyMessage.sendToTarget();
}
-//moved indent due to maximum character length
-/*
-else {
-if (postDialHandler == null)
-Log.v("GSM", "##### processNextPostDialChar: postDialHandler is NULL!");
-else
-Log.v("GSM", "##### processNextPostDialChar: postDialHandler.messageForRegistrant() returned NULL!");
-}
-*/
}
@@ -615,8 +611,8 @@ Log.v("GSM", "##### processNextPostDialChar: postDialHandler.messageForRegistran
*/
private boolean
isConnectingInOrOut() {
- return parent == null || parent == owner.ringingCall
- || parent.state == GsmCall.State.DIALING
+ return parent == null || parent == owner.ringingCall
+ || parent.state == GsmCall.State.DIALING
|| parent.state == GsmCall.State.ALERTING;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 63d145edabf4..e9d1eb3b7026 100644
--- a/telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -39,57 +39,28 @@ import android.preference.PreferenceManager;
import android.provider.Checkin;
import android.provider.Settings;
import android.provider.Telephony;
-import android.provider.Settings.SettingNotFoundException;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.gsm.PdpConnection.PdpFailCause;
-
import android.telephony.ServiceState;
import android.util.EventLog;
import android.util.Log;
import android.text.TextUtils;
+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 java.io.IOException;
import java.util.ArrayList;
/**
* {@hide}
*/
-final class DataConnectionTracker extends Handler
-{
+public final class GsmDataConnectionTracker extends DataConnectionTracker {
private static final String LOG_TAG = "GSM";
private static final boolean DBG = true;
/**
- * IDLE: ready to start data connection setup, default state
- * INITING: state of issued setupDefaultPDP() but not finish yet
- * CONNECTING: state of issued startPppd() but not finish yet
- * SCANNING: data connection fails with one apn but other apns are available
- * ready to start data connection on other apns (before INITING)
- * CONNECTED: IP connection is setup
- * FAILED: data connection fail for all apns settings
- *
- * getDataConnectionState() maps State to DataState
- * FAILED or IDLE : DISCONNECTED
- * INITING or CONNECTING or SCANNING: CONNECTING
- * CONNECTED : CONNECTED
- */
- enum State {
- IDLE,
- INITING,
- CONNECTING,
- SCANNING,
- CONNECTED,
- FAILED
- }
-
- enum Activity {
- NONE,
- DATAIN,
- DATAOUT,
- DATAINANDOUT
- }
-
- /**
* Handles changes to the APN db.
*/
private class ApnChangeObserver extends ContentObserver {
@@ -112,19 +83,14 @@ final class DataConnectionTracker extends Handler
//***** Instance Variables
- GSMPhone phone;
INetStatService netstat;
- State state = State.IDLE;
- Activity activity = Activity.NONE;
- boolean netStatPollEnabled = false;
// Indicates baseband will not auto-attach
private boolean noAutoAttach = false;
long nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
- Handler mDataConnectionTracker = null;
private ContentResolver mResolver;
+ private IntentFilter filterS;
+ private IntentFilter filter;
- int txPkts, rxPkts, sentSinceLastRecv, netStatPollPeriod;
- private int mNoRecvPollCount = 0;
private boolean mPingTestActive = false;
// Count of PDP reset attempts; reset when we see incoming,
// call reRegisterNetwork, or pingTest succeeds.
@@ -152,11 +118,11 @@ final class DataConnectionTracker extends Handler
/**
* pdpList holds all the PDP connection, i.e. IP Link in GPRS
*/
- private ArrayList<PdpConnection> pdpList;
+ private ArrayList<DataConnection> pdpList;
/** CID of active PDP */
int cidActive;
-
+
/** Currently requested APN type */
private String mRequestedApnType = Phone.APN_TYPE_DEFAULT;
@@ -182,39 +148,6 @@ final class DataConnectionTracker extends Handler
private static final int PDP_CONNECTION_POOL_SIZE = 1;
private static final int POLL_PDP_MILLIS = 5 * 1000;
- private static final int RECONNECT_DELAY_INITIAL_MILLIS = 5 * 1000;
-
- /** Slow poll when attempting connection recovery. */
- private static final int POLL_NETSTAT_SLOW_MILLIS = 5000;
-
- /** Default ping deadline, in seconds. */
- private final int DEFAULT_PING_DEADLINE = 5;
- /** Default max failure count before attempting to network re-registration. */
- private final int DEFAULT_MAX_PDP_RESET_FAIL = 3;
-
- /**
- * After detecting a potential connection problem, this is the max number
- * of subsequent polls before attempting a radio reset. At this point,
- * poll interval is 5 seconds (POLL_NETSTAT_SLOW_MILLIS), so set this to
- * poll for about 2 more minutes.
- */
- private static final int NO_RECV_POLL_LIMIT = 24;
-
- // 1 sec. default polling interval when screen is on.
- private static final int POLL_NETSTAT_MILLIS = 1000;
- // 10 min. default polling interval when screen is off.
- private static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
- // 2 min for round trip time
- private static final int POLL_LONGEST_RTT = 120 * 1000;
- // 10 for packets without ack
- private static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
- // how long to wait before switching back to default APN
- private static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000;
- // system property that can override the above value
- private static final String APN_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore";
- // represents an invalid IP address
- private static final String NULL_IP = "0.0.0.0";
-
static final String INTENT_RECONNECT_ALARM = "com.android.internal.telephony.gprs-reconnect";
//***** Tag IDs for EventLog
@@ -223,32 +156,8 @@ final class DataConnectionTracker extends Handler
private static final int EVENT_LOG_PDP_RESET = 50103;
private static final int EVENT_LOG_REREGISTER_NETWORK = 50104;
- //***** Event Codes
- static final int EVENT_DATA_SETUP_COMPLETE = 1;
- static final int EVENT_RADIO_AVAILABLE = 3;
- static final int EVENT_RECORDS_LOADED = 4;
- static final int EVENT_TRY_SETUP_DATA = 5;
- static final int EVENT_PDP_STATE_CHANGED = 6;
- static final int EVENT_POLL_PDP = 7;
- static final int EVENT_GET_PDP_LIST_COMPLETE = 11;
- static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 12;
- static final int EVENT_VOICE_CALL_STARTED = 14;
- static final int EVENT_VOICE_CALL_ENDED = 15;
- static final int EVENT_GPRS_DETACHED = 19;
- static final int EVENT_LINK_STATE_CHANGED = 20;
- static final int EVENT_ROAMING_ON = 21;
- static final int EVENT_ROAMING_OFF = 22;
- static final int EVENT_ENABLE_NEW_APN = 23;
- static final int EVENT_RESTORE_DEFAULT_APN = 24;
- static final int EVENT_DISCONNECT_DONE = 25;
- static final int EVENT_GPRS_ATTACHED = 26;
- static final int EVENT_START_NETSTAT_POLL = 27;
- static final int EVENT_START_RECOVERY = 28;
-
- BroadcastReceiver screenOnOffReceiver = new BroadcastReceiver ()
- {
- public void onReceive(Context context, Intent intent)
- {
+ BroadcastReceiver screenOnOffReceiver = new BroadcastReceiver () {
+ public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
mIsScreenOn = true;
stopNetStatPoll();
@@ -258,7 +167,8 @@ final class DataConnectionTracker extends Handler
stopNetStatPoll();
startNetStatPoll();
} else {
- Log.w(LOG_TAG, "DataConnectionTracker received unexpected Intent: " + intent.getAction());
+ Log.w(LOG_TAG, "DataConnectionTracker received unexpected Intent: "
+ + intent.getAction());
}
}
};
@@ -266,8 +176,7 @@ final class DataConnectionTracker extends Handler
BroadcastReceiver alarmReceiver
= new BroadcastReceiver () {
- public void onReceive(Context context, Intent intent)
- {
+ public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "GPRS reconnect alarm. Previous state was " + state);
if (state == State.FAILED) {
@@ -283,37 +192,37 @@ final class DataConnectionTracker extends Handler
//***** Constructor
- DataConnectionTracker(GSMPhone phone)
- {
- this.phone = phone;
- phone.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
- phone.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- phone.mSIMRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
- phone.mCM.registerForPDPStateChanged (this, EVENT_PDP_STATE_CHANGED, null);
- phone.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
- phone.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
- phone.mSST.registerForGprsAttached(this, EVENT_GPRS_ATTACHED, null);
- phone.mSST.registerForGprsDetached(this, EVENT_GPRS_DETACHED, null);
- phone.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null);
- phone.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
+ GsmDataConnectionTracker(GSMPhone p) {
+ super(p);
+
+ p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
+ p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
+ p.mSIMRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
+ p.mCM.registerForDataStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
+ p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
+ p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
+ p.mSST.registerForGprsAttached(this, EVENT_GPRS_ATTACHED, null);
+ p.mSST.registerForGprsDetached(this, EVENT_GPRS_DETACHED, null);
+ p.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null);
+ p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
this.netstat = INetStatService.Stub.asInterface(ServiceManager.getService("netstat"));
- IntentFilter filter = new IntentFilter();
+ this.filter = new IntentFilter();
filter.addAction(INTENT_RECONNECT_ALARM);
- phone.getContext().registerReceiver(
- alarmReceiver, filter, null, phone.h);
+ p.getContext().registerReceiver(
+ alarmReceiver, filter, null, phone.getHandler());
- IntentFilter filterS = new IntentFilter();
+ this.filterS = new IntentFilter();
filterS.addAction(Intent.ACTION_SCREEN_ON);
filterS.addAction(Intent.ACTION_SCREEN_OFF);
- phone.getContext().registerReceiver(screenOnOffReceiver, filterS);
+ p.getContext().registerReceiver(screenOnOffReceiver, filterS);
mDataConnectionTracker = this;
mResolver = phone.getContext().getContentResolver();
apnObserver = new ApnChangeObserver();
- phone.getContext().getContentResolver().registerContentObserver(
+ p.getContext().getContentResolver().registerContentObserver(
Telephony.Carriers.CONTENT_URI, true, apnObserver);
createAllPdpList();
@@ -325,6 +234,30 @@ final class DataConnectionTracker extends Handler
noAutoAttach = !dataEnabled[APN_DEFAULT_ID];
}
+ public void dispose() {
+ //Unregister for all events
+ phone.mCM.unregisterForAvailable(this);
+ phone.mCM.unregisterForOffOrNotAvailable(this);
+ ((GSMPhone) phone).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);
+
+ phone.getContext().unregisterReceiver(this.alarmReceiver);
+ phone.getContext().unregisterReceiver(this.screenOnOffReceiver);
+ phone.getContext().getContentResolver().unregisterContentObserver(this.apnObserver);
+
+ destroyAllPdpList();
+ }
+
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "GsmDataConnectionTracker finalized");
+ }
+
void setState(State s) {
if (state != s) {
if (s == State.INITING) { // request PDP context
@@ -347,7 +280,7 @@ final class DataConnectionTracker extends Handler
waitingApns.clear(); // when teardown the connection and set to IDLE
}
}
- String[] getActiveApnTypes() {
+ protected String[] getActiveApnTypes() {
String[] result;
if (mActiveApn != null) {
result = mActiveApn.types;
@@ -358,7 +291,7 @@ final class DataConnectionTracker extends Handler
return result;
}
- String getActiveApnString() {
+ protected String getActiveApnString() {
String result = null;
if (mActiveApn != null) {
result = mActiveApn.apn;
@@ -376,7 +309,7 @@ final class DataConnectionTracker extends Handler
* will be sent by the ConnectivityManager when a connection to
* the APN has been established.
*/
- int enableApnType(String type) {
+ protected int enableApnType(String type) {
if (!TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
return Phone.APN_REQUEST_FAILED;
}
@@ -414,7 +347,7 @@ final class DataConnectionTracker extends Handler
* @param type the APN type. The only valid value currently is {@link Phone#APN_TYPE_MMS}.
* @return
*/
- int disableApnType(String type) {
+ protected int disableApnType(String type) {
Log.d(LOG_TAG, "disableApnType("+type+")");
if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
removeMessages(EVENT_RESTORE_DEFAULT_APN);
@@ -440,7 +373,7 @@ final class DataConnectionTracker extends Handler
return Phone.APN_REQUEST_FAILED;
}
}
-
+
private boolean isApnTypeActive(String type) {
// TODO: to support simultaneous, mActiveApn can be a List instead.
return mActiveApn != null && mActiveApn.canHandleType(type);
@@ -477,7 +410,7 @@ final class DataConnectionTracker extends Handler
Log.d(LOG_TAG, "dataEnabled[DEFAULT_APN]=" + dataEnabled[APN_DEFAULT_ID] +
" dataEnabled[MMS_APN]=" + dataEnabled[APN_MMS_ID]);
}
-
+
/**
* Prevent mobile data connections from being established,
* or once again allow mobile data connections. If the state
@@ -506,8 +439,10 @@ final class DataConnectionTracker extends Handler
return true;
}
return false;
- } else // isEnabled && enable
+ } else {
+ // isEnabled && enable
return true;
+ }
}
/**
@@ -529,31 +464,11 @@ final class DataConnectionTracker extends Handler
return dataEnabled[APN_DEFAULT_ID] || dataEnabled[APN_MMS_ID];
}
- //The data roaming setting is now located in the shared preferences.
- // See if the requested preference value is the same as that stored in
- // the shared values. If it is not, then update it.
- public void setDataOnRoamingEnabled(boolean enabled) {
- if (getDataOnRoamingEnabled() != enabled) {
- Settings.System.putInt(phone.getContext().getContentResolver(),
- Settings.System.DATA_ROAMING, enabled ? 1 : 0);
- }
- Message roamingMsg = phone.getServiceState().getRoaming() ?
- obtainMessage(EVENT_ROAMING_ON) : obtainMessage(EVENT_ROAMING_OFF);
- sendMessage(roamingMsg);
- }
-
- //Retrieve the data roaming setting from the shared preferences.
- public boolean getDataOnRoamingEnabled() {
- try {
- return Settings.System.getInt(phone.getContext().getContentResolver(),
- Settings.System.DATA_ROAMING) > 0;
- } catch (SettingNotFoundException snfe) {
- return false;
- }
- }
-
- public ArrayList<PdpConnection> getAllPdps() {
- ArrayList<PdpConnection> pdps = (ArrayList<PdpConnection>)pdpList.clone();
+ /**
+ * Formerly this method was ArrayList<PdpConnection> getAllPdps()
+ */
+ public ArrayList<DataConnection> getAllDataConnections() {
+ ArrayList<DataConnection> pdps = (ArrayList<DataConnection>)pdpList.clone();
return pdps;
}
@@ -567,8 +482,7 @@ final class DataConnectionTracker extends Handler
* Invoked when ServiceStateTracker observes a transition from GPRS
* attach to detach.
*/
- private void onGprsDetached()
- {
+ protected void onGprsDetached() {
/*
* We presently believe it is unnecessary to tear down the PDP context
* when GPRS detaches, but we should stop the network polling.
@@ -576,7 +490,7 @@ final class DataConnectionTracker extends Handler
stopNetStatPoll();
phone.notifyDataConnection(Phone.REASON_GPRS_DETACHED);
}
-
+
private void onGprsAttached() {
if (state == State.CONNECTED) {
startNetStatPoll();
@@ -586,8 +500,7 @@ final class DataConnectionTracker extends Handler
}
}
- private boolean trySetupData(String reason)
- {
+ private boolean trySetupData(String reason) {
if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason));
if (phone.getSimulatedRadioControl() != null) {
@@ -600,13 +513,13 @@ final class DataConnectionTracker extends Handler
return true;
}
- int gprsState = phone.mSST.getCurrentGprsState();
+ int gprsState = ((GSMPhone) phone).mSST.getCurrentGprsState();
boolean roaming = phone.getServiceState().getRoaming();
if ((state == State.IDLE || state == State.SCANNING)
&& (gprsState == ServiceState.STATE_IN_SERVICE || noAutoAttach)
- && phone.mSIMRecords.getRecordsLoaded()
- && ( phone.mSST.isConcurrentVoiceAndData() ||
+ && ((GSMPhone) phone).mSIMRecords.getRecordsLoaded()
+ && ( ((GSMPhone) phone).mSST.isConcurrentVoiceAndData() ||
phone.getState() == Phone.State.IDLE )
&& isDataAllowed()) {
@@ -614,7 +527,7 @@ final class DataConnectionTracker extends Handler
waitingApns = buildWaitingApns();
if (waitingApns.isEmpty()) {
if (DBG) log("No APN found");
- notifyNoData(PdpConnection.PdpFailCause.BAD_APN);
+ notifyNoData(PdpConnection.FailCause.BAD_APN);
return false;
} else {
log ("Create from allApns : " + apnListToString(allApns));
@@ -630,8 +543,8 @@ final class DataConnectionTracker extends Handler
log("trySetupData: Not ready for data: " +
" dataState=" + state +
" gprsState=" + gprsState +
- " sim=" + phone.mSIMRecords.getRecordsLoaded() +
- " UMTS=" + phone.mSST.isConcurrentVoiceAndData() +
+ " sim=" + ((GSMPhone) phone).mSIMRecords.getRecordsLoaded() +
+ " UMTS=" + ((GSMPhone) phone).mSST.isConcurrentVoiceAndData() +
" phoneState=" + phone.getState() +
" dataEnabled=" + getAnyDataEnabled() +
" roaming=" + roaming +
@@ -651,7 +564,8 @@ final class DataConnectionTracker extends Handler
*/
private void cleanUpConnection(boolean tearDown, String reason) {
if (DBG) log("Clean up connection due to " + reason);
- for (PdpConnection pdp : pdpList) {
+ for (DataConnection conn : pdpList) {
+ PdpConnection pdp = (PdpConnection) conn;
if (tearDown) {
Message msg = obtainMessage(EVENT_DISCONNECT_DONE);
pdp.disconnect(msg);
@@ -705,8 +619,9 @@ final class DataConnectionTracker extends Handler
}
private PdpConnection findFreePdp() {
- for (PdpConnection pdp : pdpList) {
- if (pdp.getState() == PdpConnection.PdpState.INACTIVE) {
+ for (DataConnection conn : pdpList) {
+ PdpConnection pdp = (PdpConnection) conn;
+ if (pdp.getState() == DataConnection.State.INACTIVE) {
return pdp;
}
}
@@ -744,7 +659,7 @@ final class DataConnectionTracker extends Handler
return null;
}
- String getIpAddress(String apnType) {
+ protected String getIpAddress(String apnType) {
if (mActivePdp != null
&& (apnType == null || mActiveApn.canHandleType(apnType))) {
return mActivePdp.getIpAddress();
@@ -760,7 +675,7 @@ final class DataConnectionTracker extends Handler
return null;
}
- String[] getDnsServers(String apnType) {
+ protected String[] getDnsServers(String apnType) {
if (mActivePdp != null
&& (apnType == null || mActiveApn.canHandleType(apnType))) {
return mActivePdp.getDnsServers();
@@ -769,8 +684,7 @@ final class DataConnectionTracker extends Handler
}
private boolean
- pdpStatesHasCID (ArrayList<PDPContextState> states, int cid)
- {
+ pdpStatesHasCID (ArrayList<PDPContextState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
if (states.get(i).cid == cid) return true;
}
@@ -779,8 +693,7 @@ final class DataConnectionTracker extends Handler
}
private boolean
- pdpStatesHasActiveCID (ArrayList<PDPContextState> states, int cid)
- {
+ pdpStatesHasActiveCID (ArrayList<PDPContextState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
if (states.get(i).cid == cid) return states.get(i).active;
}
@@ -794,9 +707,7 @@ final class DataConnectionTracker extends Handler
* via an unsolicited response (which could have happened at any
* previous state
*/
- private void
- onPdpStateChanged (AsyncResult ar, boolean explicitPoll)
- {
+ protected void onPdpStateChanged (AsyncResult ar, boolean explicitPoll) {
ArrayList<PDPContextState> pdpStates;
pdpStates = (ArrayList<PDPContextState>)(ar.result);
@@ -852,7 +763,7 @@ final class DataConnectionTracker extends Handler
this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
} else {
Log.i(LOG_TAG, "PDP connection has dropped (active=false case). "
- + " Reconnecting");
+ + " Reconnecting");
cleanUpConnection(true, null);
trySetupData(null);
@@ -912,9 +823,7 @@ final class DataConnectionTracker extends Handler
* with certain RIL impl's/basebands
*
*/
- private void
- startPeriodicPdpPoll()
- {
+ private void startPeriodicPdpPoll() {
removeMessages(EVENT_POLL_PDP);
sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS);
@@ -924,6 +833,7 @@ final class DataConnectionTracker extends Handler
txPkts = -1;
rxPkts = -1;
sentSinceLastRecv = 0;
+ netStatPollPeriod = POLL_NETSTAT_MILLIS;
mNoRecvPollCount = 0;
}
@@ -931,7 +841,7 @@ final class DataConnectionTracker extends Handler
if (state == State.CONNECTED) {
int maxPdpReset = Settings.Gservices.getInt(mResolver,
Settings.Gservices.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT,
- DEFAULT_MAX_PDP_RESET_FAIL);
+ DEFAULT_MAX_PDP_RESET_FAIL);
if (mPdpResetCount < maxPdpReset) {
mPdpResetCount++;
EventLog.writeEvent(EVENT_LOG_PDP_RESET, sentSinceLastRecv);
@@ -939,16 +849,14 @@ final class DataConnectionTracker extends Handler
} else {
mPdpResetCount = 0;
EventLog.writeEvent(EVENT_LOG_REREGISTER_NETWORK, sentSinceLastRecv);
- phone.mSST.reRegisterNetwork(null);
+ ((GSMPhone) phone).mSST.reRegisterNetwork(null);
}
// TODO: Add increasingly drastic recovery steps, eg,
// reset the radio, reset the device.
}
}
- private void
- startNetStatPoll()
- {
+ protected void startNetStatPoll() {
if (state == State.CONNECTED && mPingTestActive == false) {
Log.d(LOG_TAG, "[DataConnection] Start poll NetStat");
resetPollStats();
@@ -957,17 +865,13 @@ final class DataConnectionTracker extends Handler
}
}
- private void
- stopNetStatPoll()
- {
+ protected void stopNetStatPoll() {
netStatPollEnabled = false;
removeCallbacks(mPollNetStat);
Log.d(LOG_TAG, "[DataConnection] Stop poll NetStat");
}
- private void
- restartRadio()
- {
+ protected void restartRadio() {
Log.d(LOG_TAG, "************TURN OFF RADIO**************");
cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
phone.mCM.setRadioPower(false, null);
@@ -983,117 +887,6 @@ final class DataConnectionTracker extends Handler
SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1));
}
- Runnable mPollNetStat = new Runnable()
- {
-
- public void run() {
- int sent, received;
- int preTxPkts = -1, preRxPkts = -1;
-
- Activity newActivity;
-
- preTxPkts = txPkts;
- preRxPkts = rxPkts;
-
- try {
- txPkts = netstat.getTxPackets();
- rxPkts = netstat.getRxPackets();
- } catch (RemoteException e) {
- txPkts = 0;
- rxPkts = 0;
- }
-
- //Log.d(LOG_TAG, "rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
-
- if (netStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
- sent = txPkts - preTxPkts;
- received = rxPkts - preRxPkts;
-
- if ( sent > 0 && received > 0 ) {
- sentSinceLastRecv = 0;
- newActivity = Activity.DATAINANDOUT;
- mPdpResetCount = 0;
- } else if (sent > 0 && received == 0) {
- if (phone.mCT.state == Phone.State.IDLE) {
- sentSinceLastRecv += sent;
- } else {
- sentSinceLastRecv = 0;
- }
- newActivity = Activity.DATAOUT;
- } else if (sent == 0 && received > 0) {
- sentSinceLastRecv = 0;
- newActivity = Activity.DATAIN;
- mPdpResetCount = 0;
- } else if (sent == 0 && received == 0) {
- newActivity = Activity.NONE;
- } else {
- sentSinceLastRecv = 0;
- newActivity = Activity.NONE;
- }
-
- if (activity != newActivity && mIsScreenOn) {
- activity = newActivity;
- phone.notifyDataActivity();
- }
- }
-
- int watchdogTrigger = Settings.Gservices.getInt(mResolver,
- Settings.Gservices.PDP_WATCHDOG_TRIGGER_PACKET_COUNT, NUMBER_SENT_PACKETS_OF_HANG);
-
- if (sentSinceLastRecv >= watchdogTrigger) {
- // we already have NUMBER_SENT_PACKETS sent without ack
- if (mNoRecvPollCount == 0) {
- EventLog.writeEvent(EVENT_LOG_RADIO_RESET_COUNTDOWN_TRIGGERED,
- sentSinceLastRecv);
- }
-
- int noRecvPollLimit = Settings.Gservices.getInt(mResolver,
- Settings.Gservices.PDP_WATCHDOG_ERROR_POLL_COUNT, NO_RECV_POLL_LIMIT);
-
- if (mNoRecvPollCount < noRecvPollLimit) {
- // It's possible the PDP context went down and we weren't notified.
- // Start polling the context list in an attempt to recover.
- if (DBG) log("no DATAIN in a while; polling PDP");
- phone.mCM.getPDPContextList(obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
-
- mNoRecvPollCount++;
-
- // Slow down the poll interval to let things happen
- netStatPollPeriod = Settings.Gservices.getInt(mResolver,
- Settings.Gservices.PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS, POLL_NETSTAT_SLOW_MILLIS);
- } else {
- if (DBG) log("Sent " + String.valueOf(sentSinceLastRecv) +
- " pkts since last received");
- // We've exceeded the threshold. Run ping test as a final check;
- // it will proceed with recovery if ping fails.
- netStatPollEnabled = false;
- stopNetStatPoll();
- Thread pingTest = new Thread() {
- public void run() {
- mPingTestActive = true;
- runPingTest();
- }
- };
- pingTest.start();
- }
- } else {
- mNoRecvPollCount = 0;
- if (mIsScreenOn) {
- netStatPollPeriod = Settings.Gservices.getInt(mResolver,
- Settings.Gservices.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
- } else {
- netStatPollPeriod = Settings.Gservices.getInt(mResolver,
- Settings.Gservices.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
- POLL_NETSTAT_SCREEN_OFF_MILLIS);
- }
- }
-
- if (netStatPollEnabled) {
- mDataConnectionTracker.postDelayed(this, netStatPollPeriod);
- }
- }
- };
-
private void runPingTest () {
int status = -1;
try {
@@ -1112,7 +905,7 @@ final class DataConnectionTracker extends Handler
} catch (Exception e) {
Log.w(LOG_TAG, "exception trying to ping");
}
-
+
if (status == 0) {
// ping succeeded. False alarm. Reset netStatPoll.
// ("-1" for this event indicates a false alarm)
@@ -1130,20 +923,16 @@ final class DataConnectionTracker extends Handler
* seems like it deserves an error notification.
* Transient errors are ignored
*/
- private boolean
- shouldPostNotification(PdpConnection.PdpFailCause cause)
- {
+ private boolean shouldPostNotification(PdpConnection.FailCause cause) {
boolean shouldPost = true;
// TODO CHECK
// if (dataLink != null) {
// shouldPost = dataLink.getLastLinkExitCode() != DataLink.EXIT_OPEN_FAILED;
//}
- return (shouldPost && cause != PdpConnection.PdpFailCause.UNKNOWN);
+ return (shouldPost && cause != PdpConnection.FailCause.UNKNOWN);
}
- private void
- reconnectAfterFail(PdpConnection.PdpFailCause lastFailCauseCode)
- {
+ private void reconnectAfterFail(PdpConnection.FailCause lastFailCauseCode) {
if (state == State.FAILED) {
Log.d(LOG_TAG, "PDP activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
@@ -1172,239 +961,180 @@ final class DataConnectionTracker extends Handler
}
}
- private void notifyNoData(PdpConnection.PdpFailCause lastFailCauseCode) {
+ private void notifyNoData(PdpConnection.FailCause lastFailCauseCode) {
setState(State.FAILED);
}
-
- private void log(String s) {
- Log.d(LOG_TAG, "[DataConnectionTracker] " + s);
+ protected void onRecordsLoaded() {
+ createAllApnList();
+ if (state == State.FAILED) {
+ cleanUpConnection(false, null);
+ }
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
}
- //***** Overridden from Handler
- public void
- handleMessage (Message msg)
- {
- AsyncResult ar;
- String reason = null;
-
- switch (msg.what) {
- case EVENT_RECORDS_LOADED:
- createAllApnList();
- if (state == State.FAILED) {
- cleanUpConnection(false, null);
- }
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
- break;
-
- case EVENT_ENABLE_NEW_APN:
- // TODO: To support simultaneous PDP contexts, this should really only call
- // cleanUpConnection if it needs to free up a PdpConnection.
- reason = Phone.REASON_APN_SWITCHED;
- cleanUpConnection(true, reason);
- // Fall through to EVENT_TRY_SETUP_DATA.
- case EVENT_TRY_SETUP_DATA:
- trySetupData(reason);
- break;
-
- case EVENT_RESTORE_DEFAULT_APN:
- if (DBG) Log.d(LOG_TAG, "Restore default APN");
- setEnabled(Phone.APN_TYPE_MMS, false);
- if (!isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
- cleanUpConnection(true, Phone.REASON_RESTORE_DEFAULT_APN);
- mRequestedApnType = Phone.APN_TYPE_DEFAULT;
- trySetupData(Phone.REASON_RESTORE_DEFAULT_APN );
- }
- break;
-
- case EVENT_ROAMING_OFF:
- trySetupData(Phone.REASON_ROAMING_OFF);
- break;
-
- case EVENT_GPRS_DETACHED:
- onGprsDetached();
- break;
+ protected void onEnableNewApn() {
+ // TODO: To support simultaneous PDP contexts, this should really only call
+ // cleanUpConnection if it needs to free up a PdpConnection.
+ cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
+ trySetupData(Phone.REASON_APN_SWITCHED);
+ }
- case EVENT_GPRS_ATTACHED:
- onGprsAttached();
- break;
-
- case EVENT_ROAMING_ON:
- if (getDataOnRoamingEnabled()) {
- trySetupData(Phone.REASON_ROAMING_ON);
- } else {
- if (DBG) log("Tear down data connection on roaming.");
- cleanUpConnection(true, Phone.REASON_ROAMING_ON);
- }
- break;
+ protected void onTrySetupData() {
+ trySetupData(null);
+ }
- case EVENT_RADIO_AVAILABLE:
- if (phone.getSimulatedRadioControl() != null) {
- // Assume data is connected on the simulator
- // FIXME this can be improved
- setState(State.CONNECTED);
- phone.notifyDataConnection(null);
+ protected void onRestoreDefaultApn() {
+ if (DBG) Log.d(LOG_TAG, "Restore default APN");
+ setEnabled(Phone.APN_TYPE_MMS, false);
+ if (!isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
+ cleanUpConnection(true, Phone.REASON_RESTORE_DEFAULT_APN);
+ mRequestedApnType = Phone.APN_TYPE_DEFAULT;
+ trySetupData(Phone.REASON_RESTORE_DEFAULT_APN );
+ }
+ }
- Log.i(LOG_TAG, "We're on the simulator; assuming data is connected");
- }
+ protected void onRoamingOff() {
+ trySetupData(Phone.REASON_ROAMING_OFF);
+ }
- if (state != State.IDLE) {
- cleanUpConnection(true, null);
- }
- break;
+ protected void onRoamingOn() {
+ if (getDataOnRoamingEnabled()) {
+ trySetupData(Phone.REASON_ROAMING_ON);
+ } else {
+ if (DBG) log("Tear down data connection on roaming.");
+ cleanUpConnection(true, Phone.REASON_ROAMING_ON);
+ }
+ }
- case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
- // Make sure our reconnect delay starts at the initial value
- // next time the radio comes on
- nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+ protected void onRadioAvailable() {
+ if (phone.getSimulatedRadioControl() != null) {
+ // Assume data is connected on the simulator
+ // FIXME this can be improved
+ setState(State.CONNECTED);
+ phone.notifyDataConnection(null);
- if (phone.getSimulatedRadioControl() != null) {
- // Assume data is connected on the simulator
- // FIXME this can be improved
- Log.i(LOG_TAG, "We're on the simulator; assuming radio off is meaningless");
- } else {
- if (DBG) log("Radio is off and clean up all connection");
- // TODO: Should we reset mRequestedApnType to "default"?
- cleanUpConnection(false, Phone.REASON_RADIO_TURNED_OFF);
- }
- break;
-
- case EVENT_DATA_SETUP_COMPLETE:
- ar = (AsyncResult) msg.obj;
-
- if (ar.exception == null) {
- // everything is setup
-
- // arg1 contains CID for this PDP context
- cidActive = msg.arg1;
- /*
- * We may have switched away from the default PDP context
- * in order to enable a "special" APN (e.g., for MMS
- * traffic). Set a timer to switch back and/or disable the
- * special APN, so that a negligient application doesn't
- * permanently prevent data connectivity. What we are
- * protecting against here is not malicious apps, but
- * rather an app that inadvertantly fails to reset to the
- * default APN, or that dies before doing so.
- */
- if (dataEnabled[APN_MMS_ID]) {
- removeMessages(EVENT_RESTORE_DEFAULT_APN);
- sendMessageDelayed(
- obtainMessage(EVENT_RESTORE_DEFAULT_APN),
- getRestoreDefaultApnDelay());
- }
- if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
- SystemProperties.set("gsm.defaultpdpcontext.active", "true");
- } else {
- SystemProperties.set("gsm.defaultpdpcontext.active", "false");
- }
- notifyDefaultData();
-
- // TODO: For simultaneous PDP support, we need to build another
- // trigger another TRY_SETUP_DATA for the next APN type. (Note
- // that the existing connection may service that type, in which
- // case we should try the next type, etc.
- } else {
- PdpConnection.PdpFailCause cause;
- cause = (PdpConnection.PdpFailCause) (ar.result);
- if(DBG)
- log("PDP setup failed " + cause);
-
- // No try for permanent failure
- if (cause.isPermanentFail()) {
- notifyNoData(cause);
- }
-
- if (tryNextApn(cause)) {
- waitingApns.remove(0);
- if (waitingApns.isEmpty()) {
- // No more to try, start delayed retry
- notifyNoData(cause);
- reconnectAfterFail(cause);
- } else {
- // we still have more apns to try
- setState(State.SCANNING);
- trySetupData(null);
- }
- } else {
- notifyNoData(cause);
- reconnectAfterFail(cause);
- }
- }
- break;
+ Log.i(LOG_TAG, "We're on the simulator; assuming data is connected");
+ }
- case EVENT_DISCONNECT_DONE:
- if(DBG) log("EVENT_DISCONNECT_DONE");
- trySetupData(null);
- break;
+ if (state != State.IDLE) {
+ cleanUpConnection(true, null);
+ }
+ }
- case EVENT_PDP_STATE_CHANGED:
- ar = (AsyncResult) msg.obj;
+ protected void onRadioOffOrNotAvailable() {
+ // Make sure our reconnect delay starts at the initial value
+ // next time the radio comes on
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
- onPdpStateChanged(ar, false);
- break;
+ if (phone.getSimulatedRadioControl() != null) {
+ // Assume data is connected on the simulator
+ // FIXME this can be improved
+ Log.i(LOG_TAG, "We're on the simulator; assuming radio off is meaningless");
+ } else {
+ if (DBG) log("Radio is off and clean up all connection");
+ // TODO: Should we reset mRequestedApnType to "default"?
+ cleanUpConnection(false, Phone.REASON_RADIO_TURNED_OFF);
+ }
+ }
- case EVENT_GET_PDP_LIST_COMPLETE:
- ar = (AsyncResult) msg.obj;
+ protected void onDataSetupComplete(AsyncResult ar) {
+ if (ar.exception == null) {
+ // everything is setup
+
+ /*
+ * We may have switched away from the default PDP context
+ * in order to enable a "special" APN (e.g., for MMS
+ * traffic). Set a timer to switch back and/or disable the
+ * special APN, so that a negligient application doesn't
+ * permanently prevent data connectivity. What we are
+ * protecting against here is not malicious apps, but
+ * rather an app that inadvertantly fails to reset to the
+ * default APN, or that dies before doing so.
+ */
+ if (dataEnabled[APN_MMS_ID]) {
+ removeMessages(EVENT_RESTORE_DEFAULT_APN);
+ sendMessageDelayed(obtainMessage(EVENT_RESTORE_DEFAULT_APN),
+ getRestoreDefaultApnDelay());
+ }
+ if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
+ SystemProperties.set("gsm.defaultpdpcontext.active", "true");
+ } else {
+ SystemProperties.set("gsm.defaultpdpcontext.active", "false");
+ }
+ notifyDefaultData();
- onPdpStateChanged(ar, true);
- break;
+ // TODO: For simultaneous PDP support, we need to build another
+ // trigger another TRY_SETUP_DATA for the next APN type. (Note
+ // that the existing connection may service that type, in which
+ // case we should try the next type, etc.
+ } else {
+ PdpConnection.FailCause cause;
+ cause = (PdpConnection.FailCause) (ar.result);
+ if(DBG) log("PDP setup failed " + cause);
- case EVENT_POLL_PDP:
- /* See comment in startPeriodicPdpPoll */
- ar = (AsyncResult) msg.obj;
+ // No try for permanent failure
+ if (cause.isPermanentFail()) {
+ notifyNoData(cause);
+ }
- if (!(state == State.CONNECTED)) {
- // not connected; don't poll anymore
- break;
+ if (tryNextApn(cause)) {
+ waitingApns.remove(0);
+ if (waitingApns.isEmpty()) {
+ // No more to try, start delayed retry
+ notifyNoData(cause);
+ reconnectAfterFail(cause);
+ } else {
+ // we still have more apns to try
+ setState(State.SCANNING);
+ trySetupData(null);
}
+ } else {
+ notifyNoData(cause);
+ reconnectAfterFail(cause);
+ }
+ }
+ }
- phone.mCM.getPDPContextList(this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
-
- sendMessageDelayed(obtainMessage(EVENT_POLL_PDP),
- POLL_PDP_MILLIS);
- break;
+ protected void onDisconnectDone() {
+ if(DBG) log("EVENT_DISCONNECT_DONE");
+ trySetupData(null);
+ }
- case EVENT_VOICE_CALL_STARTED:
- if (state == State.CONNECTED &&
- !phone.mSST.isConcurrentVoiceAndData()) {
- stopNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
- }
- break;
-
- case EVENT_VOICE_CALL_ENDED:
- // in case data setup was attempted when we were on a voice call
- trySetupData(Phone.REASON_VOICE_CALL_ENDED);
- if (state == State.CONNECTED &&
- !phone.mSST.isConcurrentVoiceAndData()) {
- startNetStatPoll();
- phone.notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
- } else {
- // clean slate after call end.
- resetPollStats();
- }
- break;
+ protected void onPollPdp() {
+ if (state == State.CONNECTED) {
+ // only poll when connected
+ phone.mCM.getPDPContextList(this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
+ sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS);
+ }
+ }
- case EVENT_START_NETSTAT_POLL:
- mPingTestActive = false;
- startNetStatPoll();
- break;
+ protected void onVoiceCallStarted() {
+ if (state == State.CONNECTED && !((GSMPhone) phone).mSST.isConcurrentVoiceAndData()) {
+ stopNetStatPoll();
+ phone.notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
+ }
+ }
- case EVENT_START_RECOVERY:
- mPingTestActive = false;
- doRecovery();
- break;
+ protected void onVoiceCallEnded() {
+ // in case data setup was attempted when we were on a voice call
+ trySetupData(Phone.REASON_VOICE_CALL_ENDED);
+ if (state == State.CONNECTED && !((GSMPhone) phone).mSST.isConcurrentVoiceAndData()) {
+ startNetStatPoll();
+ phone.notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
+ } else {
+ // clean slate after call end.
+ resetPollStats();
}
}
- private boolean tryNextApn(PdpFailCause cause) {
- return (cause != PdpFailCause.RADIO_NOT_AVIALABLE)
- && (cause != PdpFailCause.RADIO_OFF)
- && (cause != PdpFailCause.RADIO_ERROR_RETRY)
- && (cause != PdpFailCause.NO_SIGNAL)
- && (cause != PdpFailCause.SIM_LOCKED);
+ 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);
}
private int getRestoreDefaultApnDelay() {
@@ -1427,7 +1157,7 @@ final class DataConnectionTracker extends Handler
*/
private void createAllApnList() {
allApns = new ArrayList<ApnSetting>();
- String operator = phone.mSIMRecords.getSIMOperatorNumeric();
+ String operator = ((GSMPhone) phone).mSIMRecords.getSIMOperatorNumeric();
if (operator != null) {
String selection = "numeric = '" + operator + "'";
@@ -1438,7 +1168,7 @@ final class DataConnectionTracker extends Handler
if (cursor != null) {
if (cursor.getCount() > 0) {
allApns = createApnList(cursor);
- // TODO: Figure out where this fits in. This basically just
+ // TODO: Figure out where this fits in. This basically just
// writes the pap-secrets file. No longer tied to PdpConnection
// object. Not used on current platform (no ppp).
//PdpConnection pdp = pdpList.get(pdp_name);
@@ -1452,20 +1182,27 @@ final class DataConnectionTracker extends Handler
if (allApns.isEmpty()) {
if (DBG) log("No APN found for carrier: " + operator);
- notifyNoData(PdpConnection.PdpFailCause.BAD_APN);
+ notifyNoData(PdpConnection.FailCause.BAD_APN);
}
}
private void createAllPdpList() {
- pdpList = new ArrayList<PdpConnection>();
- PdpConnection pdp;
+ pdpList = new ArrayList<DataConnection>();
+ DataConnection pdp;
for (int i = 0; i < PDP_CONNECTION_POOL_SIZE; i++) {
- pdp = new PdpConnection(phone);
+ pdp = new PdpConnection((GSMPhone) phone);
pdpList.add(pdp);
}
}
+ private void destroyAllPdpList() {
+ if(pdpList != null) {
+ PdpConnection pdp;
+ pdpList.removeAll(pdpList);
+ }
+ }
+
/**
*
* @return waitingApns list to be used to create PDP
@@ -1485,7 +1222,7 @@ final class DataConnectionTracker extends Handler
}
/**
- * Get next apn in waitingApns
+ * Get next apn in waitingApns
* @return the first apn found in waitingApns, null if none
*/
private ApnSetting getNextApn() {
@@ -1509,4 +1246,61 @@ final class DataConnectionTracker extends Handler
}
return result.toString();
}
+
+ public void handleMessage (Message msg) {
+
+ switch (msg.what) {
+ case EVENT_RECORDS_LOADED:
+ onRecordsLoaded();
+ break;
+
+ case EVENT_ENABLE_NEW_APN:
+ onEnableNewApn();
+ break;
+
+ case EVENT_RESTORE_DEFAULT_APN:
+ onRestoreDefaultApn();
+ break;
+
+ case EVENT_GPRS_DETACHED:
+ onGprsDetached();
+ break;
+
+ case EVENT_GPRS_ATTACHED:
+ onGprsAttached();
+ break;
+
+ case EVENT_DATA_STATE_CHANGED:
+ onPdpStateChanged((AsyncResult) msg.obj, false);
+ break;
+
+ case EVENT_GET_PDP_LIST_COMPLETE:
+ onPdpStateChanged((AsyncResult) msg.obj, true);
+ break;
+
+ case EVENT_POLL_PDP:
+ onPollPdp();
+ break;
+
+ case EVENT_START_NETSTAT_POLL:
+ mPingTestActive = false;
+ startNetStatPoll();
+ break;
+
+ case EVENT_START_RECOVERY:
+ mPingTestActive = false;
+ doRecovery();
+ break;
+
+ default:
+ // handle the message in the super class DataConnectionTracker
+ super.handleMessage(msg);
+ break;
+ }
+ }
+
+ protected void log(String s) {
+ Log.d(LOG_TAG, "[GsmtaConnectionTracker] " + s);
+ }
+
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 2ac0ef5dea19..9fb1ce9b4128 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -20,14 +20,16 @@ import android.content.Context;
import com.android.internal.telephony.*;
import android.os.*;
-import android.util.Log;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
+import android.telephony.PhoneNumberUtils;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
-import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+
import static com.android.internal.telephony.CommandsInterface.*;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
/**
* The motto for this file is:
*
@@ -41,15 +43,15 @@ public final class GsmMmiCode extends Handler implements MmiCode {
static final String LOG_TAG = "GSM";
//***** Constants
-
+
// From TS 22.030 6.5.2
static final String ACTION_ACTIVATE = "*";
static final String ACTION_DEACTIVATE = "#";
static final String ACTION_INTERROGATE = "*#";
static final String ACTION_REGISTER = "**";
static final String ACTION_ERASURE = "##";
-
- // Supp Service cocdes from TS 22.030 Annex B
+
+ // Supp Service cocdes from TS 22.030 Annex B
//Called line presentation
static final String SC_CLIP = "30";
@@ -101,25 +103,24 @@ public final class GsmMmiCode extends Handler implements MmiCode {
GSMPhone phone;
Context context;
-
+
String action; // One of ACTION_*
String sc; // Service Code
String sia, sib, sic; // Service Info a,b,c
String poundString; // Entire MMI string up to and including #
String dialingNumber;
String pwd; // For password registration
-
- /** Set to true in processCode, not at newFromDialString time */
+ /** Set to true in processCode, not at newFromDialString time */
private boolean isPendingUSSD;
private boolean isUssdRequest;
- State state = State.PENDING;
+ State state = State.PENDING;
CharSequence message;
-
+
//***** Class Variables
-
+
// See TS 22.030 6.5.2 "Structure of the MMI"
@@ -136,9 +137,9 @@ public final class GsmMmiCode extends Handler implements MmiCode {
10 = dialing number
*/
- static final int MATCH_GROUP_POUND_STRING = 1;
+ static final int MATCH_GROUP_POUND_STRING = 1;
- static final int MATCH_GROUP_ACTION = 2;
+ static final int MATCH_GROUP_ACTION = 2;
//(activation/interrogation/registration/erasure)
static final int MATCH_GROUP_SERVICE_CODE = 3;
@@ -150,7 +151,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
//***** Public Class methods
-
+
/**
* Some dial strings in GSM are defined to do non-call setup
* things, such as modify or query supplementry service settings (eg, call
@@ -164,7 +165,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
* Please see flow chart in TS 22.030 6.5.3.2
*/
- static GsmMmiCode
+ static GsmMmiCode
newFromDialString(String dialString, GSMPhone phone) {
Matcher m;
GsmMmiCode ret = null;
@@ -185,7 +186,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
} else if (dialString.endsWith("#")) {
// TS 22.030 sec 6.5.3.2
- // "Entry of any characters defined in the 3GPP TS 23.038 [8] Default Alphabet
+ // "Entry of any characters defined in the 3GPP TS 23.038 [8] Default Alphabet
// (up to the maximum defined in 3GPP TS 24.080 [10]), followed by #SEND".
ret = new GsmMmiCode(phone);
@@ -195,12 +196,12 @@ public final class GsmMmiCode extends Handler implements MmiCode {
ret = new GsmMmiCode(phone);
ret.dialingNumber = dialString;
}
-
+
return ret;
}
static GsmMmiCode
- newNetworkInitiatedUssd (String ussdMessage,
+ newNetworkInitiatedUssd (String ussdMessage,
boolean isUssdRequest, GSMPhone phone) {
GsmMmiCode ret;
@@ -208,7 +209,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
ret.message = ussdMessage;
ret.isUssdRequest = isUssdRequest;
-
+
// If it's a request, set to PENDING so that it's cancelable.
if (isUssdRequest) {
ret.isPendingUSSD = true;
@@ -222,18 +223,18 @@ public final class GsmMmiCode extends Handler implements MmiCode {
static GsmMmiCode newFromUssdUserInput(String ussdMessge, GSMPhone phone) {
GsmMmiCode ret = new GsmMmiCode(phone);
-
+
ret.message = ussdMessge;
ret.state = State.PENDING;
ret.isPendingUSSD = true;
-
+
return ret;
}
//***** Private Class methods
- /** make empty strings be null.
- * Regexp returns empty strings for empty groups
+ /** make empty strings be null.
+ * Regexp returns empty strings for empty groups
*/
private static String
makeEmptyNull (String s) {
@@ -243,7 +244,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
}
/** returns true of the string is empty or null */
- private static boolean
+ private static boolean
isEmptyOrNull(CharSequence s) {
return s == null || (s.length() == 0);
}
@@ -251,10 +252,10 @@ public final class GsmMmiCode extends Handler implements MmiCode {
private static int
scToCallForwardReason(String sc) {
- if (sc == null) {
+ if (sc == null) {
throw new RuntimeException ("invalid call forward sc");
}
-
+
if (sc.equals(SC_CF_All)) {
return CommandsInterface.CF_REASON_ALL;
} else if (sc.equals(SC_CFU)) {
@@ -292,7 +293,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
/*
Note for code 20:
From TS 22.030 Annex C:
- "All GPRS bearer services" are not included in "All tele and bearer services"
+ "All GPRS bearer services" are not included in "All tele and bearer services"
and "All bearer services"."
....so SERVICE_CLASS_DATA, which (according to 27.007) includes GPRS
*/
@@ -323,29 +324,29 @@ public final class GsmMmiCode extends Handler implements MmiCode {
static boolean
isServiceCodeCallForwarding(String sc) {
- return sc != null &&
- (sc.equals(SC_CFU)
- || sc.equals(SC_CFB) || sc.equals(SC_CFNRy)
- || sc.equals(SC_CFNR) || sc.equals(SC_CF_All)
+ return sc != null &&
+ (sc.equals(SC_CFU)
+ || sc.equals(SC_CFB) || sc.equals(SC_CFNRy)
+ || sc.equals(SC_CFNR) || sc.equals(SC_CF_All)
|| sc.equals(SC_CF_All_Conditional));
}
static boolean
isServiceCodeCallBarring(String sc) {
return sc != null &&
- (sc.equals(SC_BAOC)
+ (sc.equals(SC_BAOC)
|| sc.equals(SC_BAOIC)
|| sc.equals(SC_BAOICxH)
|| sc.equals(SC_BAIC)
|| sc.equals(SC_BAICr)
|| sc.equals(SC_BA_ALL)
|| sc.equals(SC_BA_MO)
- || sc.equals(SC_BA_MT));
+ || sc.equals(SC_BA_MT));
}
static String
scToBarringFacility(String sc) {
- if (sc == null) {
+ if (sc == null) {
throw new RuntimeException ("invalid call barring sc");
}
@@ -375,7 +376,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
GsmMmiCode (GSMPhone phone) {
// The telephony unit-test cases may create GsmMmiCode's
// in secondary threads
- super(phone.h.getLooper());
+ super(phone.getHandler().getLooper());
this.phone = phone;
this.context = phone.getContext();
}
@@ -408,7 +409,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
* cancel it.
*/
phone.mCM.cancelPendingUssd(obtainMessage(EVENT_USSD_CANCEL_COMPLETE, this));
-
+
/*
* Don't call phone.onMMIDone here; wait for CANCEL_COMPLETE notice
* from RIL.
@@ -421,7 +422,6 @@ public final class GsmMmiCode extends Handler implements MmiCode {
phone.onMMIDone (this);
}
-
}
public boolean isCancelable() {
@@ -430,7 +430,6 @@ public final class GsmMmiCode extends Handler implements MmiCode {
}
//***** Instance Methods
-
/** Does this dial string contain a structured or unstructured MMI code? */
boolean
@@ -441,7 +440,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
/* Is this a 1 or 2 digit "short code" as defined in TS 22.030 sec 6.5.3.2? */
boolean
isShortCode() {
- return poundString == null
+ return poundString == null
&& dialingNumber != null && dialingNumber.length() <= 2;
}
@@ -462,7 +461,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
* for treating "0" and "00" as call setup strings.
*/
|| dialString.equals("0")
- || dialString.equals("00"))));
+ || dialString.equals("00"))));
}
/**
* @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
@@ -472,15 +471,15 @@ public final class GsmMmiCode extends Handler implements MmiCode {
|| sc.equals(SC_PUK) || sc.equals(SC_PUK2));
}
- /**
+ /**
* *See TS 22.030 Annex B
- * In temporary mode, to suppress CLIR for a single call, enter:
+ * In temporary mode, to suppress CLIR for a single call, enter:
* " * 31 # <called number> SEND "
- * In temporary mode, to invoke CLIR for a single call enter:
+ * In temporary mode, to invoke CLIR for a single call enter:
* " # 31 # <called number> SEND "
*/
-
- boolean
+
+ boolean
isTemporaryModeCLIR() {
return sc != null && sc.equals(SC_CLIR) && dialingNumber != null
&& (isActivate() || isDeactivate());
@@ -496,13 +495,13 @@ public final class GsmMmiCode extends Handler implements MmiCode {
if (isActivate()) {
return CommandsInterface.CLIR_SUPPRESSION;
} else if (isDeactivate()) {
- return CommandsInterface.CLIR_INVOCATION;
+ return CommandsInterface.CLIR_INVOCATION;
}
}
-
+
return CommandsInterface.CLIR_DEFAULT;
}
-
+
boolean isActivate() {
return action != null && action.equals(ACTION_ACTIVATE);
}
@@ -510,7 +509,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
boolean isDeactivate() {
return action != null && action.equals(ACTION_DEACTIVATE);
}
-
+
boolean isInterrogate() {
return action != null && action.equals(ACTION_INTERROGATE);
}
@@ -523,7 +522,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
return action != null && action.equals(ACTION_ERASURE);
}
- /**
+ /**
* Returns true if this is a USSD code that's been submitted to the
* network...eg, after processCode() is called
*/
@@ -547,7 +546,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
// We should have no dialing numbers here
throw new RuntimeException ("Invalid or Unsupported MMI Code");
} else if (sc != null && sc.equals(SC_CLIP)) {
- Log.d(LOG_TAG, "is CLIP");
+ Log.d(LOG_TAG, "is CLIP");
if (isInterrogate()) {
phone.mCM.queryCLIP(
obtainMessage(EVENT_QUERY_COMPLETE, this));
@@ -555,7 +554,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
throw new RuntimeException ("Invalid or Unsupported MMI Code");
}
} else if (sc != null && sc.equals(SC_CLIR)) {
- Log.d(LOG_TAG, "is CLIR");
+ Log.d(LOG_TAG, "is CLIR");
if (isActivate()) {
phone.mCM.setCLIR(CommandsInterface.CLIR_INVOCATION,
obtainMessage(EVENT_SET_COMPLETE, this));
@@ -605,7 +604,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
|| (cfAction == CommandsInterface.CF_ACTION_REGISTRATION)) ? 1 : 0;
phone.mCM.setCallForward(cfAction, reason,
- serviceClass, dialingNumber, time,
+ serviceClass, dialingNumber, time,
obtainMessage(EVENT_SET_CFF_COMPLETE,
isSettingUnconditionalVoice,
isEnableDesired,
@@ -622,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 {
@@ -713,7 +712,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
state = State.FAILED;
message = context.getText(com.android.internal.R.string.mmiError);
phone.onMMIDone(this);
- }
+ }
}
private void handlePasswordError(int res) {
@@ -725,8 +724,8 @@ public final class GsmMmiCode extends Handler implements MmiCode {
phone.onMMIDone(this);
}
- /**
- * Called from GSMPhone
+ /**
+ * Called from GSMPhone
*
* An unsolicited USSD NOTIFY or REQUEST has come in matching
* up with this pending USSD request
@@ -752,8 +751,8 @@ public final class GsmMmiCode extends Handler implements MmiCode {
}
}
- /**
- * Called from GSMPhone
+ /**
+ * Called from GSMPhone
*
* The radio has reset, and this is still pending
*/
@@ -776,8 +775,8 @@ public final class GsmMmiCode extends Handler implements MmiCode {
// response does not complete this MMI code...we wait for
// an unsolicited USSD "Notify" or "Request".
// The matching up of this is doene in GSMPhone.
-
- phone.mCM.sendUSSD(ussdMessage,
+
+ phone.mCM.sendUSSD(ussdMessage,
obtainMessage(EVENT_USSD_COMPLETE, this));
}
@@ -832,13 +831,13 @@ public final class GsmMmiCode extends Handler implements MmiCode {
com.android.internal.R.string.mmiError);
phone.onMMIDone(this);
- }
+ }
// Note that unlike most everything else, the USSD complete
// response does not complete this MMI code...we wait for
// an unsolicited USSD "Notify" or "Request".
// The matching up of this is done in GSMPhone.
-
+
break;
case EVENT_USSD_CANCEL_COMPLETE:
@@ -962,35 +961,35 @@ public final class GsmMmiCode extends Handler implements MmiCode {
com.android.internal.R.string.serviceNotProvisioned));
state = State.COMPLETE;
break;
-
+
case 1: // CLIR provisioned in permanent mode
sb.append(context.getText(
com.android.internal.R.string.CLIRPermanent));
state = State.COMPLETE;
break;
- case 2: // unknown (e.g. no network, etc.)
+ case 2: // unknown (e.g. no network, etc.)
sb.append(context.getText(
com.android.internal.R.string.mmiError));
state = State.FAILED;
break;
- case 3: // CLIR temporary mode presentation restricted
+ case 3: // CLIR temporary mode presentation restricted
// the 'n' parameter from TS 27.007 7.7
switch (clirArgs[0]) {
default:
case 0: // Default
sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOnNextCallOn));
+ com.android.internal.R.string.CLIRDefaultOnNextCallOn));
break;
case 1: // CLIR invocation
sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOnNextCallOn));
+ com.android.internal.R.string.CLIRDefaultOnNextCallOn));
break;
case 2: // CLIR suppression
sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOnNextCallOff));
+ com.android.internal.R.string.CLIRDefaultOnNextCallOff));
break;
}
state = State.COMPLETE;
@@ -1002,21 +1001,21 @@ public final class GsmMmiCode extends Handler implements MmiCode {
default:
case 0: // Default
sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOffNextCallOff));
+ com.android.internal.R.string.CLIRDefaultOffNextCallOff));
break;
case 1: // CLIR invocation
sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOffNextCallOn));
+ com.android.internal.R.string.CLIRDefaultOffNextCallOn));
break;
case 2: // CLIR suppression
sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOffNextCallOff));
+ com.android.internal.R.string.CLIRDefaultOffNextCallOff));
break;
}
state = State.COMPLETE;
break;
- }
+ }
}
message = sb;
@@ -1025,7 +1024,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
/**
* @param serviceClass 1 bit of the service class bit vectory
- * @return String to be used for call forward query MMI response text.
+ * @return String to be used for call forward query MMI response text.
* Returns null if unrecognized
*/
@@ -1065,7 +1064,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
// CF_REASON_NO_REPLY also has a time value associated with
// it. All others don't.
- needTimeTemplate =
+ needTimeTemplate =
(info.reason == CommandsInterface.CF_REASON_NO_REPLY);
if (info.status == 1) {
@@ -1093,8 +1092,8 @@ public final class GsmMmiCode extends Handler implements MmiCode {
}
// In the template (from strings.xmls)
- // {0} is one of "bearerServiceCode*"
- // {1} is dialing number
+ // {0} is one of "bearerServiceCode*"
+ // {1} is dialing number
// {2} is time in seconds
destinations[0] = serviceClassToCFString(info.serviceClass & serviceClassMask);
@@ -1122,7 +1121,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
sb.append(context.getText(com.android.internal.R.string.mmiError));
} else {
CallForwardInfo infos[];
-
+
infos = (CallForwardInfo[]) ar.result;
if (infos.length == 0) {
@@ -1136,18 +1135,18 @@ public final class GsmMmiCode extends Handler implements MmiCode {
SpannableStringBuilder tb = new SpannableStringBuilder();
// Each bit in the service class gets its own result line
- // The service classes may be split up over multiple
+ // The service classes may be split up over multiple
// CallForwardInfos. So, for each service classs, find out
// which CallForwardInfo represents it and then build
// the response text based on that
- for (int serviceClassMask = 1
+ for (int serviceClassMask = 1
; serviceClassMask <= SERVICE_CLASS_MAX
- ; serviceClassMask <<= 1
+ ; serviceClassMask <<= 1
) {
for (int i = 0, s = infos.length; i < s ; i++) {
if ((serviceClassMask & infos[i].serviceClass) != 0) {
- tb.append(makeCFQueryResultMessage(infos[i],
+ tb.append(makeCFQueryResultMessage(infos[i],
serviceClassMask));
tb.append("\n");
}
@@ -1161,7 +1160,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
message = sb;
phone.onMMIDone(this);
-
+
}
private void
@@ -1197,15 +1196,15 @@ public final class GsmMmiCode extends Handler implements MmiCode {
message = sb;
phone.onMMIDone(this);
}
-
+
private CharSequence
createQueryCallWaitingResultMessage(int serviceClass) {
- StringBuilder sb =
+ 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");
@@ -1214,12 +1213,12 @@ 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
- * some of the string parsing functionality in the Phone App's
- * SpecialCharSequenceMgr class.
+ * some of the string parsing functionality in the Phone App's
+ * SpecialCharSequenceMgr class.
*/
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
new file mode 100644
index 000000000000..e8b9fdcc6ef5
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -0,0 +1,259 @@
+/*
+ * 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.app.Activity;
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
+import android.content.Intent;
+import android.os.AsyncResult;
+import android.os.Message;
+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.SMSDispatcher;
+import com.android.internal.telephony.SmsHeader;
+import com.android.internal.telephony.SmsMessageBase;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+
+final class GsmSMSDispatcher extends SMSDispatcher {
+ private static final String TAG = "GSM";
+
+ GsmSMSDispatcher(GSMPhone phone) {
+ super(phone);
+ }
+
+ /**
+ * Called when a status report is received. This should correspond to
+ * a previously successful SEND.
+ *
+ * @param ar AsyncResult passed into the message handler. ar.result should
+ * be a String representing the status report PDU, as ASCII hex.
+ */
+ protected void handleStatusReport(AsyncResult ar) {
+ String pduString = (String) ar.result;
+ SmsMessage sms = SmsMessage.newFromCDS(pduString);
+
+ if (sms != null) {
+ int messageRef = sms.messageRef;
+ for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
+ SmsTracker tracker = deliveryPendingList.get(i);
+ if (tracker.mMessageRef == messageRef) {
+ // Found it. Remove from list and broadcast.
+ deliveryPendingList.remove(i);
+ PendingIntent intent = tracker.mDeliveryIntent;
+ Intent fillIn = new Intent();
+ fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
+ try {
+ intent.send(mContext, Activity.RESULT_OK, fillIn);
+ } catch (CanceledException ex) {}
+
+ // Only expect to see one tracker matching this messageref
+ break;
+ }
+ }
+ }
+
+ if (mCm != null) {
+ mCm.acknowledgeLastIncomingSMS(true, null);
+ }
+ }
+
+
+ /**
+ * Dispatches an incoming SMS messages.
+ *
+ * @param sms the incoming message from the phone
+ */
+ protected void dispatchMessage(SmsMessageBase smsb) {
+ 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;
+ }
+
+ if (Config.LOGD) {
+ Log.d(TAG,
+ "Received voice mail indicator set SMS shouldStore="
+ + !handled);
+ }
+ } else if (sms.isMWIClearMessage()) {
+ ((GSMPhone) mPhone).updateMessageWaitingIndicator(false);
+
+ if (sms.isMwiDontStore()) {
+ handled = true;
+ }
+
+ if (Config.LOGD) {
+ Log.d(TAG,
+ "Received voice mail indicator clear SMS shouldStore="
+ + !handled);
+ }
+ }
+
+ if (handled) {
+ return;
+ }
+
+ // 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()) {
+ 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;
+
+ 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;
+
+ break;
+ }
+
+ case SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT: {
+ byte[] data = element.getData();
+
+ destPort = (data[0] & 0xff) << 8;
+ destPort |= (data[1] & 0xff);
+
+ break;
+ }
+ }
+ }
+ }
+
+ if (referenceNumber == -1) {
+ // notify everyone of the message if it isn't partial
+ byte[][] pdus = new byte[1][];
+ pdus[0] = sms.getPdu();
+
+ if (destPort != -1) {
+ if (destPort == SmsHeader.PORT_WAP_PUSH) {
+ dispatchWapPdu(sms.getUserData());
+ }
+ // The message was sent to a port, so concoct a URI for it
+ dispatchPortAddressedPdus(pdus, destPort);
+ } else {
+ // It's a normal message, dispatch it
+ dispatchPdus(pdus);
+ }
+ } else {
+ // Process the message part
+ processMessagePart(sms, referenceNumber, sequence, count, destPort);
+ }
+ }
+
+ /** {@inheritDoc} */
+ 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;
+
+ if (sentIntents != null && sentIntents.size() > i) {
+ sentIntent = sentIntents.get(i);
+ }
+ if (deliveryIntents != null && deliveryIntents.size() > i) {
+ deliveryIntent = deliveryIntents.get(i);
+ }
+
+ SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
+ parts.get(i), deliveryIntent != null, header.toByteArray());
+
+ sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
+ }
+ }
+
+ /** {@inheritDoc} */
+ protected void sendSms(SmsTracker tracker) {
+ HashMap map = tracker.mData;
+
+ byte smsc[] = (byte[]) map.get("smsc");
+ byte pdu[] = (byte[]) map.get("pdu");
+
+ Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
+ mCm.sendSMS(IccUtils.bytesToHexString(smsc),
+ IccUtils.bytesToHexString(pdu), reply);
+ }
+
+ /** {@inheritDoc} */
+ protected void acknowledgeLastIncomingSms(boolean success, Message response){
+ // FIXME unit test leaves cm == null. this should change
+ if (mCm != null) {
+ mCm.acknowledgeLastIncomingSMS(success, response);
+ }
+ }
+
+ /** {@inheritDoc} */
+ protected void activateCellBroadcastSms(int activate, Message response) {
+ // Unless CBS is implemented for GSM, this point should be unreachable.
+ Log.e(TAG, "Error! The functionality cell broadcast sms is not implemented for GSM.");
+ response.recycle();
+ }
+
+ /** {@inheritDoc} */
+ protected void getCellBroadcastSmsConfig(Message response){
+ // Unless CBS is implemented for GSM, this point should be unreachable.
+ Log.e(TAG, "Error! The functionality cell broadcast sms is not implemented for GSM.");
+ response.recycle();
+ }
+
+ /** {@inheritDoc} */
+ protected void setCellBroadcastConfig(int[] configValuesArray, Message response) {
+ // Unless CBS is implemented for GSM, this point should be unreachable.
+ Log.e(TAG, "Error! The functionality cell broadcast sms is not implemented for GSM.");
+ response.recycle();
+ }
+
+}
+
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 2080df18e182..7c3c5598eab7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -17,13 +17,13 @@
package com.android.internal.telephony.gsm;
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_ISMANUAL;
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 static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC;
import com.android.internal.telephony.Phone;
import android.app.AlarmManager;
import android.content.ContentResolver;
@@ -47,6 +47,9 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.TimeUtils;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.PhoneProxy;
+import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyIntents;
@@ -90,7 +93,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
private boolean mZoneDst;
private long mZoneTime;
private boolean mGotCountryCode = false;
-
+ private ContentResolver cr;
+
String mSavedTimeZone;
long mSavedTime;
long mSavedAtTime;
@@ -107,9 +111,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
//***** Constants
static final boolean DBG = true;
- static final String LOG_TAG = "GsmServiceStateTracker";
+ static final String LOG_TAG = "GSM";
+
-
private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
@@ -131,7 +135,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
cellLoc = new GsmCellLocation();
newCellLoc = new GsmCellLocation();
- cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
+ cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
@@ -139,21 +143,37 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
cm.registerForSIMReady(this, EVENT_SIM_READY, null);
-
+
// system setting property AIRPLANE_MODE_ON is set in Settings.
int airplaneMode = Settings.System.getInt(
phone.getContext().getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0);
- mDesiredPowerState = ! (airplaneMode > 0);
+ mDesiredPowerState = ! (airplaneMode > 0);
- ContentResolver cr = phone.getContext().getContentResolver();
+ cr = phone.getContext().getContentResolver();
cr.registerContentObserver(
- Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
+ Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
mAutoTimeObserver);
setRssiDefaultValues();
mNeedToRegForSimLoaded = true;
}
+ public void dispose() {
+ //Unregister for all events
+ cm.unregisterForAvailable(this);
+ cm.unregisterForRadioStateChanged(this);
+ cm.unregisterForNetworkStateChanged(this);
+ cm.unregisterForSIMReady(this);
+ phone.mSIMRecords.unregisterForRecordsLoaded(this);
+ cm.unSetOnSignalStrengthUpdate(this);
+ cm.unSetOnNITZTime(this);
+ cr.unregisterContentObserver(this.mAutoTimeObserver);
+ }
+
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "GsmServiceStateTracker finalized");
+ }
+
/**
* Registration point for transition into GPRS attached.
* @param h handler to notify
@@ -170,14 +190,21 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
}
+ /*protected*/ void unregisterForGprsAttached(Handler h) {
+ gprsAttachedRegistrants.remove(h);
+ }
+
void registerForNetworkAttach(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
networkAttachedRegistrants.add(r);
-
+
if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
r.notifyRegistrant();
}
}
+ void unregisterForNetworkAttach(Handler h) {
+ networkAttachedRegistrants.remove(h);
+ }
/**
* Registration point for transition into GPRS detached.
* @param h handler to notify
@@ -193,7 +220,11 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
r.notifyRegistrant();
}
}
-
+
+ /*protected*/ void unregisterForGprsDetached(Handler h) {
+ gprsDetachedRegistrants.remove(h);
+ }
+
//***** Called from GSMPhone
public void
getLacAndCid(Message onComplete) {
@@ -243,18 +274,18 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
pollState();
break;
- case EVENT_GET_SIGNAL_STRENGTH:
+ case EVENT_GET_SIGNAL_STRENGTH:
// This callback is called when signal strength is polled
// all by itself
- if (!(cm.getRadioState().isOn())) {
- // Polling will continue when radio turns back on
+ if (!(cm.getRadioState().isOn()) || (cm.getRadioState().isCdma())) {
+ // Polling will continue when radio turns back on and not CDMA
return;
}
ar = (AsyncResult) msg.obj;
onSignalStrengthResult(ar);
queueNextSignalStrengthPoll();
-
+
break;
case EVENT_GET_LOC_DONE:
@@ -339,7 +370,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
getLacAndCid(null);
}
break;
-
+
case EVENT_SET_PREFERRED_NETWORK_TYPE:
ar = (AsyncResult) msg.obj;
// Don't care the result, only use for dereg network (COPS=2)
@@ -349,7 +380,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
case EVENT_RESET_PREFERRED_NETWORK_TYPE:
ar = (AsyncResult) msg.obj;
- if (ar.userObj != null) { //TODO check in Data Connectivity
+ if (ar.userObj != null) {
AsyncResult.forMessage(((Message) ar.userObj)).exception
= ar.exception;
((Message) ar.userObj).sendToTarget();
@@ -362,13 +393,11 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
if (ar.exception == null) {
mPreferredNetworkType = ((int[])ar.result)[0];
} else {
- mPreferredNetworkType = Phone.NT_GLOBAL_AUTO_TYPE;
+ mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
}
message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj);
- int toggledNetworkType = Phone.NT_GLOBAL_AUTO_TYPE;
- /*(mPreferredNetworkType == Phone.NT_AUTO_TYPE) ?
- Phone.NT_GSM_TYPE : Phone.NT_AUTO_TYPE;*/ //TODO check in Data Connectivity
+ int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
cm.setPreferredNetworkType(toggledNetworkType, message);
break;
@@ -382,7 +411,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
protected void updateSpnDisplay() {
int rule = phone.mSIMRecords.getDisplayRule(ss.getOperatorNumeric());
- String spn = phone.mSIMRecords.getServiceProvideName();
+ String spn = phone.mSIMRecords.getServiceProviderName();
String plmn = ss.getOperatorAlphaLong();
if (rule != curSpnRule
@@ -479,7 +508,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
if (states.length > 0) {
try {
regState = Integer.parseInt(states[0]);
-
+
// states[3] (if present) is the current radio technology
if (states.length >= 4 && states[3] != null) {
type = Integer.parseInt(states[3]);
@@ -550,7 +579,6 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
pollStateDone();
break;
-
case RADIO_OFF:
newSS.setStateOff();
newCellLoc.setStateInvalid();
@@ -560,6 +588,20 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
pollStateDone();
break;
+ case RUIM_NOT_READY:
+ case RUIM_READY:
+ case RUIM_LOCKED_OR_ABSENT:
+ case NV_NOT_READY:
+ case NV_READY:
+ log("Radio Technology Change ongoing, setting SS to off");
+ newSS.setStateOff();
+ newCellLoc.setStateInvalid();
+ setRssiDefaultValues();
+ mGotCountryCode = false;
+
+ pollStateDone();
+ break;
+
default:
// Issue all poll-related commands at once
// then count down the responses, which
@@ -588,7 +630,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
}
- private static String networkTypeToString(int type) { //Network Type from GPRS_REGISTRATION_STATE
+ private static String networkTypeToString(int type) {
+ //Network Type from GPRS_REGISTRATION_STATE
String ret = "unknown";
switch (type) {
@@ -603,7 +646,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
break;
default:
Log.e(LOG_TAG, "Wrong network type: " + Integer.toString(type));
- break;
+ break;
}
return ret;
@@ -727,7 +770,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
if (zone != null) {
Context context = phone.getContext();
if (getAutoTime()) {
- AlarmManager alarm =
+ AlarmManager alarm =
(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.setTimeZone(zone.getID());
}
@@ -769,7 +812,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
phone.notifyLocationChanged();
}
}
-
+
/**
* Returns a TimeZone object based only on parameters from the NITZ string.
*/
@@ -802,13 +845,13 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
break;
}
}
-
+
return guess;
}
private void
queueNextSignalStrengthPoll() {
- if (dontPollSignalStrength) {
+ if (dontPollSignalStrength || (cm.getRadioState().isCdma())) {
// The radio is telling us about signal strength changes
// we don't have to ask it
return;
@@ -850,7 +893,13 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
if (rssi != oldRSSI) {
- phone.notifySignalStrength();
+ 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");
+ }
}
}
@@ -897,7 +946,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
*/
private
boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) {
- String spn = SystemProperties.get(PROPERTY_SIM_OPERATOR_ALPHA, "empty");
+ String spn = SystemProperties.get(PROPERTY_ICC_OPERATOR_ALPHA, "empty");
String onsl = s.getOperatorAlphaLong();
String onss = s.getOperatorAlphaShort();
@@ -905,9 +954,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
boolean equalsOnsl = onsl != null && spn.equals(onsl);
boolean equalsOnss = onss != null && spn.equals(onss);
- String simNumeric = SystemProperties.get(PROPERTY_SIM_OPERATOR_NUMERIC, "");
+ String simNumeric = SystemProperties.get(PROPERTY_ICC_OPERATOR_NUMERIC, "");
String operatorNumeric = s.getOperatorNumeric();
-
+
boolean equalsMcc = true;
try {
equalsMcc = simNumeric.substring(0, 3).
@@ -1083,7 +1132,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
if (zone != null) {
Context context = phone.getContext();
if (getAutoTime()) {
- AlarmManager alarm =
+ AlarmManager alarm =
(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.setTimeZone(zone.getID());
}
@@ -1144,26 +1193,26 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
return true;
}
}
-
+
private void saveNitzTimeZone(String zoneId) {
mSavedTimeZone = zoneId;
- // Send out a sticky broadcast so the system can determine if
+ // Send out a sticky broadcast so the system can determine if
// the timezone was set by the carrier...
Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
intent.putExtra("time-zone", zoneId);
phone.getContext().sendStickyBroadcast(intent);
}
-
+
private void saveNitzTime(long time) {
mSavedTime = time;
mSavedAtTime = SystemClock.elapsedRealtime();
- // Send out a sticky broadcast so the system can determine if
+ // Send out a sticky broadcast so the system can determine if
// the time was set by the carrier...
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) {
@@ -1173,11 +1222,15 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
+ "' mSavedTime=" + mSavedTime
+ " mSavedAtTime=" + mSavedAtTime);
if (mSavedTimeZone != null && mSavedTime != 0 && mSavedAtTime != 0) {
- AlarmManager alarm =
+ AlarmManager alarm =
(AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
alarm.setTimeZone(mSavedTimeZone);
- SystemClock.setCurrentTimeMillis(mSavedTime
+ SystemClock.setCurrentTimeMillis(mSavedTime
+ (SystemClock.elapsedRealtime() - mSavedAtTime));
}
}
+
+ protected void log(String s) {
+ Log.d(LOG_TAG, "[GsmServiceStateTracker] " + s);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
new file mode 100644
index 000000000000..c163803a6ff0
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
@@ -0,0 +1,148 @@
+/*
+ * 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.telephony.PhoneNumberUtils;
+
+import com.android.internal.telephony.GsmAlphabet;
+import com.android.internal.telephony.SmsAddress;
+
+public class GsmSmsAddress extends SmsAddress {
+
+ static final int OFFSET_ADDRESS_LENGTH = 0;
+
+ static final int OFFSET_TOA = 1;
+
+ static final int OFFSET_ADDRESS_VALUE = 2;
+
+ /**
+ * New GsmSmsAddress from TS 23.040 9.1.2.5 Address Field
+ *
+ * @param offset the offset of the Address-Length byte
+ * @param length the length in bytes rounded up, e.g. "2 +
+ * (addressLength + 1) / 2"
+ */
+
+ public GsmSmsAddress(byte[] data, int offset, int length) {
+ origBytes = new byte[length];
+ System.arraycopy(data, offset, origBytes, 0, length);
+
+ // addressLength is the count of semi-octets, not bytes
+ int addressLength = origBytes[OFFSET_ADDRESS_LENGTH] & 0xff;
+
+ int toa = origBytes[OFFSET_TOA] & 0xff;
+ ton = 0x7 & (toa >> 4);
+
+ // TOA must have its high bit set
+ if ((toa & 0x80) != 0x80) {
+ throw new RuntimeException("Invalid TOA - high bit must be set");
+ }
+
+ if (isAlphanumeric()) {
+ // An alphanumeric address
+ int countSeptets = addressLength * 4 / 7;
+
+ address = GsmAlphabet.gsm7BitPackedToString(origBytes,
+ OFFSET_ADDRESS_VALUE, countSeptets);
+ } else {
+ // TS 23.040 9.1.2.5 says
+ // that "the MS shall interpret reserved values as 'Unknown'
+ // but shall store them exactly as received"
+
+ byte lastByte = origBytes[length - 1];
+
+ if ((addressLength & 1) == 1) {
+ // Make sure the final unused BCD digit is 0xf
+ origBytes[length - 1] |= 0xf0;
+ }
+ address = PhoneNumberUtils.calledPartyBCDToString(origBytes,
+ OFFSET_TOA, length - OFFSET_TOA);
+
+ // And restore origBytes
+ origBytes[length - 1] = lastByte;
+ }
+ }
+
+ public String getAddressString() {
+ return address;
+ }
+
+ /**
+ * Returns true if this is an alphanumeric address
+ */
+ public boolean isAlphanumeric() {
+ return ton == TON_ALPHANUMERIC;
+ }
+
+ public boolean isNetworkSpecific() {
+ return ton == TON_NETWORK;
+ }
+
+ /**
+ * Returns true of this is a valid CPHS voice message waiting indicator
+ * address
+ */
+ public boolean isCphsVoiceMessageIndicatorAddress() {
+ // CPHS-style MWI message
+ // See CPHS 4.7 B.4.2.1
+ //
+ // Basically:
+ //
+ // - Originating address should be 4 bytes long and alphanumeric
+ // - Decode will result with two chars:
+ // - Char 1
+ // 76543210
+ // ^ set/clear indicator (0 = clear)
+ // ^^^ type of indicator (000 = voice)
+ // ^^^^ must be equal to 0001
+ // - Char 2:
+ // 76543210
+ // ^ line number (0 = line 1)
+ // ^^^^^^^ set to 0
+ //
+ // Remember, since the alpha address is stored in 7-bit compact form,
+ // the "line number" is really the top bit of the first address value
+ // byte
+
+ return (origBytes[OFFSET_ADDRESS_LENGTH] & 0xff) == 4
+ && isAlphanumeric() && (origBytes[OFFSET_TOA] & 0x0f) == 0;
+ }
+
+ /**
+ * Returns true if this is a valid CPHS voice message waiting indicator
+ * address indicating a "set" of "indicator 1" of type "voice message
+ * waiting"
+ */
+ public boolean isCphsVoiceMessageSet() {
+ // 0x11 means "set" "voice message waiting" "indicator 1"
+ return isCphsVoiceMessageIndicatorAddress()
+ && (origBytes[OFFSET_ADDRESS_VALUE] & 0xff) == 0x11;
+
+ }
+
+ /**
+ * Returns true if this is a valid CPHS voice message waiting indicator
+ * address indicating a "clear" of "indicator 1" of type "voice message
+ * waiting"
+ */
+ public boolean isCphsVoiceMessageClear() {
+ // 0x10 means "clear" "voice message waiting" "indicator 1"
+ return isCphsVoiceMessageIndicatorAddress()
+ && (origBytes[OFFSET_ADDRESS_VALUE] & 0xff) == 0x10;
+
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/gsm/MccTable.java b/telephony/java/com/android/internal/telephony/gsm/MccTable.java
index 57aa01261ff8..07420e599892 100644
--- a/telephony/java/com/android/internal/telephony/gsm/MccTable.java
+++ b/telephony/java/com/android/internal/telephony/gsm/MccTable.java
@@ -51,11 +51,11 @@ public final class MccTable
entryForMcc(int mcc)
{
int index;
-
+
MccEntry m;
m = new MccEntry(mcc, null, 0);
-
+
index = Collections.binarySearch(table, m);
if (index < 0) {
@@ -110,7 +110,7 @@ public final class MccTable
/*
* The table below is built from two resources:
- *
+ *
* 1) ITU "Mobile Network Code (MNC) for the international
* identification plan for mobile terminals and mobile users"
* which is available as an annex to the ITU operational bulletin
@@ -123,238 +123,238 @@ public final class MccTable
*
* FIXME(mkf) this should be stored in a more efficient representation
*/
-
- table.add(new MccEntry(202,"gr",2)); //Greece
- table.add(new MccEntry(204,"nl",2)); //Netherlands (Kingdom of the)
- table.add(new MccEntry(206,"be",2)); //Belgium
- table.add(new MccEntry(208,"fr",2)); //France
- table.add(new MccEntry(212,"mc",2)); //Monaco (Principality of)
- table.add(new MccEntry(213,"ad",2)); //Andorra (Principality of)
- table.add(new MccEntry(214,"es",2)); //Spain
- table.add(new MccEntry(216,"hu",2)); //Hungary (Republic of)
- table.add(new MccEntry(218,"ba",2)); //Bosnia and Herzegovina
- table.add(new MccEntry(219,"hr",2)); //Croatia (Republic of)
- table.add(new MccEntry(220,"rs",2)); //Serbia and Montenegro
- table.add(new MccEntry(222,"it",2)); //Italy
- table.add(new MccEntry(225,"va",2)); //Vatican City State
- table.add(new MccEntry(226,"ro",2)); //Romania
- table.add(new MccEntry(228,"ch",2)); //Switzerland (Confederation of)
- table.add(new MccEntry(230,"cz",2)); //Czech Republic
- table.add(new MccEntry(231,"sk",2)); //Slovak Republic
- table.add(new MccEntry(232,"at",2)); //Austria
- table.add(new MccEntry(234,"gb",2)); //United Kingdom of Great Britain and Northern Ireland
- table.add(new MccEntry(235,"gb",2)); //United Kingdom of Great Britain and Northern Ireland
- table.add(new MccEntry(238,"dk",2)); //Denmark
- table.add(new MccEntry(240,"se",2)); //Sweden
- table.add(new MccEntry(242,"no",2)); //Norway
- table.add(new MccEntry(244,"fi",2)); //Finland
- table.add(new MccEntry(246,"lt",2)); //Lithuania (Republic of)
- table.add(new MccEntry(247,"lv",2)); //Latvia (Republic of)
- table.add(new MccEntry(248,"ee",2)); //Estonia (Republic of)
- table.add(new MccEntry(250,"ru",2)); //Russian Federation
- table.add(new MccEntry(255,"ua",2)); //Ukraine
- table.add(new MccEntry(257,"by",2)); //Belarus (Republic of)
- table.add(new MccEntry(259,"md",2)); //Moldova (Republic of)
- table.add(new MccEntry(260,"pl",2)); //Poland (Republic of)
- table.add(new MccEntry(262,"de",2)); //Germany (Federal Republic of)
- table.add(new MccEntry(266,"gi",2)); //Gibraltar
- table.add(new MccEntry(268,"pt",2)); //Portugal
- table.add(new MccEntry(270,"lu",2)); //Luxembourg
- table.add(new MccEntry(272,"ie",2)); //Ireland
- table.add(new MccEntry(274,"is",2)); //Iceland
- table.add(new MccEntry(276,"al",2)); //Albania (Republic of)
- table.add(new MccEntry(278,"mt",2)); //Malta
- table.add(new MccEntry(280,"cy",2)); //Cyprus (Republic of)
- table.add(new MccEntry(282,"ge",2)); //Georgia
- table.add(new MccEntry(283,"am",2)); //Armenia (Republic of)
- table.add(new MccEntry(284,"bg",2)); //Bulgaria (Republic of)
- table.add(new MccEntry(286,"tr",2)); //Turkey
- table.add(new MccEntry(288,"fo",2)); //Faroe Islands
- table.add(new MccEntry(290,"gl",2)); //Greenland (Denmark)
- table.add(new MccEntry(292,"sm",2)); //San Marino (Republic of)
- table.add(new MccEntry(293,"sl",2)); //Slovenia (Republic of)
+
+ table.add(new MccEntry(202,"gr",2)); //Greece
+ table.add(new MccEntry(204,"nl",2)); //Netherlands (Kingdom of the)
+ table.add(new MccEntry(206,"be",2)); //Belgium
+ table.add(new MccEntry(208,"fr",2)); //France
+ table.add(new MccEntry(212,"mc",2)); //Monaco (Principality of)
+ table.add(new MccEntry(213,"ad",2)); //Andorra (Principality of)
+ table.add(new MccEntry(214,"es",2)); //Spain
+ table.add(new MccEntry(216,"hu",2)); //Hungary (Republic of)
+ table.add(new MccEntry(218,"ba",2)); //Bosnia and Herzegovina
+ table.add(new MccEntry(219,"hr",2)); //Croatia (Republic of)
+ table.add(new MccEntry(220,"rs",2)); //Serbia and Montenegro
+ table.add(new MccEntry(222,"it",2)); //Italy
+ table.add(new MccEntry(225,"va",2)); //Vatican City State
+ table.add(new MccEntry(226,"ro",2)); //Romania
+ table.add(new MccEntry(228,"ch",2)); //Switzerland (Confederation of)
+ table.add(new MccEntry(230,"cz",2)); //Czech Republic
+ table.add(new MccEntry(231,"sk",2)); //Slovak Republic
+ table.add(new MccEntry(232,"at",2)); //Austria
+ table.add(new MccEntry(234,"gb",2)); //United Kingdom of Great Britain and Northern Ireland
+ table.add(new MccEntry(235,"gb",2)); //United Kingdom of Great Britain and Northern Ireland
+ table.add(new MccEntry(238,"dk",2)); //Denmark
+ table.add(new MccEntry(240,"se",2)); //Sweden
+ table.add(new MccEntry(242,"no",2)); //Norway
+ table.add(new MccEntry(244,"fi",2)); //Finland
+ table.add(new MccEntry(246,"lt",2)); //Lithuania (Republic of)
+ table.add(new MccEntry(247,"lv",2)); //Latvia (Republic of)
+ table.add(new MccEntry(248,"ee",2)); //Estonia (Republic of)
+ table.add(new MccEntry(250,"ru",2)); //Russian Federation
+ table.add(new MccEntry(255,"ua",2)); //Ukraine
+ table.add(new MccEntry(257,"by",2)); //Belarus (Republic of)
+ table.add(new MccEntry(259,"md",2)); //Moldova (Republic of)
+ table.add(new MccEntry(260,"pl",2)); //Poland (Republic of)
+ table.add(new MccEntry(262,"de",2)); //Germany (Federal Republic of)
+ table.add(new MccEntry(266,"gi",2)); //Gibraltar
+ table.add(new MccEntry(268,"pt",2)); //Portugal
+ table.add(new MccEntry(270,"lu",2)); //Luxembourg
+ table.add(new MccEntry(272,"ie",2)); //Ireland
+ table.add(new MccEntry(274,"is",2)); //Iceland
+ table.add(new MccEntry(276,"al",2)); //Albania (Republic of)
+ table.add(new MccEntry(278,"mt",2)); //Malta
+ table.add(new MccEntry(280,"cy",2)); //Cyprus (Republic of)
+ table.add(new MccEntry(282,"ge",2)); //Georgia
+ table.add(new MccEntry(283,"am",2)); //Armenia (Republic of)
+ table.add(new MccEntry(284,"bg",2)); //Bulgaria (Republic of)
+ table.add(new MccEntry(286,"tr",2)); //Turkey
+ table.add(new MccEntry(288,"fo",2)); //Faroe Islands
+ table.add(new MccEntry(290,"gl",2)); //Greenland (Denmark)
+ table.add(new MccEntry(292,"sm",2)); //San Marino (Republic of)
+ table.add(new MccEntry(293,"sl",2)); //Slovenia (Republic of)
table.add(new MccEntry(294,"mk",2)); //The Former Yugoslav Republic of Macedonia
- table.add(new MccEntry(295,"li",2)); //Liechtenstein (Principality of)
- table.add(new MccEntry(302,"ca",2)); //Canada
- table.add(new MccEntry(308,"pm",2)); //Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)
- table.add(new MccEntry(310,"us",3)); //United States of America
- table.add(new MccEntry(311,"us",3)); //United States of America
- table.add(new MccEntry(312,"us",3)); //United States of America
- table.add(new MccEntry(313,"us",3)); //United States of America
- table.add(new MccEntry(314,"us",3)); //United States of America
- table.add(new MccEntry(315,"us",3)); //United States of America
- table.add(new MccEntry(316,"us",3)); //United States of America
- table.add(new MccEntry(330,"pr",2)); //Puerto Rico
- table.add(new MccEntry(332,"vi",2)); //United States Virgin Islands
- table.add(new MccEntry(334,"mx",3)); //Mexico
- table.add(new MccEntry(338,"jm",3)); //Jamaica
- table.add(new MccEntry(340,"gp",2)); //Guadeloupe (French Department of)
- table.add(new MccEntry(342,"bb",3)); //Barbados
- table.add(new MccEntry(344,"ag",3)); //Antigua and Barbuda
- table.add(new MccEntry(346,"ky",3)); //Cayman Islands
- table.add(new MccEntry(348,"vg",3)); //British Virgin Islands
- table.add(new MccEntry(350,"bm",2)); //Bermuda
- table.add(new MccEntry(352,"gd",2)); //Grenada
- table.add(new MccEntry(354,"ms",2)); //Montserrat
- table.add(new MccEntry(356,"kn",2)); //Saint Kitts and Nevis
- table.add(new MccEntry(358,"lc",2)); //Saint Lucia
- table.add(new MccEntry(360,"vc",2)); //Saint Vincent and the Grenadines
- table.add(new MccEntry(362,"nl",2)); //Netherlands Antilles
- table.add(new MccEntry(363,"aw",2)); //Aruba
- table.add(new MccEntry(364,"bs",2)); //Bahamas (Commonwealth of the)
- table.add(new MccEntry(365,"ai",3)); //Anguilla
- table.add(new MccEntry(366,"dm",2)); //Dominica (Commonwealth of)
- table.add(new MccEntry(368,"cu",2)); //Cuba
- table.add(new MccEntry(370,"do",2)); //Dominican Republic
- table.add(new MccEntry(372,"ht",2)); //Haiti (Republic of)
- table.add(new MccEntry(374,"tt",2)); //Trinidad and Tobago
- table.add(new MccEntry(376,"tc",2)); //Turks and Caicos Islands
- table.add(new MccEntry(400,"az",2)); //Azerbaijani Republic
- table.add(new MccEntry(401,"kz",2)); //Kazakhstan (Republic of)
- table.add(new MccEntry(402,"bt",2)); //Bhutan (Kingdom of)
- table.add(new MccEntry(404,"in",2)); //India (Republic of)
- table.add(new MccEntry(405,"in",2)); //India (Republic of)
- table.add(new MccEntry(410,"pk",2)); //Pakistan (Islamic Republic of)
- table.add(new MccEntry(412,"af",2)); //Afghanistan
- table.add(new MccEntry(413,"lk",2)); //Sri Lanka (Democratic Socialist Republic of)
- table.add(new MccEntry(414,"mm",2)); //Myanmar (Union of)
- table.add(new MccEntry(415,"lb",2)); //Lebanon
- table.add(new MccEntry(416,"jo",2)); //Jordan (Hashemite Kingdom of)
- table.add(new MccEntry(417,"sy",2)); //Syrian Arab Republic
- table.add(new MccEntry(418,"iq",2)); //Iraq (Republic of)
- table.add(new MccEntry(419,"kw",2)); //Kuwait (State of)
- table.add(new MccEntry(420,"sa",2)); //Saudi Arabia (Kingdom of)
- table.add(new MccEntry(421,"ye",2)); //Yemen (Republic of)
- table.add(new MccEntry(422,"om",2)); //Oman (Sultanate of)
- table.add(new MccEntry(424,"ae",2)); //United Arab Emirates
- table.add(new MccEntry(425,"il",2)); //Israel (State of)
- table.add(new MccEntry(426,"bh",2)); //Bahrain (Kingdom of)
- table.add(new MccEntry(427,"qa",2)); //Qatar (State of)
- table.add(new MccEntry(428,"mn",2)); //Mongolia
- table.add(new MccEntry(429,"np",2)); //Nepal
- table.add(new MccEntry(430,"ae",2)); //United Arab Emirates
- table.add(new MccEntry(431,"ae",2)); //United Arab Emirates
- table.add(new MccEntry(432,"ir",2)); //Iran (Islamic Republic of)
- table.add(new MccEntry(434,"uz",2)); //Uzbekistan (Republic of)
- table.add(new MccEntry(436,"tj",2)); //Tajikistan (Republic of)
- table.add(new MccEntry(437,"kg",2)); //Kyrgyz Republic
- table.add(new MccEntry(438,"tm",2)); //Turkmenistan
- table.add(new MccEntry(440,"jp",2)); //Japan
- table.add(new MccEntry(441,"jp",2)); //Japan
- table.add(new MccEntry(450,"kr",2)); //Korea (Republic of)
- table.add(new MccEntry(452,"vn",2)); //Viet Nam (Socialist Republic of)
- table.add(new MccEntry(454,"hk",2)); //"Hong Kong, China"
- table.add(new MccEntry(455,"mo",2)); //"Macao, China"
- table.add(new MccEntry(456,"kh",2)); //Cambodia (Kingdom of)
- table.add(new MccEntry(457,"la",2)); //Lao People's Democratic Republic
- table.add(new MccEntry(460,"cn",2)); //China (People's Republic of)
- table.add(new MccEntry(461,"cn",2)); //China (People's Republic of)
- table.add(new MccEntry(466,"tw",2)); //"Taiwan, China"
- table.add(new MccEntry(467,"kp",2)); //Democratic People's Republic of Korea
- table.add(new MccEntry(470,"bd",2)); //Bangladesh (People's Republic of)
- table.add(new MccEntry(472,"mv",2)); //Maldives (Republic of)
- table.add(new MccEntry(502,"my",2)); //Malaysia
- table.add(new MccEntry(505,"au",2)); //Australia
- table.add(new MccEntry(510,"id",2)); //Indonesia (Republic of)
- table.add(new MccEntry(514,"tl",2)); //Democratic Republic of Timor-Leste
- table.add(new MccEntry(515,"ph",2)); //Philippines (Republic of the)
- table.add(new MccEntry(520,"th",2)); //Thailand
- table.add(new MccEntry(525,"sg",2)); //Singapore (Republic of)
- table.add(new MccEntry(528,"bn",2)); //Brunei Darussalam
- table.add(new MccEntry(530,"nz",2)); //New Zealand
- table.add(new MccEntry(534,"mp",2)); //Northern Mariana Islands (Commonwealth of the)
- table.add(new MccEntry(535,"gu",2)); //Guam
- table.add(new MccEntry(536,"nr",2)); //Nauru (Republic of)
- table.add(new MccEntry(537,"pg",2)); //Papua New Guinea
- table.add(new MccEntry(539,"to",2)); //Tonga (Kingdom of)
- table.add(new MccEntry(540,"sb",2)); //Solomon Islands
- table.add(new MccEntry(541,"vu",2)); //Vanuatu (Republic of)
- table.add(new MccEntry(542,"fj",2)); //Fiji (Republic of)
- table.add(new MccEntry(543,"wf",2)); //Wallis and Futuna (Territoire franais d'outre-mer)
- table.add(new MccEntry(544,"as",2)); //American Samoa
- table.add(new MccEntry(545,"ki",2)); //Kiribati (Republic of)
- table.add(new MccEntry(546,"nc",2)); //New Caledonia (Territoire franais d'outre-mer)
- table.add(new MccEntry(547,"pf",2)); //French Polynesia (Territoire franais d'outre-mer)
- table.add(new MccEntry(548,"ck",2)); //Cook Islands
- table.add(new MccEntry(549,"ws",2)); //Samoa (Independent State of)
- table.add(new MccEntry(550,"fm",2)); //Micronesia (Federated States of)
- table.add(new MccEntry(551,"mh",2)); //Marshall Islands (Republic of the)
- table.add(new MccEntry(552,"pw",2)); //Palau (Republic of)
- table.add(new MccEntry(602,"eg",2)); //Egypt (Arab Republic of)
- table.add(new MccEntry(603,"dz",2)); //Algeria (People's Democratic Republic of)
- table.add(new MccEntry(604,"ma",2)); //Morocco (Kingdom of)
- table.add(new MccEntry(605,"tn",2)); //Tunisia
- table.add(new MccEntry(606,"ly",2)); //Libya (Socialist People's Libyan Arab Jamahiriya)
- table.add(new MccEntry(607,"gm",2)); //Gambia (Republic of the)
- table.add(new MccEntry(608,"sn",2)); //Senegal (Republic of)
- table.add(new MccEntry(609,"mr",2)); //Mauritania (Islamic Republic of)
- table.add(new MccEntry(610,"ml",2)); //Mali (Republic of)
- table.add(new MccEntry(611,"gn",2)); //Guinea (Republic of)
- table.add(new MccEntry(612,"ci",2)); //Cte d'Ivoire (Republic of)
- table.add(new MccEntry(613,"bf",2)); //Burkina Faso
- table.add(new MccEntry(614,"ne",2)); //Niger (Republic of the)
- table.add(new MccEntry(615,"tg",2)); //Togolese Republic
- table.add(new MccEntry(616,"bj",2)); //Benin (Republic of)
- table.add(new MccEntry(617,"mu",2)); //Mauritius (Republic of)
- table.add(new MccEntry(618,"lr",2)); //Liberia (Republic of)
- table.add(new MccEntry(619,"sl",2)); //Sierra Leone
- table.add(new MccEntry(620,"gh",2)); //Ghana
- table.add(new MccEntry(621,"ng",2)); //Nigeria (Federal Republic of)
- table.add(new MccEntry(622,"td",2)); //Chad (Republic of)
- table.add(new MccEntry(623,"cf",2)); //Central African Republic
- table.add(new MccEntry(624,"cm",2)); //Cameroon (Republic of)
- table.add(new MccEntry(625,"cv",2)); //Cape Verde (Republic of)
- table.add(new MccEntry(626,"st",2)); //Sao Tome and Principe (Democratic Republic of)
- table.add(new MccEntry(627,"gq",2)); //Equatorial Guinea (Republic of)
- table.add(new MccEntry(628,"ga",2)); //Gabonese Republic
- table.add(new MccEntry(629,"cg",2)); //Congo (Republic of the)
- table.add(new MccEntry(630,"cg",2)); //Democratic Republic of the Congo
- table.add(new MccEntry(631,"ao",2)); //Angola (Republic of)
- table.add(new MccEntry(632,"gw",2)); //Guinea-Bissau (Republic of)
- table.add(new MccEntry(633,"sc",2)); //Seychelles (Republic of)
- table.add(new MccEntry(634,"sd",2)); //Sudan (Republic of the)
- table.add(new MccEntry(635,"rw",2)); //Rwanda (Republic of)
- table.add(new MccEntry(636,"et",2)); //Ethiopia (Federal Democratic Republic of)
- table.add(new MccEntry(637,"so",2)); //Somali Democratic Republic
- table.add(new MccEntry(638,"dj",2)); //Djibouti (Republic of)
- table.add(new MccEntry(639,"ke",2)); //Kenya (Republic of)
- table.add(new MccEntry(640,"tz",2)); //Tanzania (United Republic of)
- table.add(new MccEntry(641,"ug",2)); //Uganda (Republic of)
- table.add(new MccEntry(642,"bi",2)); //Burundi (Republic of)
- table.add(new MccEntry(643,"mz",2)); //Mozambique (Republic of)
- table.add(new MccEntry(645,"zm",2)); //Zambia (Republic of)
- table.add(new MccEntry(646,"mg",2)); //Madagascar (Republic of)
- table.add(new MccEntry(647,"re",2)); //Reunion (French Department of)
- table.add(new MccEntry(648,"zw",2)); //Zimbabwe (Republic of)
- table.add(new MccEntry(649,"na",2)); //Namibia (Republic of)
- table.add(new MccEntry(650,"mw",2)); //Malawi
- table.add(new MccEntry(651,"ls",2)); //Lesotho (Kingdom of)
- table.add(new MccEntry(652,"bw",2)); //Botswana (Republic of)
- table.add(new MccEntry(653,"sz",2)); //Swaziland (Kingdom of)
- table.add(new MccEntry(654,"km",2)); //Comoros (Union of the)
- table.add(new MccEntry(655,"za",2)); //South Africa (Republic of)
- table.add(new MccEntry(657,"er",2)); //Eritrea
- table.add(new MccEntry(702,"bz",2)); //Belize
- table.add(new MccEntry(704,"gt",2)); //Guatemala (Republic of)
- table.add(new MccEntry(706,"sv",2)); //El Salvador (Republic of)
- table.add(new MccEntry(708,"hn",3)); //Honduras (Republic of)
- table.add(new MccEntry(710,"ni",2)); //Nicaragua
- table.add(new MccEntry(712,"cr",2)); //Costa Rica
- table.add(new MccEntry(714,"pa",2)); //Panama (Republic of)
- table.add(new MccEntry(716,"pe",2)); //Peru
- table.add(new MccEntry(722,"ar",3)); //Argentine Republic
- table.add(new MccEntry(724,"br",2)); //Brazil (Federative Republic of)
- table.add(new MccEntry(730,"cl",2)); //Chile
- table.add(new MccEntry(732,"co",3)); //Colombia (Republic of)
- table.add(new MccEntry(734,"ve",2)); //Venezuela (Bolivarian Republic of)
- table.add(new MccEntry(736,"bo",2)); //Bolivia (Republic of)
- table.add(new MccEntry(738,"gy",2)); //Guyana
- table.add(new MccEntry(740,"ec",2)); //Ecuador
- table.add(new MccEntry(742,"gf",2)); //French Guiana (French Department of)
- table.add(new MccEntry(744,"py",2)); //Paraguay (Republic of)
- table.add(new MccEntry(746,"sr",2)); //Suriname (Republic of)
- table.add(new MccEntry(748,"uy",2)); //Uruguay (Eastern Republic of)
- table.add(new MccEntry(750,"fk",2)); //Falkland Islands (Malvinas)
+ table.add(new MccEntry(295,"li",2)); //Liechtenstein (Principality of)
+ table.add(new MccEntry(302,"ca",2)); //Canada
+ table.add(new MccEntry(308,"pm",2)); //Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)
+ table.add(new MccEntry(310,"us",3)); //United States of America
+ table.add(new MccEntry(311,"us",3)); //United States of America
+ table.add(new MccEntry(312,"us",3)); //United States of America
+ table.add(new MccEntry(313,"us",3)); //United States of America
+ table.add(new MccEntry(314,"us",3)); //United States of America
+ table.add(new MccEntry(315,"us",3)); //United States of America
+ table.add(new MccEntry(316,"us",3)); //United States of America
+ table.add(new MccEntry(330,"pr",2)); //Puerto Rico
+ table.add(new MccEntry(332,"vi",2)); //United States Virgin Islands
+ table.add(new MccEntry(334,"mx",3)); //Mexico
+ table.add(new MccEntry(338,"jm",3)); //Jamaica
+ table.add(new MccEntry(340,"gp",2)); //Guadeloupe (French Department of)
+ table.add(new MccEntry(342,"bb",3)); //Barbados
+ table.add(new MccEntry(344,"ag",3)); //Antigua and Barbuda
+ table.add(new MccEntry(346,"ky",3)); //Cayman Islands
+ table.add(new MccEntry(348,"vg",3)); //British Virgin Islands
+ table.add(new MccEntry(350,"bm",2)); //Bermuda
+ table.add(new MccEntry(352,"gd",2)); //Grenada
+ table.add(new MccEntry(354,"ms",2)); //Montserrat
+ table.add(new MccEntry(356,"kn",2)); //Saint Kitts and Nevis
+ table.add(new MccEntry(358,"lc",2)); //Saint Lucia
+ table.add(new MccEntry(360,"vc",2)); //Saint Vincent and the Grenadines
+ table.add(new MccEntry(362,"nl",2)); //Netherlands Antilles
+ table.add(new MccEntry(363,"aw",2)); //Aruba
+ table.add(new MccEntry(364,"bs",2)); //Bahamas (Commonwealth of the)
+ table.add(new MccEntry(365,"ai",3)); //Anguilla
+ table.add(new MccEntry(366,"dm",2)); //Dominica (Commonwealth of)
+ table.add(new MccEntry(368,"cu",2)); //Cuba
+ table.add(new MccEntry(370,"do",2)); //Dominican Republic
+ table.add(new MccEntry(372,"ht",2)); //Haiti (Republic of)
+ table.add(new MccEntry(374,"tt",2)); //Trinidad and Tobago
+ table.add(new MccEntry(376,"tc",2)); //Turks and Caicos Islands
+ table.add(new MccEntry(400,"az",2)); //Azerbaijani Republic
+ table.add(new MccEntry(401,"kz",2)); //Kazakhstan (Republic of)
+ table.add(new MccEntry(402,"bt",2)); //Bhutan (Kingdom of)
+ table.add(new MccEntry(404,"in",2)); //India (Republic of)
+ table.add(new MccEntry(405,"in",2)); //India (Republic of)
+ table.add(new MccEntry(410,"pk",2)); //Pakistan (Islamic Republic of)
+ table.add(new MccEntry(412,"af",2)); //Afghanistan
+ table.add(new MccEntry(413,"lk",2)); //Sri Lanka (Democratic Socialist Republic of)
+ table.add(new MccEntry(414,"mm",2)); //Myanmar (Union of)
+ table.add(new MccEntry(415,"lb",2)); //Lebanon
+ table.add(new MccEntry(416,"jo",2)); //Jordan (Hashemite Kingdom of)
+ table.add(new MccEntry(417,"sy",2)); //Syrian Arab Republic
+ table.add(new MccEntry(418,"iq",2)); //Iraq (Republic of)
+ table.add(new MccEntry(419,"kw",2)); //Kuwait (State of)
+ table.add(new MccEntry(420,"sa",2)); //Saudi Arabia (Kingdom of)
+ table.add(new MccEntry(421,"ye",2)); //Yemen (Republic of)
+ table.add(new MccEntry(422,"om",2)); //Oman (Sultanate of)
+ table.add(new MccEntry(424,"ae",2)); //United Arab Emirates
+ table.add(new MccEntry(425,"il",2)); //Israel (State of)
+ table.add(new MccEntry(426,"bh",2)); //Bahrain (Kingdom of)
+ table.add(new MccEntry(427,"qa",2)); //Qatar (State of)
+ table.add(new MccEntry(428,"mn",2)); //Mongolia
+ table.add(new MccEntry(429,"np",2)); //Nepal
+ table.add(new MccEntry(430,"ae",2)); //United Arab Emirates
+ table.add(new MccEntry(431,"ae",2)); //United Arab Emirates
+ table.add(new MccEntry(432,"ir",2)); //Iran (Islamic Republic of)
+ table.add(new MccEntry(434,"uz",2)); //Uzbekistan (Republic of)
+ table.add(new MccEntry(436,"tj",2)); //Tajikistan (Republic of)
+ table.add(new MccEntry(437,"kg",2)); //Kyrgyz Republic
+ table.add(new MccEntry(438,"tm",2)); //Turkmenistan
+ table.add(new MccEntry(440,"jp",2)); //Japan
+ table.add(new MccEntry(441,"jp",2)); //Japan
+ table.add(new MccEntry(450,"kr",2)); //Korea (Republic of)
+ table.add(new MccEntry(452,"vn",2)); //Viet Nam (Socialist Republic of)
+ table.add(new MccEntry(454,"hk",2)); //"Hong Kong, China"
+ table.add(new MccEntry(455,"mo",2)); //"Macao, China"
+ table.add(new MccEntry(456,"kh",2)); //Cambodia (Kingdom of)
+ table.add(new MccEntry(457,"la",2)); //Lao People's Democratic Republic
+ table.add(new MccEntry(460,"cn",2)); //China (People's Republic of)
+ table.add(new MccEntry(461,"cn",2)); //China (People's Republic of)
+ table.add(new MccEntry(466,"tw",2)); //"Taiwan, China"
+ table.add(new MccEntry(467,"kp",2)); //Democratic People's Republic of Korea
+ table.add(new MccEntry(470,"bd",2)); //Bangladesh (People's Republic of)
+ table.add(new MccEntry(472,"mv",2)); //Maldives (Republic of)
+ table.add(new MccEntry(502,"my",2)); //Malaysia
+ table.add(new MccEntry(505,"au",2)); //Australia
+ table.add(new MccEntry(510,"id",2)); //Indonesia (Republic of)
+ table.add(new MccEntry(514,"tl",2)); //Democratic Republic of Timor-Leste
+ table.add(new MccEntry(515,"ph",2)); //Philippines (Republic of the)
+ table.add(new MccEntry(520,"th",2)); //Thailand
+ table.add(new MccEntry(525,"sg",2)); //Singapore (Republic of)
+ table.add(new MccEntry(528,"bn",2)); //Brunei Darussalam
+ table.add(new MccEntry(530,"nz",2)); //New Zealand
+ table.add(new MccEntry(534,"mp",2)); //Northern Mariana Islands (Commonwealth of the)
+ table.add(new MccEntry(535,"gu",2)); //Guam
+ table.add(new MccEntry(536,"nr",2)); //Nauru (Republic of)
+ table.add(new MccEntry(537,"pg",2)); //Papua New Guinea
+ table.add(new MccEntry(539,"to",2)); //Tonga (Kingdom of)
+ table.add(new MccEntry(540,"sb",2)); //Solomon Islands
+ table.add(new MccEntry(541,"vu",2)); //Vanuatu (Republic of)
+ table.add(new MccEntry(542,"fj",2)); //Fiji (Republic of)
+ table.add(new MccEntry(543,"wf",2)); //Wallis and Futuna (Territoire franais d'outre-mer)
+ table.add(new MccEntry(544,"as",2)); //American Samoa
+ table.add(new MccEntry(545,"ki",2)); //Kiribati (Republic of)
+ table.add(new MccEntry(546,"nc",2)); //New Caledonia (Territoire franais d'outre-mer)
+ table.add(new MccEntry(547,"pf",2)); //French Polynesia (Territoire franais d'outre-mer)
+ table.add(new MccEntry(548,"ck",2)); //Cook Islands
+ table.add(new MccEntry(549,"ws",2)); //Samoa (Independent State of)
+ table.add(new MccEntry(550,"fm",2)); //Micronesia (Federated States of)
+ table.add(new MccEntry(551,"mh",2)); //Marshall Islands (Republic of the)
+ table.add(new MccEntry(552,"pw",2)); //Palau (Republic of)
+ table.add(new MccEntry(602,"eg",2)); //Egypt (Arab Republic of)
+ table.add(new MccEntry(603,"dz",2)); //Algeria (People's Democratic Republic of)
+ table.add(new MccEntry(604,"ma",2)); //Morocco (Kingdom of)
+ table.add(new MccEntry(605,"tn",2)); //Tunisia
+ table.add(new MccEntry(606,"ly",2)); //Libya (Socialist People's Libyan Arab Jamahiriya)
+ table.add(new MccEntry(607,"gm",2)); //Gambia (Republic of the)
+ table.add(new MccEntry(608,"sn",2)); //Senegal (Republic of)
+ table.add(new MccEntry(609,"mr",2)); //Mauritania (Islamic Republic of)
+ table.add(new MccEntry(610,"ml",2)); //Mali (Republic of)
+ table.add(new MccEntry(611,"gn",2)); //Guinea (Republic of)
+ table.add(new MccEntry(612,"ci",2)); //Cte d'Ivoire (Republic of)
+ table.add(new MccEntry(613,"bf",2)); //Burkina Faso
+ table.add(new MccEntry(614,"ne",2)); //Niger (Republic of the)
+ table.add(new MccEntry(615,"tg",2)); //Togolese Republic
+ table.add(new MccEntry(616,"bj",2)); //Benin (Republic of)
+ table.add(new MccEntry(617,"mu",2)); //Mauritius (Republic of)
+ table.add(new MccEntry(618,"lr",2)); //Liberia (Republic of)
+ table.add(new MccEntry(619,"sl",2)); //Sierra Leone
+ table.add(new MccEntry(620,"gh",2)); //Ghana
+ table.add(new MccEntry(621,"ng",2)); //Nigeria (Federal Republic of)
+ table.add(new MccEntry(622,"td",2)); //Chad (Republic of)
+ table.add(new MccEntry(623,"cf",2)); //Central African Republic
+ table.add(new MccEntry(624,"cm",2)); //Cameroon (Republic of)
+ table.add(new MccEntry(625,"cv",2)); //Cape Verde (Republic of)
+ table.add(new MccEntry(626,"st",2)); //Sao Tome and Principe (Democratic Republic of)
+ table.add(new MccEntry(627,"gq",2)); //Equatorial Guinea (Republic of)
+ table.add(new MccEntry(628,"ga",2)); //Gabonese Republic
+ table.add(new MccEntry(629,"cg",2)); //Congo (Republic of the)
+ table.add(new MccEntry(630,"cg",2)); //Democratic Republic of the Congo
+ table.add(new MccEntry(631,"ao",2)); //Angola (Republic of)
+ table.add(new MccEntry(632,"gw",2)); //Guinea-Bissau (Republic of)
+ table.add(new MccEntry(633,"sc",2)); //Seychelles (Republic of)
+ table.add(new MccEntry(634,"sd",2)); //Sudan (Republic of the)
+ table.add(new MccEntry(635,"rw",2)); //Rwanda (Republic of)
+ table.add(new MccEntry(636,"et",2)); //Ethiopia (Federal Democratic Republic of)
+ table.add(new MccEntry(637,"so",2)); //Somali Democratic Republic
+ table.add(new MccEntry(638,"dj",2)); //Djibouti (Republic of)
+ table.add(new MccEntry(639,"ke",2)); //Kenya (Republic of)
+ table.add(new MccEntry(640,"tz",2)); //Tanzania (United Republic of)
+ table.add(new MccEntry(641,"ug",2)); //Uganda (Republic of)
+ table.add(new MccEntry(642,"bi",2)); //Burundi (Republic of)
+ table.add(new MccEntry(643,"mz",2)); //Mozambique (Republic of)
+ table.add(new MccEntry(645,"zm",2)); //Zambia (Republic of)
+ table.add(new MccEntry(646,"mg",2)); //Madagascar (Republic of)
+ table.add(new MccEntry(647,"re",2)); //Reunion (French Department of)
+ table.add(new MccEntry(648,"zw",2)); //Zimbabwe (Republic of)
+ table.add(new MccEntry(649,"na",2)); //Namibia (Republic of)
+ table.add(new MccEntry(650,"mw",2)); //Malawi
+ table.add(new MccEntry(651,"ls",2)); //Lesotho (Kingdom of)
+ table.add(new MccEntry(652,"bw",2)); //Botswana (Republic of)
+ table.add(new MccEntry(653,"sz",2)); //Swaziland (Kingdom of)
+ table.add(new MccEntry(654,"km",2)); //Comoros (Union of the)
+ table.add(new MccEntry(655,"za",2)); //South Africa (Republic of)
+ table.add(new MccEntry(657,"er",2)); //Eritrea
+ table.add(new MccEntry(702,"bz",2)); //Belize
+ table.add(new MccEntry(704,"gt",2)); //Guatemala (Republic of)
+ table.add(new MccEntry(706,"sv",2)); //El Salvador (Republic of)
+ table.add(new MccEntry(708,"hn",3)); //Honduras (Republic of)
+ table.add(new MccEntry(710,"ni",2)); //Nicaragua
+ table.add(new MccEntry(712,"cr",2)); //Costa Rica
+ table.add(new MccEntry(714,"pa",2)); //Panama (Republic of)
+ table.add(new MccEntry(716,"pe",2)); //Peru
+ table.add(new MccEntry(722,"ar",3)); //Argentine Republic
+ table.add(new MccEntry(724,"br",2)); //Brazil (Federative Republic of)
+ table.add(new MccEntry(730,"cl",2)); //Chile
+ table.add(new MccEntry(732,"co",3)); //Colombia (Republic of)
+ table.add(new MccEntry(734,"ve",2)); //Venezuela (Bolivarian Republic of)
+ table.add(new MccEntry(736,"bo",2)); //Bolivia (Republic of)
+ table.add(new MccEntry(738,"gy",2)); //Guyana
+ table.add(new MccEntry(740,"ec",2)); //Ecuador
+ table.add(new MccEntry(742,"gf",2)); //French Guiana (French Department of)
+ table.add(new MccEntry(744,"py",2)); //Paraguay (Republic of)
+ table.add(new MccEntry(746,"sr",2)); //Suriname (Republic of)
+ table.add(new MccEntry(748,"uy",2)); //Uruguay (Eastern Republic of)
+ table.add(new MccEntry(750,"fk",2)); //Falkland Islands (Malvinas)
//table.add(new MccEntry(901,"",2)); //"International Mobile, shared code"
Collections.sort(table);
diff --git a/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.aidl b/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.aidl
index c600530a4629..d88d0b721f47 100644
--- a/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.aidl
@@ -16,11 +16,11 @@
package com.android.internal.telephony.gsm;
-/**
+/**
* Used to indicate that the NetworkInfo object is parcelable to aidl.
* This is a simple effort to make NetworkInfo parcelable rather than
* trying to make the conventional containing object (AsyncResult),
- * implement parcelable. This functionality is needed for the
+ * implement parcelable. This functionality is needed for the
* NetworkQueryService to fix 1128695
*/
parcelable NetworkInfo;
diff --git a/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.java b/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.java
index 353524531ace..04fd13e715a7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.java
+++ b/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.java
@@ -57,9 +57,9 @@ public class NetworkInfo implements Parcelable {
return state;
}
- NetworkInfo(String operatorAlphaLong,
- String operatorAlphaShort,
- String operatorNumeric,
+ NetworkInfo(String operatorAlphaLong,
+ String operatorAlphaShort,
+ String operatorNumeric,
State state) {
this.operatorAlphaLong = operatorAlphaLong;
@@ -70,11 +70,11 @@ public class NetworkInfo implements Parcelable {
}
- public NetworkInfo(String operatorAlphaLong,
- String operatorAlphaShort,
- String operatorNumeric,
+ public NetworkInfo(String operatorAlphaLong,
+ String operatorAlphaShort,
+ String operatorNumeric,
String stateString) {
- this (operatorAlphaLong, operatorAlphaShort,
+ this (operatorAlphaLong, operatorAlphaShort,
operatorNumeric, rilStateToState(stateString));
}
@@ -98,27 +98,27 @@ public class NetworkInfo implements Parcelable {
public String toString() {
- return "NetworkInfo " + operatorAlphaLong
- + "/" + operatorAlphaShort
- + "/" + operatorNumeric
+ return "NetworkInfo " + operatorAlphaLong
+ + "/" + operatorAlphaShort
+ + "/" + operatorNumeric
+ "/" + state;
}
-
- /**
+
+ /**
* Parcelable interface implemented below.
* This is a simple effort to make NetworkInfo parcelable rather than
* trying to make the conventional containing object (AsyncResult),
- * implement parcelable. This functionality is needed for the
+ * implement parcelable. This functionality is needed for the
* NetworkQueryService to fix 1128695.
*/
-
+
public int describeContents() {
return 0;
}
- /**
+ /**
* Implement the Parcelable interface.
- * Method to serialize a NetworkInfo object.
+ * Method to serialize a NetworkInfo object.
*/
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(operatorAlphaLong);
@@ -127,9 +127,9 @@ public class NetworkInfo implements Parcelable {
dest.writeSerializable(state);
}
- /**
+ /**
* Implement the Parcelable interface
- * Method to deserialize a NetworkInfo object, or an array thereof.
+ * Method to deserialize a NetworkInfo object, or an array thereof.
*/
public static final Creator<NetworkInfo> CREATOR =
new Creator<NetworkInfo>() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java b/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java
index d5d481adc92a..feb78f81153a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java
+++ b/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java
@@ -19,8 +19,7 @@ package com.android.internal.telephony.gsm;
/**
* {@hide}
*/
-public class PDPContextState
-{
+public class PDPContextState {
public int cid;
public boolean active;
public String type;
diff --git a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
index d8d75e154132..c23fad499029 100644
--- a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
@@ -17,87 +17,23 @@
package com.android.internal.telephony.gsm;
import android.os.*;
-import com.android.internal.telephony.CommandsInterface;
-import android.database.Cursor;
-import android.provider.Telephony;
import android.util.EventLog;
import android.util.Log;
-import java.util.ArrayList;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.DataConnection;
+import com.android.internal.telephony.DataLink;
+import com.android.internal.telephony.RILConstants;
/**
* {@hide}
*/
-public class PdpConnection extends Handler {
+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;
- public enum PdpState {
- ACTIVE, /* has active pdp context */
- ACTIVATING, /* during connecting process */
- INACTIVE; /* has empty pdp context */
-
- public String toString() {
- switch (this) {
- case ACTIVE: return "active";
- case ACTIVATING: return "setting up";
- default: return "inactive";
- }
- }
-
- public boolean isActive() {
- return this == ACTIVE;
- }
-
- public boolean isInactive() {
- return this == INACTIVE;
- }
- }
-
- public enum PdpFailCause {
- NONE,
- BAD_APN,
- BAD_PAP_SECRET,
- BARRED,
- USER_AUTHENTICATION,
- SERVICE_OPTION_NOT_SUPPORTED,
- SERVICE_OPTION_NOT_SUBSCRIBED,
- SIM_LOCKED,
- RADIO_OFF,
- NO_SIGNAL,
- NO_DATA_PLAN,
- RADIO_NOT_AVIALABLE,
- SUSPENED_TEMPORARY,
- RADIO_ERROR_RETRY,
- UNKNOWN;
-
- public boolean isPermanentFail() {
- return (this == RADIO_OFF);
- }
-
- 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";
- case USER_AUTHENTICATION: return "error user autentication";
- case SERVICE_OPTION_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";
- case RADIO_NOT_AVIALABLE: return "radio not available";
- case SUSPENED_TEMPORARY: return "suspend temporary";
- case RADIO_ERROR_RETRY: return "transient radio error";
- default: return "unknown data error";
- }
- }
- }
-
/** 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;
@@ -106,56 +42,20 @@ public class PdpConnection extends Handler {
private static final int PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED = 33;
private static final int PDP_FAIL_RIL_ERROR_UNSPECIFIED = 0xffff;
- //***** Event codes
- private static final int EVENT_SETUP_PDP_DONE = 1;
- private static final int EVENT_GET_LAST_FAIL_DONE = 2;
- private static final int EVENT_LINK_STATE_CHANGED = 3;
- private static final int EVENT_DEACTIVATE_DONE = 4;
- private static final int EVENT_FORCE_RETRY = 5;
-
- //***** Tag IDs for EventLog
- private static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
-
//***** Instance Variables
- private GSMPhone phone;
private String pdp_name;
- private PdpState state;
- private Message onConnectCompleted;
- private Message onDisconnect;
- private int cid;
- private long createTime;
- private long lastFailTime;
- private PdpFailCause lastFailCause;
- private ApnSetting apn;
- private String interfaceName;
- private String ipAddress;
- private String gatewayAddress;
- private String[] dnsServers;
-
- private static final String NULL_IP = "0.0.0.0";
+ protected ApnSetting apn;
// dataLink is only used to support pppd link
DataLink dataLink;
- // receivedDisconnectReq is set when disconnect pdp link during activating
- private boolean receivedDisconnectReq;
//***** Constructor
PdpConnection(GSMPhone phone) {
- this.phone = phone;
- this.state = PdpState.INACTIVE;
- onConnectCompleted = null;
- onDisconnect = null;
- this.cid = -1;
- this.createTime = -1;
- this.lastFailTime = -1;
- this.lastFailCause = PdpFailCause.NONE;
- this.apn = null;
+ super(phone);
this.dataLink = null;
- receivedDisconnectReq = false;
- this.dnsServers = new String[2];
if (SystemProperties.get("ro.radio.use-ppp","no").equals("yes")) {
- dataLink = new PppLink(phone.mDataConnection);
+ dataLink = new PppLink((GsmDataConnectionTracker) phone.mDataConnection, phone);
dataLink.setOnLinkChange(this, EVENT_LINK_STATE_CHANGED, null);
}
}
@@ -172,55 +72,41 @@ public class PdpConnection extends Handler {
setHttpProxy (apn.proxy, apn.port);
- state = PdpState.ACTIVATING;
+ state = State.ACTIVATING;
this.apn = apn;
onConnectCompleted = onCompleted;
createTime = -1;
lastFailTime = -1;
- lastFailCause = PdpFailCause.NONE;
+ lastFailCause = FailCause.NONE;
receivedDisconnectReq = false;
if (FAKE_FAIL) {
// for debug before baseband implement error in setup PDP
if (apn.apn.equalsIgnoreCase("badapn")){
- notifyFail(PdpFailCause.BAD_APN, onConnectCompleted);
+ notifyFail(FailCause.BAD_APN, onConnectCompleted);
return;
}
}
- phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password,
- obtainMessage(EVENT_SETUP_PDP_DONE));
+ phone.mCM.setupDataCall(Integer.toString(RILConstants.GSM_PHONE), null, apn.apn, apn.user,
+ apn.password, obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
}
- void disconnect(Message msg) {
+ protected void disconnect(Message msg) {
onDisconnect = msg;
- if (state == PdpState.ACTIVE) {
+ if (state == State.ACTIVE) {
if (dataLink != null) {
dataLink.disconnect();
}
if (phone.mCM.getRadioState().isOn()) {
- phone.mCM.deactivateDefaultPDP(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
+ phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
}
- } else if (state == PdpState.ACTIVATING) {
+ } else if (state == State.ACTIVATING) {
receivedDisconnectReq = true;
}
}
- private void
- setHttpProxy(String httpProxy, String httpPort) {
- if (httpProxy == null || httpProxy.length() == 0) {
- phone.setSystemProperty("net.gprs.http-proxy", null);
- return;
- }
-
- if (httpPort == null || httpPort.length() == 0) {
- httpPort = "8080"; // Default to port 8080
- }
-
- phone.setSystemProperty("net.gprs.http-proxy",
- "http://" + httpProxy + ":" + httpPort + "/");
- }
public String toString() {
return "State=" + state + " Apn=" + apn +
@@ -228,46 +114,11 @@ public class PdpConnection extends Handler {
" lastFailCause=" + lastFailCause;
}
- public long getConnectionTime() {
- return createTime;
- }
-
- public long getLastFailTime() {
- return lastFailTime;
- }
-
- public PdpFailCause getLastFailCause() {
- return lastFailCause;
- }
-
- public ApnSetting getApn() {
- return apn;
- }
-
- String getInterface() {
- return interfaceName;
- }
-
- String getIpAddress() {
- return ipAddress;
- }
-
- String getGatewayAddress() {
- return gatewayAddress;
- }
-
- String[] getDnsServers() {
- return dnsServers;
- }
- public PdpState getState() {
- return state;
- }
-
- private void notifyFail(PdpFailCause cause, Message onCompleted) {
+ protected void notifyFail(FailCause cause, Message onCompleted) {
if (onCompleted == null) return;
- state = PdpState.INACTIVE;
+ state = State.INACTIVE;
lastFailCause = cause;
lastFailTime = System.currentTimeMillis();
onConnectCompleted = null;
@@ -282,7 +133,7 @@ public class PdpConnection extends Handler {
private void notifySuccess(Message onCompleted) {
if (onCompleted == null) return;
- state = PdpState.ACTIVE;
+ state = State.ACTIVE;
createTime = System.currentTimeMillis();
onConnectCompleted = null;
onCompleted.arg1 = cid;
@@ -293,9 +144,9 @@ public class PdpConnection extends Handler {
onCompleted.sendToTarget();
}
- private void notifyDisconnect(Message msg) {
+ protected void notifyDisconnect(Message msg) {
if (DBG) log("Notify PDP disconnect");
-
+
if (msg != null) {
AsyncResult.forMessage(msg);
msg.sendToTarget();
@@ -303,22 +154,7 @@ public class PdpConnection extends Handler {
clearSettings();
}
- void clearSettings() {
- state = PdpState.INACTIVE;
- receivedDisconnectReq = false;
- createTime = -1;
- lastFailTime = -1;
- lastFailCause = PdpFailCause.NONE;
- apn = null;
- onConnectCompleted = null;
- interfaceName = null;
- ipAddress = null;
- gatewayAddress = null;
- dnsServers[0] = null;
- dnsServers[1] = null;
- }
-
- private void onLinkStateChanged(DataLink.LinkState linkState) {
+ protected void onLinkStateChanged(DataLink.LinkState linkState) {
switch (linkState) {
case LINK_UP:
notifySuccess(onConnectCompleted);
@@ -332,141 +168,107 @@ public class PdpConnection extends Handler {
}
}
- private PdpFailCause getFailCauseFromRequest(int rilCause) {
- PdpFailCause cause;
+ protected FailCause getFailCauseFromRequest(int rilCause) {
+ FailCause cause;
switch (rilCause) {
case PDP_FAIL_RIL_BARRED:
- cause = PdpFailCause.BARRED;
+ cause = FailCause.BARRED;
break;
case PDP_FAIL_RIL_BAD_APN:
- cause = PdpFailCause.BAD_APN;
+ cause = FailCause.BAD_APN;
break;
case PDP_FAIL_RIL_USER_AUTHENTICATION:
- cause = PdpFailCause.USER_AUTHENTICATION;
+ cause = FailCause.USER_AUTHENTICATION;
break;
case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED:
- cause = PdpFailCause.SERVICE_OPTION_NOT_SUPPORTED;
+ cause = FailCause.SERVICE_OPTION_NOT_SUPPORTED;
break;
case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED:
- cause = PdpFailCause.SERVICE_OPTION_NOT_SUBSCRIBED;
+ cause = FailCause.SERVICE_OPTION_NOT_SUBSCRIBED;
break;
default:
- cause = PdpFailCause.UNKNOWN;
+ cause = FailCause.UNKNOWN;
}
return cause;
}
- private void log(String s) {
+ protected void log(String s) {
Log.d(LOG_TAG, "[PdpConnection] " + s);
}
@Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case EVENT_SETUP_PDP_DONE:
- ar = (AsyncResult) msg.obj;
-
- if (ar.exception != null) {
- Log.e(LOG_TAG, "PDP Context Init failed " + ar.exception);
-
- if (receivedDisconnectReq) {
- // Don't bother reporting the error if there's already a
- // pending disconnect request, since DataConnectionTracker
- // has already updated its state.
- notifyDisconnect(onDisconnect);
- } else {
- if ( ar.exception instanceof CommandException &&
- ((CommandException) (ar.exception)).getCommandError()
- == CommandException.Error.RADIO_NOT_AVAILABLE) {
- notifyFail(PdpFailCause.RADIO_NOT_AVIALABLE,
- onConnectCompleted);
- } else {
- phone.mCM.getLastPdpFailCause(
- obtainMessage(EVENT_GET_LAST_FAIL_DONE));
- }
- }
+ protected void onDeactivated(AsyncResult ar) {
+ notifyDisconnect((Message) ar.userObj);
+ if (DBG) log("PDP Connection Deactivated");
+ }
+
+ @Override
+ protected void onSetupConnectionCompleted(AsyncResult ar) {
+ if (ar.exception != null) {
+ Log.e(LOG_TAG, "PDP Context Init failed " + ar.exception);
+
+ if (receivedDisconnectReq) {
+ // Don't bother reporting the error if there's already a
+ // pending disconnect request, since DataConnectionTracker
+ // has already updated its state.
+ notifyDisconnect(onDisconnect);
+ } else {
+ if ( ar.exception instanceof CommandException &&
+ ((CommandException) (ar.exception)).getCommandError()
+ == CommandException.Error.RADIO_NOT_AVAILABLE) {
+ notifyFail(FailCause.RADIO_NOT_AVAILABLE,
+ onConnectCompleted);
} else {
- if (receivedDisconnectReq) {
- // Don't bother reporting success if there's already a
- // pending disconnect request, since DataConnectionTracker
- // has already updated its state.
- disconnect(onDisconnect);
- } else {
- String[] response = ((String[]) ar.result);
- cid = Integer.parseInt(response[0]);
-
- if (response.length > 2) {
- interfaceName = response[1];
- ipAddress = response[2];
- String prefix = "net." + interfaceName + ".";
- gatewayAddress = SystemProperties.get(prefix + "gw");
- dnsServers[0] = SystemProperties.get(prefix + "dns1");
- dnsServers[1] = SystemProperties.get(prefix + "dns2");
- if (DBG) {
- log("interface=" + interfaceName + " ipAddress=" + ipAddress
- + " gateway=" + gatewayAddress + " DNS1=" + dnsServers[0]
- + " DNS2=" + dnsServers[1]);
- }
-
- if (NULL_IP.equals(dnsServers[0]) && NULL_IP.equals(dnsServers[1])) {
- // Work around a race condition where QMI does not fill in DNS:
- // Deactivate PDP and let DataConnectionTracker retry.
- EventLog.writeEvent(EVENT_LOG_BAD_DNS_ADDRESS, dnsServers[0]);
- phone.mCM.deactivateDefaultPDP(cid,
- obtainMessage(EVENT_FORCE_RETRY));
- break;
- }
- }
-
- if (dataLink != null) {
- dataLink.connect();
- } else {
- onLinkStateChanged(DataLink.LinkState.LINK_UP);
- }
-
- if (DBG) log("PDP setup on cid = " + cid);
+ phone.mCM.getLastPdpFailCause(
+ obtainMessage(EVENT_GET_LAST_FAIL_DONE));
+ }
+ }
+ } else {
+ if (receivedDisconnectReq) {
+ // Don't bother reporting success if there's already a
+ // pending disconnect request, since DataConnectionTracker
+ // has already updated its state.
+ disconnect(onDisconnect);
+ } else {
+ String[] response = ((String[]) ar.result);
+ cid = Integer.parseInt(response[0]);
+
+ if (response.length > 2) {
+ interfaceName = response[1];
+ ipAddress = response[2];
+ String prefix = "net." + interfaceName + ".";
+ gatewayAddress = SystemProperties.get(prefix + "gw");
+ dnsServers[0] = SystemProperties.get(prefix + "dns1");
+ dnsServers[1] = SystemProperties.get(prefix + "dns2");
+ if (DBG) {
+ log("interface=" + interfaceName + " ipAddress=" + ipAddress
+ + " gateway=" + gatewayAddress + " DNS1=" + dnsServers[0]
+ + " DNS2=" + dnsServers[1]);
+ }
+
+ if (NULL_IP.equals(dnsServers[0]) && NULL_IP.equals(dnsServers[1])) {
+ // Work around a race condition where QMI does not fill in DNS:
+ // Deactivate PDP and let DataConnectionTracker retry.
+ EventLog.writeEvent(EVENT_LOG_BAD_DNS_ADDRESS, dnsServers[0]);
+ phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_FORCE_RETRY));
+ return;
}
}
- break;
- case EVENT_FORCE_RETRY:
- if (receivedDisconnectReq) {
- notifyDisconnect(onDisconnect);
+
+ if (dataLink != null) {
+ dataLink.connect();
} else {
- ar = (AsyncResult) msg.obj;
- notifyFail(PdpFailCause.RADIO_ERROR_RETRY, onConnectCompleted);
- }
- break;
- case EVENT_GET_LAST_FAIL_DONE:
- if (receivedDisconnectReq) {
- // Don't bother reporting the error if there's already a
- // pending disconnect request, since DataConnectionTracker
- // has already updated its state.
- notifyDisconnect(onDisconnect);
- } else {
- ar = (AsyncResult) msg.obj;
- PdpFailCause cause = PdpFailCause.UNKNOWN;
-
- if (ar.exception == null) {
- int rilFailCause = ((int[]) (ar.result))[0];
- cause = getFailCauseFromRequest(rilFailCause);
- }
- notifyFail(cause, onConnectCompleted);
+ onLinkStateChanged(DataLink.LinkState.LINK_UP);
}
- break;
- case EVENT_LINK_STATE_CHANGED:
- ar = (AsyncResult) msg.obj;
- DataLink.LinkState ls = (DataLink.LinkState) ar.result;
- onLinkStateChanged(ls);
- break;
- case EVENT_DEACTIVATE_DONE:
- ar = (AsyncResult) msg.obj;
- notifyDisconnect((Message) ar.userObj);
- break;
+ if (DBG) log("PDP setup on cid = " + cid);
+ }
}
}
+
+ public ApnSetting getApn() {
+ return this.apn;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/PppLink.java b/telephony/java/com/android/internal/telephony/gsm/PppLink.java
index 43d4f1f91350..96276968add1 100644
--- a/telephony/java/com/android/internal/telephony/gsm/PppLink.java
+++ b/telephony/java/com/android/internal/telephony/gsm/PppLink.java
@@ -16,28 +16,31 @@
package com.android.internal.telephony.gsm;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-
import android.database.Cursor;
import android.os.Message;
import android.os.SystemProperties;
import android.os.SystemService;
-import com.android.internal.telephony.gsm.DataConnectionTracker.State;
-import com.android.internal.util.ArrayUtils;
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 implements DataLinkInterface {
+final class PppLink extends DataLink {
private static final String LOG_TAG = "GSM";
static final String PATH_PPP_OPERSTATE = "/sys/class/net/ppp0/operstate";
@@ -69,11 +72,14 @@ final class PppLink extends DataLink implements DataLinkInterface {
};
private final byte[] mCheckPPPBuffer = new byte[32];
+ private PhoneBase phone;
+
int lastPppdExitCode = EXIT_OK;
- PppLink(DataConnectionTracker dc) {
+ PppLink(GsmDataConnectionTracker dc, GSMPhone p) {
super(dc);
+ this.phone = p;
}
public void connect() {
@@ -131,7 +137,7 @@ final class PppLink extends DataLink implements DataLinkInterface {
checkPPP();
// keep polling in case interface goes down
- if (dataConnection.state != State.IDLE) {
+ if (dataConnection.getState() != State.IDLE) {
Message poll = obtainMessage();
poll.what = EVENT_POLL_DATA_CONNECTION;
sendMessageDelayed(poll, POLL_SYSFS_MILLIS);
@@ -141,7 +147,7 @@ final class PppLink extends DataLink implements DataLinkInterface {
}
private void checkPPP() {
- boolean connecting = (dataConnection.state == State.CONNECTING);
+ boolean connecting = (dataConnection.getState() == State.CONNECTING);
try {
RandomAccessFile file = new RandomAccessFile(PATH_PPP_OPERSTATE, "r");
@@ -152,10 +158,10 @@ final class PppLink extends DataLink implements DataLinkInterface {
// "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.state == State.CONNECTING) {
+ UNKNOWN_ASCII_STRING.length)
+ && dataConnection.getState() == State.CONNECTING) {
- Log.i(LOG_TAG,
+ Log.i(LOG_TAG,
"found ppp interface. Notifying GPRS connected");
if (mLinkChangeRegistrant != null) {
@@ -163,23 +169,23 @@ final class PppLink extends DataLink implements DataLinkInterface {
}
connecting = false;
- } else if (dataConnection.state == State.CONNECTED
+ } else if (dataConnection.getState() == State.CONNECTED
&& ArrayUtils.equals(mCheckPPPBuffer, DOWN_ASCII_STRING,
- DOWN_ASCII_STRING.length)) {
+ DOWN_ASCII_STRING.length)) {
- Log.i(LOG_TAG,
+ 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.state == State.CONNECTED &&
+ if (dataConnection.getState() == State.CONNECTED &&
mLinkChangeRegistrant != null) {
mLinkChangeRegistrant.notifyResult(LinkState.LINK_DOWN);
}
@@ -206,4 +212,8 @@ final class PppLink extends DataLink implements DataLinkInterface {
}
}
+
+ protected void log(String s) {
+ Log.d(LOG_TAG, "[PppLink] " + s);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
index 3c12c37f3c24..ead1327d5d74 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
@@ -16,13 +16,18 @@
package com.android.internal.telephony.gsm;
-import com.android.internal.telephony.*; //TODO Remove *
-import com.android.internal.telephony.gsm.stk.ImageDescriptor;
import android.os.*;
import android.os.AsyncResult;
-import android.os.RegistrantList;
-import android.os.Registrant;
import android.util.Log;
+
+import com.android.internal.telephony.IccConstants;
+import com.android.internal.telephony.IccException;
+import com.android.internal.telephony.IccFileHandler;
+import com.android.internal.telephony.IccFileTypeMismatch;
+import com.android.internal.telephony.IccIoResult;
+import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.PhoneProxy;
+
import java.util.ArrayList;
/**
@@ -32,415 +37,33 @@ public final class SIMFileHandler extends IccFileHandler {
static final String LOG_TAG = "GSM";
//***** Instance Variables
- GSMPhone phone;
-
-
- //***** Inner Classes
-
- static class LoadLinearFixedContext {
-
- int efid;
- int recordNum, recordSize, countRecords;
- boolean loadAll;
-
- Message onLoaded;
-
- ArrayList<byte[]> results;
-
- LoadLinearFixedContext(int efid, int recordNum, Message onLoaded) {
- this.efid = efid;
- this.recordNum = recordNum;
- this.onLoaded = onLoaded;
- this.loadAll = false;
- }
-
- LoadLinearFixedContext(int efid, Message onLoaded) {
- this.efid = efid;
- this.recordNum = 1;
- this.loadAll = true;
- this.onLoaded = onLoaded;
- }
-
- }
-
//***** Constructor
SIMFileHandler(GSMPhone phone) {
- this.phone = phone;
+ super(phone);
}
- //***** Public Methods
-
- /**
- * Load a record from a SIM Linear Fixed EF
- *
- * @param fileid EF id
- * @param recordNum 1-based (not 0-based) record number
- * @param onLoaded
- *
- * ((AsyncResult)(onLoaded.obj)).result is the byte[]
- *
- */
- protected void loadEFLinearFixed(int fileid, int recordNum, Message onLoaded) {
- Message response
- = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
- new LoadLinearFixedContext(fileid, recordNum, onLoaded));
-
- phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
+ public void dispose() {
+ super.dispose();
}
- /**
- * Load a image instance record from a SIM Linear Fixed EF-IMG
- *
- * @param recordNum 1-based (not 0-based) record number
- * @param onLoaded
- *
- * ((AsyncResult)(onLoaded.obj)).result is the byte[]
- *
- */
- public void loadEFImgLinearFixed(int recordNum, Message onLoaded) {
- Message response = obtainMessage(EVENT_READ_IMG_DONE,
- new LoadLinearFixedContext(IccConstants.EF_IMG, recordNum,
- onLoaded));
-
- phone.mCM.iccIO(COMMAND_GET_RESPONSE, IccConstants.EF_IMG, "img",
- recordNum, READ_RECORD_MODE_ABSOLUTE,
- ImageDescriptor.ID_LENGTH, null, null, response);
- }
-
- /**
- * get record size for a linear fixed EF
- *
- * @param fileid EF id
- * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]
- * int[0] is the record length int[1] is the total length of the EF
- * file int[3] is the number of records in the EF file So int[0] *
- * int[3] = int[1]
- */
- protected void getEFLinearRecordSize(int fileid, Message onLoaded) {
- Message response
- = obtainMessage(EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE,
- new LoadLinearFixedContext(fileid, onLoaded));
- phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
- }
-
- /**
- * Load all records from a SIM Linear Fixed EF
- *
- * @param fileid EF id
- * @param onLoaded
- *
- * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
- *
- */
- protected void loadEFLinearFixedAll(int fileid, Message onLoaded) {
- Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
- new LoadLinearFixedContext(fileid,onLoaded));
-
- phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
+ protected void finalize() {
+ Log.d(LOG_TAG, "SIMFileHandler finalized");
}
- /**
- * Load a SIM Transparent EF
- *
- * @param fileid EF id
- * @param onLoaded
- *
- * ((AsyncResult)(onLoaded.obj)).result is the byte[]
- *
- */
-
- protected void loadEFTransparent(int fileid, Message onLoaded) {
- Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
- fileid, 0, onLoaded);
-
- phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
- }
-
- /**
- * Load a SIM Transparent EF-IMG. Used right after loadEFImgLinearFixed to
- * retrive STK's icon data.
- *
- * @param fileid EF id
- * @param onLoaded
- *
- * ((AsyncResult)(onLoaded.obj)).result is the byte[]
- *
- */
- public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset,
- int length, Message onLoaded) {
- Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0,
- onLoaded);
-
- phone.mCM.iccIO(COMMAND_READ_BINARY, fileid, "img", highOffset, lowOffset,
- length, null, null, response);
- }
-
- /**
- * Update a record in a linear fixed EF
- * @param fileid EF id
- * @param recordNum 1-based (not 0-based) record number
- * @param data must be exactly as long as the record in the EF
- * @param pin2 for CHV2 operations, otherwist must be null
- * @param onComplete onComplete.obj will be an AsyncResult
- * onComplete.obj.userObj will be a IccIoResult on success
- */
- protected void updateEFLinearFixed(int fileid, int recordNum, byte[] data,
- String pin2, Message onComplete) {
- phone.mCM.iccIO(COMMAND_UPDATE_RECORD, fileid, null,
- recordNum, READ_RECORD_MODE_ABSOLUTE, data.length,
- IccUtils.bytesToHexString(data), pin2, onComplete);
- }
-
- /**
- * Update a transparent EF
- * @param fileid EF id
- * @param data must be exactly as long as the EF
- */
- protected void updateEFTransparent(int fileid, byte[] data, Message onComplete) {
- phone.mCM.iccIO(COMMAND_UPDATE_BINARY, fileid, null,
- 0, 0, data.length,
- IccUtils.bytesToHexString(data), null, onComplete);
- }
-
- //***** Overridden from Handler
+ //***** Overridden from IccFileHandler
+ @Override
public void handleMessage(Message msg) {
- AsyncResult ar;
- IccIoResult result;
- Message response = null;
- String str;
- LoadLinearFixedContext lc;
-
- IccException iccException;
- byte data[];
- int size;
- int fileid;
- int recordNum;
- int recordSize[];
-
- try {
- switch (msg.what) {
- case EVENT_READ_IMG_DONE:
- ar = (AsyncResult) msg.obj;
- lc = (LoadLinearFixedContext) ar.userObj;
- result = (IccIoResult) ar.result;
- response = lc.onLoaded;
-
- iccException = result.getException();
- if (iccException != null) {
- sendResult(response, result.payload, ar.exception);
- }
- break;
- case EVENT_READ_ICON_DONE:
- ar = (AsyncResult) msg.obj;
- response = (Message) ar.userObj;
- result = (IccIoResult) ar.result;
-
- iccException = result.getException();
- if (iccException != null) {
- sendResult(response, result.payload, ar.exception);
- }
- break;
- case EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE:
- ar = (AsyncResult)msg.obj;
- lc = (LoadLinearFixedContext) ar.userObj;
- result = (IccIoResult) ar.result;
- response = lc.onLoaded;
-
- if (ar.exception != null) {
- sendResult(response, null, ar.exception);
- break;
- }
-
- iccException = result.getException();
- if (iccException != null) {
- sendResult(response, null, iccException);
- break;
- }
-
- data = result.payload;
-
- if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE] ||
- EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
- throw new IccFileTypeMismatch();
- }
-
- recordSize = new int[3];
- recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
- recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
- + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
- recordSize[2] = recordSize[1] / recordSize[0];
-
- sendResult(response, recordSize, null);
- break;
- case EVENT_GET_RECORD_SIZE_DONE:
- ar = (AsyncResult)msg.obj;
- lc = (LoadLinearFixedContext) ar.userObj;
- result = (IccIoResult) ar.result;
- response = lc.onLoaded;
-
- if (ar.exception != null) {
- sendResult(response, null, ar.exception);
- break;
- }
-
- iccException = result.getException();
-
- if (iccException != null) {
- sendResult(response, null, iccException);
- break;
- }
-
- data = result.payload;
- fileid = lc.efid;
- recordNum = lc.recordNum;
-
- if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
- throw new IccFileTypeMismatch();
- }
-
- if (EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
- throw new IccFileTypeMismatch();
- }
-
- lc.recordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
-
- size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
- + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
-
- lc.countRecords = size / lc.recordSize;
-
- if (lc.loadAll) {
- lc.results = new ArrayList<byte[]>(lc.countRecords);
- }
-
- phone.mCM.iccIO(COMMAND_READ_RECORD, lc.efid, null,
- lc.recordNum,
- READ_RECORD_MODE_ABSOLUTE,
- lc.recordSize, null, null,
- obtainMessage(EVENT_READ_RECORD_DONE, lc));
- break;
- case EVENT_GET_BINARY_SIZE_DONE:
- ar = (AsyncResult)msg.obj;
- response = (Message) ar.userObj;
- result = (IccIoResult) ar.result;
-
- if (ar.exception != null) {
- sendResult(response, null, ar.exception);
- break;
- }
-
- iccException = result.getException();
-
- if (iccException != null) {
- sendResult(response, null, iccException);
- break;
- }
-
- data = result.payload;
-
- fileid = msg.arg1;
-
- if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
- throw new IccFileTypeMismatch();
- }
-
- if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) {
- throw new IccFileTypeMismatch();
- }
-
- size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
- + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
-
- phone.mCM.iccIO(COMMAND_READ_BINARY, fileid, null,
- 0, 0, size, null, null,
- obtainMessage(EVENT_READ_BINARY_DONE,
- fileid, 0, response));
- break;
-
- case EVENT_READ_RECORD_DONE:
-
- ar = (AsyncResult)msg.obj;
- lc = (LoadLinearFixedContext) ar.userObj;
- result = (IccIoResult) ar.result;
- response = lc.onLoaded;
-
- if (ar.exception != null) {
- sendResult(response, null, ar.exception);
- break;
- }
-
- iccException = result.getException();
-
- if (iccException != null) {
- sendResult(response, null, iccException);
- break;
- }
-
- if (!lc.loadAll) {
- sendResult(response, result.payload, null);
- } else {
- lc.results.add(result.payload);
-
- lc.recordNum++;
-
- if (lc.recordNum > lc.countRecords) {
- sendResult(response, lc.results, null);
- } else {
- phone.mCM.iccIO(COMMAND_READ_RECORD, lc.efid, null,
- lc.recordNum,
- READ_RECORD_MODE_ABSOLUTE,
- lc.recordSize, null, null,
- obtainMessage(EVENT_READ_RECORD_DONE, lc));
- }
- }
-
- break;
-
- case EVENT_READ_BINARY_DONE:
- ar = (AsyncResult)msg.obj;
- response = (Message) ar.userObj;
- result = (IccIoResult) ar.result;
-
- if (ar.exception != null) {
- sendResult(response, null, ar.exception);
- break;
- }
-
- iccException = result.getException();
-
- if (iccException != null) {
- sendResult(response, null, iccException);
- break;
- }
-
- sendResult(response, result.payload, null);
- break;
-
- }} catch (Exception exc) {
- if (response != null) {
- sendResult(response, null, exc);
- } else {
- Log.e(LOG_TAG, "uncaught exception", exc);
- }
- }
+ super.handleMessage(msg);
}
- //***** Private Methods
-
- private void sendResult(Message response, Object result, Throwable ex) {
- if (response == null) {
- return;
- }
-
- AsyncResult.forMessage(response, result, ex);
+ protected void logd(String msg) {
+ Log.d(LOG_TAG, "[SIMFileHandler] " + msg);
+ }
- response.sendToTarget();
+ protected void loge(String msg) {
+ Log.e(LOG_TAG, "[SIMFileHandler] " + msg);
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 57d76c25c927..e33e556b6d7b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -17,23 +17,26 @@
package com.android.internal.telephony.gsm;
import android.os.AsyncResult;
-import android.os.RegistrantList;
-import android.os.Registrant;
import android.os.Handler;
import android.os.Message;
-import android.telephony.gsm.SmsMessage;
+import android.os.Registrant;
import android.util.Log;
-import java.util.ArrayList;
-import com.android.internal.telephony.IccUtils;
+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.gsm.SimCard;
+import com.android.internal.telephony.gsm.SmsMessage;
import com.android.internal.telephony.IccException;
+import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccRecords;
-import static com.android.internal.telephony.TelephonyProperties.*;
-import com.android.internal.telephony.gsm.SimCard;
+import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.PhoneProxy;
+
+import java.util.ArrayList;
/**
* {@hide}
@@ -47,36 +50,16 @@ public final class SIMRecords extends IccRecords {
//***** Instance Variables
- GSMPhone phone;
- RegistrantList recordsLoadedRegistrants = new RegistrantList();
-
- int recordsToLoad; // number of pending load requests
-
- AdnRecordCache adnCache;
-
VoiceMailConstants mVmConfig;
-
- //***** Cached SIM State; cleared on channel close
- boolean recordsRequested = false; // true if we've made requests for the sim records
+ //***** Cached SIM State; cleared on channel close
String imsi;
- String iccid;
- String msisdn = null; // My mobile number
- String msisdnTag = null;
- String voiceMailNum = null;
- String voiceMailTag = null;
- String newVoiceMailNum = null;
- String newVoiceMailTag = null;
- boolean isVoiceMailFixed = false;
- int countVoiceMessages = 0;
boolean callForwardingEnabled;
- int mncLength = 0; // 0 is used to indicate that the value
- // is not initialized
- int mailboxIndex = 0; // 0 is no mailbox dailing number associated
+
/**
- * Sates only used by getSpnFsm FSM
+ * States only used by getSpnFsm FSM
*/
private Get_Spn_Fsm_State spnState;
@@ -157,9 +140,8 @@ public final class SIMRecords extends IccRecords {
//***** Constructor
- SIMRecords(GSMPhone phone) {
- super(phone);
- this.phone = phone;
+ SIMRecords(GSMPhone p) {
+ super(p);
adnCache = new AdnRecordCache(phone);
@@ -171,19 +153,26 @@ public final class SIMRecords extends IccRecords {
recordsToLoad = 0;
- phone.mCM.registerForSIMReady(this, EVENT_SIM_READY, null);
- phone.mCM.registerForOffOrNotAvailable(
+ p.mCM.registerForSIMReady(this, EVENT_SIM_READY, null);
+ p.mCM.registerForOffOrNotAvailable(
this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- phone.mCM.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
- phone.mCM.setOnIccRefresh(this, EVENT_SIM_REFRESH, null);
+ p.mCM.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
+ p.mCM.setOnIccRefresh(this, EVENT_SIM_REFRESH, null);
// Start off by setting empty state
- onRadioOffOrNotAvailable();
+ onRadioOffOrNotAvailable();
}
- protected AdnRecordCache getAdnCache() {
- return adnCache;
+ public void dispose() {
+ //Unregister for all events
+ phone.mCM.unregisterForSIMReady(this);
+ phone.mCM.unregisterForOffOrNotAvailable( this);
+ phone.mCM.unSetOnIccRefresh(this);
+ }
+
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "SIMRecords finalized");
}
protected void onRadioOffOrNotAvailable() {
@@ -197,7 +186,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;
spn = null;
spdiNetworks = null;
pnnHomeName = null;
@@ -205,9 +194,9 @@ public final class SIMRecords extends IccRecords {
adnCache.reset();
phone.setSystemProperty(PROPERTY_LINE1_VOICE_MAIL_WAITING, null);
- phone.setSystemProperty(PROPERTY_SIM_OPERATOR_NUMERIC, null);
- phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ALPHA, null);
- phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ISO_COUNTRY, null);
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null);
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, null);
+ phone.setSystemProperty(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
@@ -217,14 +206,6 @@ public final class SIMRecords extends IccRecords {
//***** Public Methods
- public void registerForRecordsLoaded(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- recordsLoadedRegistrants.add(r);
-
- if (recordsToLoad == 0 && recordsRequested == true) {
- r.notifyRegistrant(new AsyncResult(null, null, null));
- }
- }
/** Returns null if SIM is not yet ready */
public String getIMSI() {
@@ -274,21 +255,13 @@ public final class SIMRecords extends IccRecords {
}
/**
- * Return Service Provider Name stored in SIM
- * @return null if SIM is not yet ready
- */
- public String getServiceProvideName() {
- return spn;
- }
-
- /**
* Set voice mail number to SIM record
*
* The voice mail number can be stored either in EF_MBDN (TS 51.011) or
* EF_MAILBOX_CPHS (CPHS 4.2)
*
* If EF_MBDN is available, store the voice mail number to EF_MBDN
- *
+ *
* If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
*
* So the voice mail number will be stored in both EFs if both are available
@@ -346,7 +319,7 @@ public final class SIMRecords extends IccRecords {
* Sets the SIM voice message waiting indicator records
* @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
* @param countWaiting The number of messages waiting, if known. Use
- * -1 to indicate that an unknown number of
+ * -1 to indicate that an unknown number of
* messages are waiting
*/
public void
@@ -367,17 +340,17 @@ public final class SIMRecords extends IccRecords {
countVoiceMessages = countWaiting;
- phone.setSystemProperty(PROPERTY_LINE1_VOICE_MAIL_WAITING,
+ phone.setSystemProperty(PROPERTY_LINE1_VOICE_MAIL_WAITING,
(countVoiceMessages != 0) ? "true" : "false");
- phone.notifyMessageWaitingIndicator();
+ ((GSMPhone) phone).notifyMessageWaitingIndicator();
try {
if (efMWIS != null) {
// TS 51.011 10.3.45
// lsb of byte 0 is 'voicemail' status
- efMWIS[0] = (byte)((efMWIS[0] & 0xfe)
+ efMWIS[0] = (byte)((efMWIS[0] & 0xfe)
| (countVoiceMessages == 0 ? 0 : 1));
// byte 1 is the number of voice messages waiting
@@ -389,17 +362,17 @@ public final class SIMRecords extends IccRecords {
efMWIS[1] = (byte) countWaiting;
}
- ((SIMFileHandler)phone.getIccFileHandler()).updateEFLinearFixed(
+ phone.getIccFileHandler().updateEFLinearFixed(
EF_MWIS, 1, efMWIS, null,
obtainMessage (EVENT_UPDATE_DONE, EF_MWIS));
- }
+ }
if (efCPHS_MWI != null) {
// Refer CPHS4_2.WW6 B4.2.3
- efCPHS_MWI[0] = (byte)((efCPHS_MWI[0] & 0xf0)
+ efCPHS_MWI[0] = (byte)((efCPHS_MWI[0] & 0xf0)
| (countVoiceMessages == 0 ? 0x5 : 0xa));
- ((SIMFileHandler)phone.getIccFileHandler()).updateEFTransparent(
+ phone.getIccFileHandler().updateEFTransparent(
EF_VOICE_MAIL_INDICATOR_CPHS, efCPHS_MWI,
obtainMessage (EVENT_UPDATE_DONE, EF_VOICE_MAIL_INDICATOR_CPHS));
}
@@ -409,20 +382,6 @@ public final class SIMRecords extends IccRecords {
}
}
- /** @return true if there are messages waiting, false otherwise. */
- public boolean getVoiceMessageWaiting() {
- return countVoiceMessages != 0;
- }
-
- /**
- * Returns number of voice messages waiting, if available
- * If not available (eg, on an older CPHS SIM) -1 is returned if
- * getVoiceMessageWaiting() is true
- */
- public int getCountVoiceMessages() {
- return countVoiceMessages;
- }
-
public boolean getVoiceCallForwardingFlag() {
return callForwardingEnabled;
}
@@ -436,7 +395,7 @@ public final class SIMRecords extends IccRecords {
phone.setSystemProperty(PROPERTY_LINE1_VOICE_CALL_FORWARDING,
(callForwardingEnabled ? "true" : "false"));
- phone.notifyCallForwardingIndicator();
+ ((GSMPhone) phone).notifyCallForwardingIndicator();
try {
if (mEfCfis != null) {
@@ -450,7 +409,7 @@ public final class SIMRecords extends IccRecords {
// TODO: Should really update other fields in EF_CFIS, eg,
// dialing number. We don't read or use it right now.
- ((SIMFileHandler)phone.getIccFileHandler()).updateEFLinearFixed(
+ phone.getIccFileHandler().updateEFLinearFixed(
EF_CFIS, 1, mEfCfis, null,
obtainMessage (EVENT_UPDATE_DONE, EF_CFIS));
}
@@ -464,7 +423,7 @@ public final class SIMRecords extends IccRecords {
| CFF_UNCONDITIONAL_DEACTIVE);
}
- ((SIMFileHandler)phone.getIccFileHandler()).updateEFTransparent(
+ phone.getIccFileHandler().updateEFTransparent(
EF_CFF_CPHS, mEfCff,
obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS));
}
@@ -530,19 +489,19 @@ public final class SIMRecords extends IccRecords {
case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
onRadioOffOrNotAvailable();
- break;
+ break;
/* IO events */
case EVENT_GET_IMSI_DONE:
isRecordLoadResponse = true;
-
+
ar = (AsyncResult)msg.obj;
if (ar.exception != null) {
Log.e(LOG_TAG, "Exception querying IMSI", ar.exception);
break;
- }
-
+ }
+
imsi = (String) ar.result;
// IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
@@ -551,10 +510,10 @@ public final class SIMRecords extends IccRecords {
Log.e(LOG_TAG, "invalid IMSI " + imsi);
imsi = null;
}
-
+
Log.d(LOG_TAG, "IMSI: " + imsi.substring(0, 6) + "xxxxxxxxx");
- phone.mSimCard.updateImsiConfiguration(imsi);
- phone.mSimCard.broadcastSimStateChangedIntent(
+ ((GSMPhone) phone).mSimCard.updateImsiConfiguration(imsi);
+ ((GSMPhone) phone).mSimCard.broadcastSimStateChangedIntent(
SimCard.INTENT_VALUE_ICC_IMSI, null);
break;
@@ -604,20 +563,20 @@ public final class SIMRecords extends IccRecords {
ar = (AsyncResult)msg.obj;
if (ar.exception != null) {
-
- Log.d(LOG_TAG, "Invalid or missing EF"
+
+ Log.d(LOG_TAG, "Invalid or missing EF"
+ ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? "[MAILBOX]" : "[MBDN]"));
// Bug #645770 fall back to CPHS
// FIXME should use SST to decide
if (msg.what == EVENT_GET_MBDN_DONE) {
- //load CPHS on fail...
+ //load CPHS on fail...
// FIXME right now, only load line1's CPHS voice mail entry
recordsToLoad += 1;
new AdnRecordLoader(phone).loadFromEF(
- EF_MAILBOX_CPHS, EF_EXT1, 1,
+ EF_MAILBOX_CPHS, EF_EXT1, 1,
obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
}
break;
@@ -625,7 +584,8 @@ public final class SIMRecords extends IccRecords {
adn = (AdnRecord)ar.result;
- Log.d(LOG_TAG, "VM: " + adn + ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? " EF[MAILBOX]" : " EF[MBDN]"));
+ Log.d(LOG_TAG, "VM: " + adn +
+ ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? " EF[MAILBOX]" : " EF[MBDN]"));
if (adn.isEmpty() && msg.what == EVENT_GET_MBDN_DONE) {
// Bug #645770 fall back to CPHS
@@ -633,7 +593,7 @@ public final class SIMRecords extends IccRecords {
// FIXME right now, only load line1's CPHS voice mail entry
recordsToLoad += 1;
new AdnRecordLoader(phone).loadFromEF(
- EF_MAILBOX_CPHS, EF_EXT1, 1,
+ EF_MAILBOX_CPHS, EF_EXT1, 1,
obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
break;
@@ -697,13 +657,13 @@ public final class SIMRecords extends IccRecords {
countVoiceMessages = data[1] & 0xff;
if (voiceMailWaiting && countVoiceMessages == 0) {
- // Unknown count = -1
+ // Unknown count = -1
countVoiceMessages = -1;
}
- phone.setSystemProperty(PROPERTY_LINE1_VOICE_MAIL_WAITING,
+ phone.setSystemProperty(PROPERTY_LINE1_VOICE_MAIL_WAITING,
voiceMailWaiting ? "true" : "false");
- phone.notifyMessageWaitingIndicator();
+ ((GSMPhone) phone).notifyMessageWaitingIndicator();
break;
case EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE:
@@ -732,10 +692,10 @@ public final class SIMRecords extends IccRecords {
countVoiceMessages = 0;
}
- phone.setSystemProperty(PROPERTY_LINE1_VOICE_MAIL_WAITING,
- countVoiceMessages != 0
+ phone.setSystemProperty(PROPERTY_LINE1_VOICE_MAIL_WAITING,
+ countVoiceMessages != 0
? "true" : "false");
- phone.notifyMessageWaitingIndicator();
+ ((GSMPhone) phone).notifyMessageWaitingIndicator();
}
break;
@@ -744,13 +704,13 @@ public final class SIMRecords extends IccRecords {
ar = (AsyncResult)msg.obj;
data = (byte[])ar.result;
-
+
if (ar.exception != null) {
break;
- }
+ }
iccid = IccUtils.bcdToString(data, 0, data.length);
-
+
Log.d(LOG_TAG, "iccid: " + iccid);
break;
@@ -819,7 +779,7 @@ public final class SIMRecords extends IccRecords {
phone.setSystemProperty(PROPERTY_LINE1_VOICE_CALL_FORWARDING,
(callForwardingEnabled ? "true" : "false"));
- phone.notifyCallForwardingIndicator();
+ ((GSMPhone) phone).notifyCallForwardingIndicator();
}
break;
@@ -833,7 +793,7 @@ public final class SIMRecords extends IccRecords {
break;
}
- parseEfSpdi(data);
+ parseEfSpdi(data);
break;
case EVENT_UPDATE_DONE:
@@ -857,7 +817,7 @@ public final class SIMRecords extends IccRecords {
for ( ; tlv.isValidObject() ; tlv.nextObject()) {
if (tlv.getTag() == TAG_FULL_NETWORK_NAME) {
- pnnHomeName
+ pnnHomeName
= IccUtils.networkNameToString(
tlv.getData(), 0, tlv.getData().length);
break;
@@ -892,7 +852,8 @@ public final class SIMRecords extends IccRecords {
+ ar.exception + " length " + index.length);
} else {
Log.d(LOG_TAG, "READ EF_SMS RECORD index=" + index[0]);
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFLinearFixed(EF_SMS,index[0],obtainMessage(EVENT_GET_SMS_DONE));
+ phone.getIccFileHandler().loadEFLinearFixed(EF_SMS,index[0],
+ obtainMessage(EVENT_GET_SMS_DONE));
}
break;
@@ -1013,20 +974,20 @@ 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);
phone.setSystemProperty(PROPERTY_LINE1_VOICE_CALL_FORWARDING,
(callForwardingEnabled ? "true" : "false"));
- phone.notifyCallForwardingIndicator();
+ ((GSMPhone) phone).notifyCallForwardingIndicator();
break;
}}catch (RuntimeException exc) {
// I don't want these exceptions to be fatal
Log.w(LOG_TAG, "Exception parsing SIM record", exc);
- } finally {
+ } finally {
// Count up record load responses even if they are fails
if (isRecordLoadResponse) {
onRecordLoaded();
@@ -1039,12 +1000,12 @@ public final class SIMRecords extends IccRecords {
case EF_MBDN:
recordsToLoad++;
new AdnRecordLoader(phone).loadFromEF(EF_MBDN, EF_EXT6,
- mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
+ mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
break;
case EF_MAILBOX_CPHS:
recordsToLoad++;
new AdnRecordLoader(phone).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1,
- 1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
+ 1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
break;
default:
// For now, fetch all records if this is not a
@@ -1060,7 +1021,7 @@ public final class SIMRecords extends IccRecords {
if (result == null || result.length == 0) {
return;
}
-
+
switch ((result[0])) {
case CommandsInterface.SIM_REFRESH_FILE_UPDATED:
// result[1] contains the EFID of the updated file.
@@ -1111,7 +1072,7 @@ public final class SIMRecords extends IccRecords {
Log.i("ENF", "message text " +
message.getMessageBody());
- phone.mSMS.dispatchMessage(message);
+ ((GSMPhone) phone).mSMS.dispatchMessage(message);
}
}
@@ -1146,7 +1107,7 @@ public final class SIMRecords extends IccRecords {
Log.i("ENF", "message text " +
message.getMessageBody());
- phone.mSMS.dispatchMessage(message);
+ ((GSMPhone) phone).mSMS.dispatchMessage(message);
// 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3
// 1 == "received by MS from network; message read"
@@ -1154,8 +1115,8 @@ public final class SIMRecords extends IccRecords {
ba[0] = 1;
if (false) { // XXX writing seems to crash RdoServD
- ((SIMFileHandler)phone.getIccFileHandler()).updateEFLinearFixed(EF_SMS, i, ba, null,
- obtainMessage(EVENT_MARK_SMS_READ_DONE, i));
+ phone.getIccFileHandler().updateEFLinearFixed(EF_SMS,
+ i, ba, null, obtainMessage(EVENT_MARK_SMS_READ_DONE, i));
}
}
}
@@ -1173,19 +1134,17 @@ public final class SIMRecords extends IccRecords {
recordsToLoad = 0;
}
}
-
+
protected void onAllRecordsLoaded() {
Log.d(LOG_TAG, "SIMRecords: record load complete");
// Some fields require more than one SIM record to set
- phone.setSystemProperty(PROPERTY_SIM_OPERATOR_NUMERIC,
- getSIMOperatorNumeric());
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, getSIMOperatorNumeric());
if (imsi != null) {
- phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ISO_COUNTRY,
- MccTable.countryCodeForMcc(
- Integer.parseInt(imsi.substring(0,3))));
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
+ MccTable.countryCodeForMcc(Integer.parseInt(imsi.substring(0,3))));
}
else {
Log.e("SIM", "[SIMRecords] onAllRecordsLoaded: imsi is NULL!");
@@ -1195,13 +1154,13 @@ public final class SIMRecords extends IccRecords {
recordsLoadedRegistrants.notifyRegistrants(
new AsyncResult(null, null, null));
- phone.mSimCard.broadcastSimStateChangedIntent(
+ ((GSMPhone) phone).mSimCard.broadcastSimStateChangedIntent(
SimCard.INTENT_VALUE_ICC_LOADED, null);
}
-
+
//***** Private Methods
-
+
private void setVoiceMailByCountry (String spn) {
if (mVmConfig.containsCarrier(spn)) {
isVoiceMailFixed = true;
@@ -1214,7 +1173,7 @@ public final class SIMRecords extends IccRecords {
/* broadcast intent SIM_READY here so that we can make sure
READY is sent before IMSI ready
*/
- phone.mSimCard.broadcastSimStateChangedIntent(
+ ((GSMPhone) phone).mSimCard.broadcastSimStateChangedIntent(
SimCard.INTENT_VALUE_ICC_READY, null);
fetchSimRecords();
@@ -1222,14 +1181,14 @@ public final class SIMRecords extends IccRecords {
private void fetchSimRecords() {
recordsRequested = true;
+ IccFileHandler iccFh = phone.getIccFileHandler();
- Log.v(LOG_TAG, "SIMRecords:fetchSimRecords " + recordsToLoad);
+ Log.v(LOG_TAG, "SIMRecords:fetchSimRecords " + recordsToLoad);
phone.mCM.getIMSI(obtainMessage(EVENT_GET_IMSI_DONE));
recordsToLoad++;
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFTransparent(EF_ICCID,
- obtainMessage(EVENT_GET_ICCID_DONE));
+ iccFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
recordsToLoad++;
// FIXME should examine EF[MSISDN]'s capability configuration
@@ -1239,17 +1198,14 @@ public final class SIMRecords extends IccRecords {
recordsToLoad++;
// Record number is subscriber profile
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFLinearFixed(EF_MBI, 1,
- obtainMessage(EVENT_GET_MBI_DONE));
+ iccFh.loadEFLinearFixed(EF_MBI, 1, obtainMessage(EVENT_GET_MBI_DONE));
recordsToLoad++;
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFTransparent(EF_AD,
- obtainMessage(EVENT_GET_AD_DONE));
+ iccFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
recordsToLoad++;
// Record number is subscriber profile
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFLinearFixed(EF_MWIS, 1,
- obtainMessage(EVENT_GET_MWIS_DONE));
+ iccFh.loadEFLinearFixed(EF_MWIS, 1, obtainMessage(EVENT_GET_MWIS_DONE));
recordsToLoad++;
@@ -1257,50 +1213,49 @@ public final class SIMRecords extends IccRecords {
// the same info as EF[MWIS]. If both exist, both are updated
// but the EF[MWIS] data is preferred
// Please note this must be loaded after EF[MWIS]
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFTransparent(
- EF_VOICE_MAIL_INDICATOR_CPHS,
+ iccFh.loadEFTransparent(
+ EF_VOICE_MAIL_INDICATOR_CPHS,
obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE));
recordsToLoad++;
// Same goes for Call Forward Status indicator: fetch both
// EF[CFIS] and CPHS-EF, with EF[CFIS] preferred.
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
+ iccFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
recordsToLoad++;
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFTransparent(EF_CFF_CPHS,
- obtainMessage(EVENT_GET_CFF_DONE));
+ iccFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE));
recordsToLoad++;
getSpnFsm(true, null);
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFTransparent(EF_SPDI,
- obtainMessage(EVENT_GET_SPDI_DONE));
+ iccFh.loadEFTransparent(EF_SPDI, obtainMessage(EVENT_GET_SPDI_DONE));
recordsToLoad++;
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFLinearFixed(EF_PNN, 1,
- obtainMessage(EVENT_GET_PNN_DONE));
+ iccFh.loadEFLinearFixed(EF_PNN, 1, obtainMessage(EVENT_GET_PNN_DONE));
recordsToLoad++;
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFTransparent(EF_SST,
- obtainMessage(EVENT_GET_SST_DONE));
+ iccFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
recordsToLoad++;
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFTransparent(EF_INFO_CPHS,
- obtainMessage(EVENT_GET_INFO_CPHS_DONE));
+ iccFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
recordsToLoad++;
// XXX should seek instead of examining them all
if (false) { // XXX
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFLinearFixedAll(EF_SMS,
- obtainMessage(EVENT_GET_ALL_SMS_DONE));
+ iccFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
recordsToLoad++;
}
if (CRASH_RIL) {
- String sms = "0107912160130310f20404d0110041007030208054832b0120ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
+ String sms = "0107912160130310f20404d0110041007030208054832b0120"
+ + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ + "ffffffffffffffffffffffffffffff";
byte[] ba = IccUtils.hexStringToBytes(sms);
- ((SIMFileHandler)phone.getIccFileHandler()).updateEFLinearFixed(EF_SMS, 1, ba, null,
+ iccFh.updateEFLinearFixed(EF_SMS, 1, ba, null,
obtainMessage(EVENT_MARK_SMS_READ_DONE, 1));
}
}
@@ -1387,7 +1342,7 @@ public final class SIMRecords extends IccRecords {
case INIT:
spn = null;
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFTransparent( EF_SPN,
+ phone.getIccFileHandler().loadEFTransparent( EF_SPN,
obtainMessage(EVENT_GET_SPN_DONE));
recordsToLoad++;
@@ -1401,16 +1356,16 @@ public final class SIMRecords extends IccRecords {
if (DBG) log("Load EF_SPN: " + spn
+ " spnDisplayCondition: " + spnDisplayCondition);
- phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ALPHA, spn);
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, spn);
spnState = Get_Spn_Fsm_State.IDLE;
} else {
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFTransparent( EF_SPN_CPHS,
+ phone.getIccFileHandler().loadEFTransparent( EF_SPN_CPHS,
obtainMessage(EVENT_GET_SPN_DONE));
recordsToLoad++;
spnState = Get_Spn_Fsm_State.READ_SPN_CPHS;
-
+
// See TS 51.011 10.3.11. Basically, default to
// show PLMN always, and SPN also if roaming.
spnDisplayCondition = -1;
@@ -1423,12 +1378,12 @@ public final class SIMRecords extends IccRecords {
data, 0, data.length - 1 );
if (DBG) log("Load EF_SPN_CPHS: " + spn);
- phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ALPHA, spn);
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, spn);
spnState = Get_Spn_Fsm_State.IDLE;
} else {
- ((SIMFileHandler)phone.getIccFileHandler()).loadEFTransparent( EF_SPN_SHORT_CPHS,
- obtainMessage(EVENT_GET_SPN_DONE));
+ phone.getIccFileHandler().loadEFTransparent(
+ EF_SPN_SHORT_CPHS, obtainMessage(EVENT_GET_SPN_DONE));
recordsToLoad++;
spnState = Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS;
@@ -1441,7 +1396,7 @@ public final class SIMRecords extends IccRecords {
data, 0, data.length - 1);
if (DBG) log("Load EF_SPN_SHORT_CPHS: " + spn);
- phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ALPHA, spn);
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, spn);
}else {
if (DBG) log("No SPN loaded in either CHPS or 3GPP");
}
@@ -1479,7 +1434,7 @@ public final class SIMRecords extends IccRecords {
spdiNetworks = new ArrayList<String>(plmnEntries.length / 3);
for (int i = 0 ; i + 2 < plmnEntries.length ; i += 3) {
- String plmnCode;
+ String plmnCode;
plmnCode = IccUtils.bcdToString(plmnEntries, i, 3);
// Valid operator codes are 5 or 6 digits
@@ -1498,7 +1453,9 @@ public final class SIMRecords extends IccRecords {
return ((mCphsInfo[1] & CPHS_SST_MBN_MASK) == CPHS_SST_MBN_ENABLED );
}
- private void log(String s) {
+ protected void log(String s) {
Log.d(LOG_TAG, "[SIMRecords] " + s);
}
+
}
+
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimCard.java b/telephony/java/com/android/internal/telephony/gsm/SimCard.java
index 4d5e74d0fce8..9af3aa6a2e1f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimCard.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimCard.java
@@ -16,6 +16,9 @@
package com.android.internal.telephony.gsm;
+import android.app.ActivityManagerNative;
+import android.content.Intent;
+import android.content.res.Configuration;
import android.os.AsyncResult;
import android.os.RemoteException;
import android.os.Handler;
@@ -26,28 +29,28 @@ import android.util.Log;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.TelephonyIntents;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.app.ActivityManagerNative;
+import com.android.internal.telephony.TelephonyProperties;
import static android.Manifest.permission.READ_PHONE_STATE;
/**
+ * Note: this class shares common code with RuimCard, consider a base class to minimize code
+ * duplication.
* {@hide}
*/
public final class SimCard extends Handler implements IccCard {
static final String LOG_TAG="GSM";
-
+
//***** Instance Variables
private static final boolean DBG = true;
private GSMPhone phone;
private CommandsInterface.IccStatus status = null;
private boolean mDesiredPinLocked;
- private boolean mDesiredFdnEnabled;
+ private boolean mDesiredFdnEnabled;
private boolean mSimPinLocked = true; // Default to locked
private boolean mSimFdnEnabled = false; // Default to disabled.
// Will be updated when SIM_READY.
@@ -88,7 +91,18 @@ public final class SimCard extends Handler implements IccCard {
updateStateProperty();
}
-
+
+ public void dispose() {
+ //Unregister for all events
+ phone.mCM.unregisterForSIMLockedOrAbsent(this);
+ phone.mCM.unregisterForOffOrNotAvailable(this);
+ phone.mCM.unregisterForSIMReady(this);
+ }
+
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "SimCard finalized");
+ }
+
//***** SimCard implementation
public State
@@ -138,7 +152,7 @@ public final class SimCard extends Handler implements IccCard {
r.notifyRegistrant();
}
}
-
+
public void unregisterForAbsent(Handler h) {
absentRegistrants.remove(h);
}
@@ -156,7 +170,7 @@ public final class SimCard extends Handler implements IccCard {
public void unregisterForNetworkLocked(Handler h) {
networkLockedRegistrants.remove(h);
}
-
+
public void registerForLocked(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
@@ -173,7 +187,7 @@ public final class SimCard extends Handler implements IccCard {
public void supplyPin (String pin, Message onComplete) {
- phone.mCM.supplyIccPin(pin,
+ phone.mCM.supplyIccPin(pin,
obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
@@ -182,7 +196,7 @@ public final class SimCard extends Handler implements IccCard {
obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPin2 (String pin2, Message onComplete) {
- phone.mCM.supplyIccPin2(pin2,
+ phone.mCM.supplyIccPin2(pin2,
obtainMessage(EVENT_PINPUK_DONE, onComplete));
}
public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
@@ -250,7 +264,7 @@ public final class SimCard extends Handler implements IccCard {
}
public String getServiceProviderName () {
- return phone.mSIMRecords.getServiceProvideName();
+ return phone.mSIMRecords.getServiceProviderName();
}
//***** Handler implementation
@@ -413,7 +427,7 @@ public final class SimCard extends Handler implements IccCard {
return;
}
- CommandsInterface.IccStatus newStatus
+ CommandsInterface.IccStatus newStatus
= (CommandsInterface.IccStatus) ar.result;
handleSimStatus(newStatus);
@@ -424,7 +438,7 @@ public final class SimCard extends Handler implements IccCard {
boolean transitionedIntoPinLocked;
boolean transitionedIntoAbsent;
boolean transitionedIntoNetworkLocked;
-
+
SimCard.State oldState, newState;
oldState = getState();
@@ -443,7 +457,7 @@ public final class SimCard extends Handler implements IccCard {
if (transitionedIntoPinLocked) {
if(DBG) log("Notify SIM pin or puk locked.");
pinLockedRegistrants.notifyRegistrants();
- broadcastSimStateChangedIntent(SimCard.INTENT_VALUE_ICC_LOCKED,
+ broadcastSimStateChangedIntent(SimCard.INTENT_VALUE_ICC_LOCKED,
(newState == State.PIN_REQUIRED) ?
INTENT_VALUE_LOCKED_ON_PIN : INTENT_VALUE_LOCKED_ON_PUK);
} else if (transitionedIntoAbsent) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
index e65fa36d763e..076da6bcf68c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
@@ -25,261 +25,77 @@ import android.os.ServiceManager;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
-import java.util.ArrayList;
-import java.util.List;
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
import com.android.internal.telephony.AdnRecord;
import com.android.internal.telephony.AdnRecordCache;
+import com.android.internal.telephony.IccPhoneBookInterfaceManager;
+import com.android.internal.telephony.PhoneProxy;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* SimPhoneBookInterfaceManager to provide an inter-process communication to
* access ADN-like SIM records.
*/
-public class SimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
- static final String LOG_TAG = "GSM";
- static final boolean DBG = false;
- private GSMPhone phone;
- private AdnRecordCache adnCache;
- private final Object mLock = new Object();
- private int recordSize[];
- private boolean success;
- private List<AdnRecord> records;
- private static final boolean ALLOW_SIM_OP_IN_UI_THREAD = false;
+public class SimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
+ static final String LOG_TAG = "GSM";
- private static final int EVENT_GET_SIZE_DONE = 1;
- private static final int EVENT_LOAD_DONE = 2;
- private static final int EVENT_UPDATE_DONE = 3;
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
- switch (msg.what) {
- case EVENT_GET_SIZE_DONE:
- ar = (AsyncResult) msg.obj;
- synchronized (mLock) {
- if (ar.exception == null) {
- recordSize = (int[])ar.result;
- // recordSize[0] is the record length
- // recordSize[1] is the total length of the EF file
- // recordSize[2] is the number of records in the EF file
- log("GET_RECORD_SIZE Size " + recordSize[0] +
- " total " + recordSize[1] +
- " #record " + recordSize[2]);
- mLock.notifyAll();
- }
- }
- break;
- case EVENT_UPDATE_DONE:
- ar = (AsyncResult) msg.obj;
- synchronized (mLock) {
- success = (ar.exception == null);
- mLock.notifyAll();
- }
- break;
- case EVENT_LOAD_DONE:
- ar = (AsyncResult)msg.obj;
- synchronized (mLock) {
- if (ar.exception == null) {
- records = (List<AdnRecord>)
- ((ArrayList<AdnRecord>) ar.result);
- } else {
- if(DBG) log("Cannot load ADN records");
- if (records != null) {
- records.clear();
- }
- }
- mLock.notifyAll();
- }
+ switch(msg.what) {
+ default:
+ mBaseHandler.handleMessage(msg);
break;
}
}
};
public SimPhoneBookInterfaceManager(GSMPhone phone) {
- this.phone = phone;
+ super(phone);
adnCache = phone.mSIMRecords.getAdnCache();
- //publish(); //TODO REMOVE
- }
-
- private void publish() {
- // TODO T: Do we have to change the service
- // as well to "iccphonebook"?
- // defined in: device/commands/binder/Service_info.c
- ServiceManager.addService("simphonebook", this);
+ //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
}
- /**
- * Replace oldAdn with newAdn in ADN-like record in EF
- *
- * getAdnRecordsInEf must be called at least once before this function,
- * otherwise an error will be returned
- * throws SecurityException if no WRITE_CONTACTS permission
- *
- * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
- * @param oldTag adn tag to be replaced
- * @param oldPhoneNumber adn number to be replaced
- * Set both oldTag and oldPhoneNubmer to "" means to replace an
- * empty record, aka, insert new record
- * @param newTag adn tag to be stored
- * @param newPhoneNumber adn number ot be stored
- * Set both newTag and newPhoneNubmer to "" means to replace the old
- * record with empty one, aka, delete old record
- * @param pin2 required to update EF_FDN, otherwise must be null
- * @return true for success
- */
- public boolean
- updateAdnRecordsInEfBySearch (int efid,
- String oldTag, String oldPhoneNumber,
- String newTag, String newPhoneNumber, String pin2) {
-
-
- if (phone.getContext().checkCallingOrSelfPermission(
- android.Manifest.permission.WRITE_CONTACTS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(
- "Requires android.permission.WRITE_CONTACTS permission");
- }
-
-
- if (DBG) log("updateAdnRecordsInEfBySearch: efid=" + efid +
- " ("+ oldTag + "," + oldPhoneNumber + ")"+ "==>" +
- " ("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
- synchronized(mLock) {
- checkThread();
- success = false;
- Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
- AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
- AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
- adnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to update by search");
- }
- }
- return success;
+ public void dispose() {
+ super.dispose();
}
- /**
- * Update an ADN-like EF record by record index
- *
- * This is useful for iteration the whole ADN file, such as write the whole
- * phone book or erase/format the whole phonebook
- * throws SecurityException if no WRITE_CONTACTS permission
- *
- * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
- * @param newTag adn tag to be stored
- * @param newPhoneNumber adn number to be stored
- * Set both newTag and newPhoneNubmer to "" means to replace the old
- * record with empty one, aka, delete old record
- * @param index is 1-based adn record index to be updated
- * @param pin2 required to update EF_FDN, otherwise must be null
- * @return true for success
- */
- public boolean
- updateAdnRecordsInEfByIndex(int efid, String newTag,
- String newPhoneNumber, int index, String pin2) {
-
- if (phone.getContext().checkCallingOrSelfPermission(
- android.Manifest.permission.WRITE_CONTACTS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(
- "Requires android.permission.WRITE_CONTACTS permission");
- }
-
- if (DBG) log("updateAdnRecordsInEfByIndex: efid=" + efid +
- " Index=" + index + " ==> " +
- "("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
- synchronized(mLock) {
- checkThread();
- success = false;
- Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
- AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
- adnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to update by index");
- }
- }
- return success;
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "SimPhoneBookInterfaceManager finalized");
}
- /**
- * Get the capacity of records in efid
- *
- * @param efid the EF id of a ADN-like SIM
- * @return int[3] array
- * recordSizes[0] is the single record length
- * recordSizes[1] is the total length of the EF file
- * recordSizes[2] is the number of records in the EF file
- */
public int[] getAdnRecordsSize(int efid) {
- if (DBG) log("getAdnRecordsSize: efid=" + efid);
+ if (DBG) logd("getAdnRecordsSize: efid=" + efid);
synchronized(mLock) {
checkThread();
recordSize = new int[3];
- Message response = mHandler.obtainMessage(EVENT_GET_SIZE_DONE);
- ((SIMFileHandler)phone.getIccFileHandler()).getEFLinearRecordSize(efid, response);
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to load from the SIM");
- }
- }
-
- return recordSize;
- }
- /**
- * Loads the AdnRecords in efid and returns them as a
- * List of AdnRecords
- *
- * throws SecurityException if no READ_CONTACTS permission
- *
- * @param efid the EF id of a ADN-like SIM
- * @return List of AdnRecord
- */
- public List<AdnRecord> getAdnRecordsInEf(int efid) {
-
- if (phone.getContext().checkCallingOrSelfPermission(
- android.Manifest.permission.READ_CONTACTS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(
- "Requires android.permission.READ_CONTACTS permission");
- }
+ //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
+ Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE);
- if (DBG) log("getAdnRecordsInEF: efid=" + efid);
-
- synchronized(mLock) {
- checkThread();
- Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
- adnCache.requestLoadAllAdnLike(efid, response);
+ phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to load from the SIM");
+ logd("interrupted while trying to load from the SIM");
}
}
- return records;
- }
- private void checkThread() {
- if (!ALLOW_SIM_OP_IN_UI_THREAD) {
- // Make sure this isn't the UI thread, since it will block
- if (mHandler.getLooper().equals(Looper.myLooper())) {
- Log.e(LOG_TAG, "query() called on the main UI thread!");
- throw new IllegalStateException(
- "You cannot call query on this provder from the main UI thread.");
- }
- }
+ return recordSize;
}
- private void log(String msg) {
+ protected void logd(String msg) {
Log.d(LOG_TAG, "[SimPbInterfaceManager] " + msg);
}
+
+ protected void loge(String msg) {
+ Log.e(LOG_TAG, "[SimPbInterfaceManager] " + msg);
+ }
}
+
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
index 26163eb4f6bc..875d8d01f81a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
@@ -16,21 +16,22 @@
package com.android.internal.telephony.gsm;
-import android.app.PendingIntent;
import android.content.Context;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
-import android.os.ServiceManager;
-import android.telephony.gsm.SmsManager;
import android.util.Log;
+import com.android.internal.telephony.IccConstants;
+import com.android.internal.telephony.IccSmsInterfaceManager;
+import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.PhoneProxy;
+import com.android.internal.telephony.SmsRawData;
+
import java.util.ArrayList;
import java.util.List;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccSmsInterfaceManager;
+import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
/**
* SimSmsInterfaceManager to provide an inter-process communication to
@@ -38,9 +39,8 @@ import com.android.internal.telephony.IccSmsInterfaceManager;
*/
public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
static final String LOG_TAG = "GSM";
- static final boolean DBG = false;
+ static final boolean DBG = true;
- private GSMPhone mPhone;
private final Object mLock = new Object();
private boolean mSuccess;
private List<SmsRawData> mSms;
@@ -80,33 +80,31 @@ public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
};
public SimSmsInterfaceManager(GSMPhone phone) {
- this.mPhone = phone;
- //ServiceManager.addService("isms", this); //TODO REMOVE
+ super(phone);
+ mDispatcher = new GsmSMSDispatcher(phone);
}
- private void enforceReceiveAndSend(String message) {
- Context context = mPhone.getContext();
+ public void dispose() {
+ }
- context.enforceCallingPermission(
- "android.permission.RECEIVE_SMS", message);
- context.enforceCallingPermission(
- "android.permission.SEND_SMS", message);
+ protected void finalize() {
+ if(DBG) Log.d(LOG_TAG, "SimSmsInterfaceManager finalized");
}
/**
* Update the specified message on the SIM.
*
* @param index record index of message to update
- * @param status new message status (STATUS_ON_SIM_READ,
- * STATUS_ON_SIM_UNREAD, STATUS_ON_SIM_SENT,
- * STATUS_ON_SIM_UNSENT, STATUS_ON_SIM_FREE)
+ * @param status new message status (STATUS_ON_ICC_READ,
+ * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
+ * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
* @param pdu the raw PDU to store
* @return success or not
*
*/
public boolean
- updateMessageOnSimEf(int index, int status, byte[] pdu) {
- if (DBG) log("updateMessageOnSimEf: index=" + index +
+ updateMessageOnIccEf(int index, int status, byte[] pdu) {
+ if (DBG) log("updateMessageOnIccEf: index=" + index +
" status=" + status + " ==> " +
"("+ pdu + ")");
enforceReceiveAndSend("Updating message on SIM");
@@ -114,13 +112,13 @@ public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
mSuccess = false;
Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
- if (status == SmsManager.STATUS_ON_SIM_FREE) {
+ if (status == STATUS_ON_ICC_FREE) {
// Special case FREE: call deleteSmsOnSim instead of
// manipulating the SIM record
mPhone.mCM.deleteSmsOnSim(index, response);
} else {
byte[] record = makeSmsRecordData(status, pdu);
- ((SIMFileHandler)mPhone.getIccFileHandler()).updateEFLinearFixed(
+ ((SIMFileHandler)mPhone.getIccFileHandler()).updateEFLinearFixed(
IccConstants.EF_SMS,
index, record, null, response);
}
@@ -137,13 +135,13 @@ public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
* Copy a raw SMS PDU to the SIM.
*
* @param pdu the raw PDU to store
- * @param status message status (STATUS_ON_SIM_READ, STATUS_ON_SIM_UNREAD,
- * STATUS_ON_SIM_SENT, STATUS_ON_SIM_UNSENT)
+ * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
+ * STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
* @return success or not
*
*/
- public boolean copyMessageToSimEf(int status, byte[] pdu, byte[] smsc) {
- if (DBG) log("copyMessageToSimEf: status=" + status + " ==> " +
+ public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
+ if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
"pdu=("+ pdu + "), smsm=(" + smsc +")");
enforceReceiveAndSend("Copying message to SIM");
synchronized(mLock) {
@@ -163,11 +161,11 @@ public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
}
/**
- * Retrieves all messages currently stored on SIM.
+ * Retrieves all messages currently stored on ICC.
*
- * @return list of SmsRawData of all sms on SIM
+ * @return list of SmsRawData of all sms on ICC
*/
- public List<SmsRawData> getAllMessagesFromSimEf() {
+ public List<SmsRawData> getAllMessagesFromIccEf() {
if (DBG) log("getAllMessagesFromEF");
Context context = mPhone.getContext();
@@ -189,119 +187,7 @@ public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
return mSms;
}
- /**
- * Send a Raw PDU SMS
- *
- * @param smsc the SMSC to send the message through, or NULL for the
- * defatult SMSC
- * @param pdu the raw PDU to send
- * @param sentIntent if not NULL this <code>Intent</code> is
- * broadcast when the message is sucessfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:
- * <code>RESULT_ERROR_GENERIC_FAILURE</code>
- * <code>RESULT_ERROR_RADIO_OFF</code>
- * <code>RESULT_ERROR_NULL_PDU</code>.
- * @param deliveryIntent if not NULL this <code>Intent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- */
- public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent) {
- Context context = mPhone.getContext();
-
- context.enforceCallingPermission(
- "android.permission.SEND_SMS",
- "Sending SMS message");
- if (DBG) log("sendRawPdu: smsc=" + smsc +
- " pdu="+ pdu + " sentIntent" + sentIntent +
- " deliveryIntent" + deliveryIntent);
- mPhone.mSMS.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
- }
-
- /**
- * Send a multi-part text based SMS.
- *
- * @param destinationAddress the address to send the message to
- * @param scAddress is the service center address or null to use
- * the current default SMSC
- * @param parts an <code>ArrayList</code> of strings that, in order,
- * comprise the original message
- * @param sentIntents if not null, an <code>ArrayList</code> of
- * <code>PendingIntent</code>s (one for each message part) that is
- * broadcast when the corresponding message part has been sent.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:
- * <code>RESULT_ERROR_GENERIC_FAILURE</code>
- * <code>RESULT_ERROR_RADIO_OFF</code>
- * <code>RESULT_ERROR_NULL_PDU</code>.
- * @param deliveryIntents if not null, an <code>ArrayList</code> of
- * <code>PendingIntent</code>s (one for each message part) that is
- * broadcast when the corresponding message part has been delivered
- * to the recipient. The raw pdu of the status report is in the
- * extended data ("pdu").
- */
- public void sendMultipartText(String destinationAddress, String scAddress, List<String> parts,
- List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
- Context context = mPhone.getContext();
-
- context.enforceCallingPermission(
- "android.permission.SEND_SMS",
- "Sending SMS message");
- if (DBG) log("sendMultipartText");
- mPhone.mSMS.sendMultipartText(destinationAddress, scAddress, (ArrayList<String>) parts,
- (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents);
- }
-
- /**
- * Generates an EF_SMS record from status and raw PDU.
- *
- * @param status Message status. See TS 51.011 10.5.3.
- * @param pdu Raw message PDU.
- * @return byte array for the record.
- */
- private byte[] makeSmsRecordData(int status, byte[] pdu) {
- byte[] data = new byte[IccConstants.SMS_RECORD_LENGTH];
-
- // Status bits for this record. See TS 51.011 10.5.3
- data[0] = (byte)(status & 7);
-
- System.arraycopy(pdu, 0, data, 1, pdu.length);
-
- // Pad out with 0xFF's.
- for (int j = pdu.length+1; j < IccConstants.SMS_RECORD_LENGTH; j++) {
- data[j] = -1;
- }
-
- return data;
- }
-
- /**
- * create SmsRawData lists from all sms record byte[]
- * Use null to indicate "free" record
- *
- * @param messages List of message records from EF_SMS.
- * @return SmsRawData list of all in-used records
- */
- private ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) {
- int count = messages.size();
- ArrayList<SmsRawData> ret;
-
- ret = new ArrayList<SmsRawData>(count);
-
- for (int i = 0; i < count; i++) {
- byte[] ba = messages.get(i);
- if (ba[0] == 0) {
- ret.add(null);
- } else {
- ret.add(new SmsRawData(messages.get(i)));
- }
- }
-
- return ret;
- }
-
- private void log(String msg) {
+ protected void log(String msg) {
Log.d(LOG_TAG, "[SimSmsInterfaceManager] " + msg);
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimTlv.java b/telephony/java/com/android/internal/telephony/gsm/SimTlv.java
index 00879ce657b6..30543c7becd1 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimTlv.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimTlv.java
@@ -34,9 +34,8 @@ public class SimTlv
int curDataOffset;
int curDataLength;
boolean hasValidTlvObject;
-
- public SimTlv(byte[] record, int offset, int length)
- {
+
+ public SimTlv(byte[] record, int offset, int length) {
this.record = record;
this.tlvOffset = offset;
@@ -46,19 +45,15 @@ public class SimTlv
hasValidTlvObject = parseCurrentTlvObject();
}
- public boolean
- nextObject()
- {
+ public boolean nextObject() {
if (!hasValidTlvObject) return false;
curOffset = curDataOffset + curDataLength;
- hasValidTlvObject = parseCurrentTlvObject();
+ hasValidTlvObject = parseCurrentTlvObject();
return hasValidTlvObject;
}
- public boolean
- isValidObject()
- {
+ public boolean isValidObject() {
return hasValidTlvObject;
}
@@ -68,9 +63,7 @@ public class SimTlv
* 0 and 0xff are invalid tag values
* valid tags range from 1 - 0xfe
*/
- public int
- getTag()
- {
+ public int getTag() {
if (!hasValidTlvObject) return 0;
return record[curOffset] & 0xff;
}
@@ -79,10 +72,8 @@ public class SimTlv
* Returns data associated with current TLV object
* returns null if !isValidObject()
*/
-
- public byte[]
- getData()
- {
+
+ public byte[] getData() {
if (!hasValidTlvObject) return null;
byte[] ret = new byte[curDataLength];
@@ -95,14 +86,12 @@ public class SimTlv
* @return false on invalid record, true on valid record
*/
- private boolean
- parseCurrentTlvObject()
- {
+ private boolean parseCurrentTlvObject() {
// 0x00 and 0xff are invalid tag values
if (record[curOffset] == 0 || (record[curOffset] & 0xff) == 0xff) {
return false;
}
-
+
try {
if ((record[curOffset + 1] & 0xff) < 0x80) {
// one byte length 0 - 0x7f
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimUtils.java b/telephony/java/com/android/internal/telephony/gsm/SimUtils.java
deleted file mode 100644
index 5cd5a90d9f2f..000000000000
--- a/telephony/java/com/android/internal/telephony/gsm/SimUtils.java
+++ /dev/null
@@ -1,329 +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 java.io.UnsupportedEncodingException;
-
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.util.Log;
-
-/**
- * Various methods, useful for dealing with SIM data.
- */
-public class SimUtils
-{
- static final String LOG_TAG="GSM";
-
- /**
- * Many fields in GSM SIM's are stored as nibble-swizzled BCD
- *
- * Assumes left-justified field that may be padded right with 0xf
- * values.
- *
- * Stops on invalid BCD value, returning string so far
- */
- public static String
- bcdToString(byte[] data, int offset, int length)
- {
- StringBuilder ret = new StringBuilder(length*2);
-
- for (int i = offset ; i < offset + length ; i++) {
- byte b;
- int v;
-
- v = data[i] & 0xf;
- if (v > 9) break;
- ret.append((char)('0' + v));
-
- v = (data[i] >> 4) & 0xf;
- if (v > 9) break;
- ret.append((char)('0' + v));
- }
-
- return ret.toString();
- }
-
-
- /**
- * Decodes a GSM-style BCD byte, returning an int ranging from 0-99.
- *
- * In GSM land, the least significant BCD digit is stored in the most
- * significant nibble.
- *
- * Out-of-range digits are treated as 0 for the sake of the time stamp,
- * because of this:
- *
- * TS 23.040 section 9.2.3.11
- * "if the MS receives a non-integer value in the SCTS, it shall
- * assume the digit is set to 0 but shall store the entire field
- * exactly as received"
- */
- public static int
- bcdByteToInt(byte b)
- {
- int ret = 0;
-
- // treat out-of-range BCD values as 0
- if ((b & 0xf0) <= 0x90) {
- ret = (b >> 4) & 0xf;
- }
-
- if ((b & 0x0f) <= 0x09) {
- ret += (b & 0xf) * 10;
- }
-
- return ret;
- }
-
-
- /**
- * Decodes a string field that's formatted like the EF[ADN] alpha
- * identifier
- *
- * From TS 51.011 10.5.1:
- * Coding:
- * this alpha tagging shall use either
- * - the SMS default 7 bit coded alphabet as defined in
- * TS 23.038 [12] with bit 8 set to 0. The alpha identifier
- * shall be left justified. Unused bytes shall be set to 'FF'; or
- * - one of the UCS2 coded options as defined in annex B.
- *
- * Annex B from TS 11.11 V8.13.0:
- * 1) If the first octet in the alpha string is '80', then the
- * remaining octets are 16 bit UCS2 characters ...
- * 2) if the first octet in the alpha string is '81', then the
- * second octet contains a value indicating the number of
- * characters in the string, and the third octet contains an
- * 8 bit number which defines bits 15 to 8 of a 16 bit
- * base pointer, where bit 16 is set to zero and bits 7 to 1
- * are also set to zero. These sixteen bits constitute a
- * base pointer to a "half page" in the UCS2 code space, to be
- * used with some or all of the remaining octets in the string.
- * The fourth and subsequent octets contain codings as follows:
- * If bit 8 of the octet is set to zero, the remaining 7 bits
- * of the octet contain a GSM Default Alphabet character,
- * whereas if bit 8 of the octet is set to one, then the
- * remaining seven bits are an offset value added to the
- * 16 bit base pointer defined earlier...
- * 3) If the first octet of the alpha string is set to '82', then
- * the second octet contains a value indicating the number of
- * characters in the string, and the third and fourth octets
- * contain a 16 bit number which defines the complete 16 bit
- * base pointer to a "half page" in the UCS2 code space...
- */
- public static String
- adnStringFieldToString(byte[] data, int offset, int length)
- {
- if (length >= 1) {
- if (data[offset] == (byte) 0x80) {
- int ucslen = (length - 1) / 2;
- String ret = null;
-
- try {
- ret = new String(data, offset + 1, ucslen * 2, "utf-16be");
- } catch (UnsupportedEncodingException ex) {
- Log.e(LOG_TAG, "implausible UnsupportedEncodingException",
- ex);
- }
-
- if (ret != null) {
- // trim off trailing FFFF characters
-
- ucslen = ret.length();
- while (ucslen > 0 && ret.charAt(ucslen - 1) == '\uFFFF')
- ucslen--;
-
- return ret.substring(0, ucslen);
- }
- }
- }
-
- boolean isucs2 = false;
- char base = '\0';
- int len = 0;
-
- if (length >= 3 && data[offset] == (byte) 0x81) {
- len = data[offset + 1] & 0xFF;
- if (len > length - 3)
- len = length - 3;
-
- base = (char) ((data[offset + 2] & 0xFF) << 7);
- offset += 3;
- isucs2 = true;
- } else if (length >= 4 && data[offset] == (byte) 0x82) {
- len = data[offset + 1] & 0xFF;
- if (len > length - 4)
- len = length - 4;
-
- base = (char) (((data[offset + 2] & 0xFF) << 8) |
- (data[offset + 3] & 0xFF));
- offset += 4;
- isucs2 = true;
- }
-
- if (isucs2) {
- StringBuilder ret = new StringBuilder();
-
- while (len > 0) {
- // UCS2 subset case
-
- if (data[offset] < 0) {
- ret.append((char) (base + (data[offset] & 0x7F)));
- offset++;
- len--;
- }
-
- // GSM character set case
-
- int count = 0;
- while (count < len && data[offset + count] >= 0)
- count++;
-
- ret.append(GsmAlphabet.gsm8BitUnpackedToString(data,
- offset, count));
-
- offset += count;
- len -= count;
- }
-
- return ret.toString();
- }
-
- return GsmAlphabet.gsm8BitUnpackedToString(data, offset, length);
- }
-
- static int
- hexCharToInt(char c)
- {
- if (c >= '0' && c <= '9') return (c - '0');
- if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
- if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
-
- throw new RuntimeException ("invalid hex char '" + c + "'");
- }
-
- /**
- * Converts a hex String to a byte array.
- *
- * @param s A string of hexadecimal characters, must be an even number of
- * chars long
- *
- * @return byte array representation
- *
- * @throws RuntimeException on invalid format
- */
- public static byte[]
- hexStringToBytes(String s)
- {
- byte[] ret;
-
- if (s == null) return null;
-
- int sz = s.length();
-
- ret = new byte[sz/2];
-
- for (int i=0 ; i <sz ; i+=2) {
- ret[i/2] = (byte) ((hexCharToInt(s.charAt(i)) << 4)
- | hexCharToInt(s.charAt(i+1)));
- }
-
- return ret;
- }
-
-
- /**
- * Converts a byte array into a String hexidecimal characters
- *
- * null returns null
- */
- public static String
- bytesToHexString(byte[] bytes)
- {
- if (bytes == null) return null;
-
- StringBuilder ret = new StringBuilder(2*bytes.length);
-
- for (int i = 0 ; i < bytes.length ; i++) {
- int b;
-
- b = 0x0f & (bytes[i] >> 4);
-
- ret.append("0123456789abcdef".charAt(b));
-
- b = 0x0f & bytes[i];
-
- ret.append("0123456789abcdef".charAt(b));
- }
-
- return ret.toString();
- }
-
-
- /**
- * Convert a TS 24.008 Section 10.5.3.5a Network Name field to a string
- * "offset" points to "octet 3", the coding scheme byte
- * empty string returned on decode error
- */
- public static String
- networkNameToString(byte[] data, int offset, int length)
- {
- String ret;
-
- if ((data[offset] & 0x80) != 0x80 || length < 1) {
- return "";
- }
-
- switch ((data[offset] >>> 4) & 0x7) {
- case 0:
- // SMS character set
- int countSeptets;
- int unusedBits = data[offset] & 7;
- countSeptets = (((length - 1) * 8) - unusedBits) / 7 ;
- ret = GsmAlphabet.gsm7BitPackedToString(
- data, offset + 1, countSeptets);
- break;
- case 1:
- // UCS2
- try {
- ret = new String(data,
- offset + 1, length - 1, "utf-16");
- } catch (UnsupportedEncodingException ex) {
- ret = "";
- Log.e(LOG_TAG,"implausible UnsupportedEncodingException", ex);
- }
- break;
-
- // unsupported encoding
- default:
- ret = "";
- break;
- }
-
- // "Add CI"
- // "The MS should add the letters for the Country's Initials and
- // a separator (e.g. a space) to the text string"
-
- if ((data[offset] & 0x40) != 0) {
- // FIXME(mkf) add country initials here
-
- }
-
- return ret;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
new file mode 100755
index 000000000000..d70b588e0918
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -0,0 +1,1058 @@
+/*
+ * 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.pim.Time;
+import android.os.Parcel;
+import android.telephony.PhoneNumberUtils;
+import android.util.Config;
+import android.util.Log;
+import com.android.internal.telephony.IccUtils;
+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 java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+
+import static android.telephony.SmsMessage.ENCODING_7BIT;
+import static android.telephony.SmsMessage.ENCODING_8BIT;
+import static android.telephony.SmsMessage.ENCODING_16BIT;
+import static android.telephony.SmsMessage.ENCODING_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;
+import static android.telephony.SmsMessage.MessageClass;
+
+/**
+ * A Short Message Service message.
+ *
+ */
+public class SmsMessage extends SmsMessageBase{
+ static final String LOG_TAG = "GSM";
+
+ private MessageClass messageClass;
+
+ /**
+ * TP-Message-Type-Indicator
+ * 9.2.3
+ */
+ private int mti;
+
+ /** TP-Protocol-Identifier (TP-PID) */
+ private int protocolIdentifier;
+
+ // TP-Data-Coding-Scheme
+ // see TS 23.038
+ private int dataCodingScheme;
+
+ // TP-Reply-Path
+ // e.g. 23.040 9.2.2.1
+ private boolean replyPathPresent = false;
+
+ // "Message Marked for Automatic Deletion Group"
+ // 23.038 Section 4
+ private boolean automaticDeletion;
+
+ /** True if Status Report is for SMS-SUBMIT; false for SMS-COMMAND. */
+ private boolean forSubmit;
+
+ /** The address of the receiver. */
+ private GsmSmsAddress recipientAddress;
+
+ /** Time when SMS-SUBMIT was delivered from SC to MSE. */
+ private long dischargeTimeMillis;
+
+ /**
+ * TP-Status - status of a previously submitted SMS.
+ * This field applies to SMS-STATUS-REPORT messages. 0 indicates success;
+ * see TS 23.040, 9.2.3.15 for description of other possible values.
+ */
+ private int status;
+
+ /**
+ * TP-Status - status of a previously submitted SMS.
+ * This field is true iff the message is a SMS-STATUS-REPORT message.
+ */
+ private boolean isStatusReportMessage = false;
+
+ public static class SubmitPdu extends SubmitPduBase {
+ }
+
+ /**
+ * Create an SmsMessage from a raw PDU.
+ */
+ public static SmsMessage createFromPdu(byte[] pdu) {
+ try {
+ SmsMessage msg = new SmsMessage();
+ msg.parsePdu(pdu);
+ return msg;
+ } catch (RuntimeException ex) {
+ Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
+ return null;
+ }
+ }
+
+ /**
+ * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
+ * +CMT unsolicited response (PDU mode, of course)
+ * +CMT: [&lt;alpha>],<length><CR><LF><pdu>
+ *
+ * Only public for debugging
+ *
+ * {@hide}
+ */
+ public static SmsMessage newFromCMT(String[] lines) {
+ try {
+ SmsMessage msg = new SmsMessage();
+ msg.parsePdu(IccUtils.hexStringToBytes(lines[1]));
+ return msg;
+ } catch (RuntimeException ex) {
+ Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
+ return null;
+ }
+ }
+
+ /** @hide */
+ public static SmsMessage newFromCMTI(String line) {
+ // the thinking here is not to read the message immediately
+ // FTA test case
+ Log.e(LOG_TAG, "newFromCMTI: not yet supported");
+ return null;
+ }
+
+ /** @hide */
+ public static SmsMessage newFromCDS(String line) {
+ try {
+ SmsMessage msg = new SmsMessage();
+ msg.parsePdu(IccUtils.hexStringToBytes(line));
+ return msg;
+ } catch (RuntimeException ex) {
+ Log.e(LOG_TAG, "CDS SMS PDU parsing failed: ", ex);
+ return null;
+ }
+ }
+
+ /**
+ * Note: This functionality is currently not supported in GSM mode.
+ * @hide
+ */
+ public static SmsMessageBase newFromParcel(Parcel p){
+ Log.w(LOG_TAG, "newFromParcel: is not supported in GSM mode.");
+ return null;
+ }
+
+ /**
+ * Create an SmsMessage from an SMS EF record.
+ *
+ * @param index Index of SMS record. This should be index in ArrayList
+ * returned by SmsManager.getAllMessagesFromSim + 1.
+ * @param data Record data.
+ * @return An SmsMessage representing the record.
+ *
+ * @hide
+ */
+ public static SmsMessage createFromEfRecord(int index, byte[] data) {
+ try {
+ SmsMessage msg = new SmsMessage();
+
+ msg.indexOnIcc = index;
+
+ // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT,
+ // or STORED_UNSENT
+ // See TS 51.011 10.5.3
+ if ((data[0] & 1) == 0) {
+ Log.w(LOG_TAG,
+ "SMS parsing failed: Trying to parse a free record");
+ return null;
+ } else {
+ msg.statusOnIcc = data[0] & 0x07;
+ }
+
+ int size = data.length - 1;
+
+ // Note: Data may include trailing FF's. That's OK; message
+ // should still parse correctly.
+ byte[] pdu = new byte[size];
+ System.arraycopy(data, 1, pdu, 0, size);
+ msg.parsePdu(pdu);
+ return msg;
+ } catch (RuntimeException ex) {
+ Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
+ return null;
+ }
+ }
+
+ /**
+ * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
+ * length in bytes (not hex chars) less the SMSC header
+ */
+ public static int getTPLayerLengthForPDU(String pdu) {
+ int len = pdu.length() / 2;
+ int smscLen = 0;
+
+ smscLen = Integer.parseInt(pdu.substring(0, 2), 16);
+
+ return len - smscLen - 1;
+ }
+
+ /**
+ * 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.
+ * @hide
+ */
+ public static SubmitPdu getSubmitPdu(String scAddress,
+ String destinationAddress, String message,
+ boolean statusReportRequested, byte[] header) {
+
+ // Perform null parameter checks.
+ if (message == null || destinationAddress == null) {
+ return null;
+ }
+
+ SubmitPdu ret = new SubmitPdu();
+ // MTI = SMS-SUBMIT, UDHI = header != null
+ byte mtiByte = (byte)(0x01 | (header != null ? 0x40 : 0x00));
+ ByteArrayOutputStream bo = getSubmitPduHead(
+ scAddress, destinationAddress, mtiByte,
+ statusReportRequested, ret);
+
+ try {
+ // First, try encoding it with the GSM alphabet
+
+ // User Data (and length)
+ byte[] userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header);
+
+ if ((0xff & userData[0]) > MAX_USER_DATA_SEPTETS) {
+ // Message too long
+ return null;
+ }
+
+ // TP-Data-Coding-Scheme
+ // Default encoding, uncompressed
+ bo.write(0x00);
+
+ // (no TP-Validity-Period)
+
+ bo.write(userData, 0, userData.length);
+ } catch (EncodeException ex) {
+ byte[] userData, textPart;
+ // Encoding to the 7-bit alphabet failed. Let's see if we can
+ // send it as a UCS-2 encoded message
+
+ try {
+ textPart = message.getBytes("utf-16be");
+ } catch (UnsupportedEncodingException uex) {
+ Log.e(LOG_TAG,
+ "Implausible UnsupportedEncodingException ",
+ uex);
+ return null;
+ }
+
+ if (header != null) {
+ userData = new byte[header.length + textPart.length];
+
+ System.arraycopy(header, 0, userData, 0, header.length);
+ System.arraycopy(textPart, 0, userData, header.length, textPart.length);
+ }
+ else {
+ userData = textPart;
+ }
+
+ if (userData.length > MAX_USER_DATA_BYTES) {
+ // Message too long
+ return null;
+ }
+
+ // TP-Data-Coding-Scheme
+ // Class 3, UCS-2 encoding, uncompressed
+ bo.write(0x0b);
+
+ // (no TP-Validity-Period)
+
+ // TP-UDL
+ bo.write(userData.length);
+
+ bo.write(userData, 0, userData.length);
+ }
+
+ ret.encodedMessage = bo.toByteArray();
+ return ret;
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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
+ * destination
+ * @param data the dat 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 destinationAddress, short destinationPort, byte[] data,
+ boolean statusReportRequested) {
+ if (data.length > (MAX_USER_DATA_BYTES - 7 /* UDH size */)) {
+ Log.e(LOG_TAG, "SMS data message may only contain "
+ + (MAX_USER_DATA_BYTES - 7) + " bytes");
+ return null;
+ }
+
+ SubmitPdu ret = new SubmitPdu();
+ ByteArrayOutputStream bo = getSubmitPduHead(
+ scAddress, destinationAddress, (byte) 0x41, // MTI = SMS-SUBMIT,
+ // TP-UDHI = true
+ statusReportRequested, ret);
+
+ // TP-Data-Coding-Scheme
+ // No class, 8 bit data
+ bo.write(0x04);
+
+ // (no TP-Validity-Period)
+
+ // User data size
+ bo.write(data.length + 7);
+
+ // User data header size
+ bo.write(0x06); // header is 6 octets
+
+ // 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
+ bo.write(data, 0, data.length);
+
+ ret.encodedMessage = bo.toByteArray();
+ return ret;
+ }
+
+ /**
+ * Create the beginning of a SUBMIT PDU. This is the part of the
+ * SUBMIT PDU that is common to the two versions of {@link #getSubmitPdu},
+ * one of which takes a byte array and the other of which takes a
+ * <code>String</code>.
+ *
+ * @param scAddress Service Centre address. null == use default
+ * @param destinationAddress the address of the destination for the message
+ * @param mtiByte
+ * @param ret <code>SubmitPdu</code> containing the encoded SC
+ * address, if applicable, and the encoded message
+ */
+ private static ByteArrayOutputStream getSubmitPduHead(
+ String scAddress, String destinationAddress, byte mtiByte,
+ boolean statusReportRequested, SubmitPdu ret) {
+ ByteArrayOutputStream bo = new ByteArrayOutputStream(
+ MAX_USER_DATA_BYTES + 40);
+
+ // SMSC address with length octet, or 0
+ if (scAddress == null) {
+ ret.encodedScAddress = null;
+ } else {
+ ret.encodedScAddress = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(
+ scAddress);
+ }
+
+ // TP-Message-Type-Indicator (and friends)
+ if (statusReportRequested) {
+ // Set TP-Status-Report-Request bit.
+ mtiByte |= 0x20;
+ if (Config.LOGD) Log.d(LOG_TAG, "SMS status report requested");
+ }
+ bo.write(mtiByte);
+
+ // space for TP-Message-Reference
+ bo.write(0);
+
+ byte[] daBytes;
+
+ daBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(destinationAddress);
+
+ // destination address length in BCD digits, ignoring TON byte and pad
+ // TODO Should be better.
+ bo.write((daBytes.length - 1) * 2
+ - ((daBytes[daBytes.length - 1] & 0xf0) == 0xf0 ? 1 : 0));
+
+ // destination address
+ bo.write(daBytes, 0, daBytes.length);
+
+ // TP-Protocol-Identifier
+ bo.write(0);
+ return bo;
+ }
+
+ static class PduParser {
+ byte pdu[];
+ int cur;
+ SmsHeader userDataHeader;
+ byte[] userData;
+ int mUserDataSeptetPadding;
+ int mUserDataSize;
+
+ PduParser(String s) {
+ this(IccUtils.hexStringToBytes(s));
+ }
+
+ PduParser(byte[] pdu) {
+ this.pdu = pdu;
+ cur = 0;
+ mUserDataSeptetPadding = 0;
+ }
+
+ /**
+ * Parse and return the SC address prepended to SMS messages coming via
+ * the TS 27.005 / AT interface. Returns null on invalid address
+ */
+ String getSCAddress() {
+ int len;
+ String ret;
+
+ // length of SC Address
+ len = getByte();
+
+ if (len == 0) {
+ // no SC address
+ ret = null;
+ } else {
+ // SC address
+ try {
+ ret = PhoneNumberUtils
+ .calledPartyBCDToString(pdu, cur, len);
+ } catch (RuntimeException tr) {
+ Log.d(LOG_TAG, "invalid SC address: ", tr);
+ ret = null;
+ }
+ }
+
+ cur += len;
+
+ return ret;
+ }
+
+ /**
+ * returns non-sign-extended byte value
+ */
+ int getByte() {
+ return pdu[cur++] & 0xff;
+ }
+
+ /**
+ * Any address except the SC address (eg, originating address) See TS
+ * 23.040 9.1.2.5
+ */
+ GsmSmsAddress getAddress() {
+ GsmSmsAddress ret;
+
+ // "The Address-Length field is an integer representation of
+ // the number field, i.e. excludes any semi octet containing only
+ // fill bits."
+ // The TOA field is not included as part of this
+ int addressLength = pdu[cur] & 0xff;
+ int lengthBytes = 2 + (addressLength + 1) / 2;
+
+ ret = new GsmSmsAddress(pdu, cur, lengthBytes);
+
+ cur += lengthBytes;
+
+ return ret;
+ }
+
+ /**
+ * Parses an SC timestamp and returns a currentTimeMillis()-style
+ * timestamp
+ */
+
+ long getSCTimestampMillis() {
+ // TP-Service-Centre-Time-Stamp
+ int year = IccUtils.bcdByteToInt(pdu[cur++]);
+ int month = IccUtils.bcdByteToInt(pdu[cur++]);
+ int day = IccUtils.bcdByteToInt(pdu[cur++]);
+ int hour = IccUtils.bcdByteToInt(pdu[cur++]);
+ int minute = IccUtils.bcdByteToInt(pdu[cur++]);
+ int second = IccUtils.bcdByteToInt(pdu[cur++]);
+
+ // For the timezone, the most significant bit of the
+ // least signficant nibble is the sign byte
+ // (meaning the max range of this field is 79 quarter-hours,
+ // which is more than enough)
+
+ byte tzByte = pdu[cur++];
+
+ // Mask out sign bit.
+ int timezoneOffset = IccUtils
+ .bcdByteToInt((byte) (tzByte & (~0x08)));
+
+ timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset
+ : -timezoneOffset;
+
+ Time time = new Time(Time.TIMEZONE_UTC);
+
+ // It's 2006. Should I really support years < 2000?
+ time.year = year >= 90 ? year + 1900 : year + 2000;
+ time.month = month - 1;
+ time.monthDay = day;
+ time.hour = hour;
+ time.minute = minute;
+ time.second = second;
+
+ // Timezone offset is in quarter hours.
+ return time.toMillis(true) - (timezoneOffset * 15 * 60 * 1000);
+ }
+
+ /**
+ * Pulls the user data out of the PDU, and separates the payload from
+ * the header if there is one.
+ *
+ * @param hasUserDataHeader true if there is a user data header
+ * @param dataInSeptets true if the data payload is in septets instead
+ * of octets
+ * @return the number of septets or octets in the user data payload
+ */
+ int constructUserData(boolean hasUserDataHeader, boolean dataInSeptets) {
+ int offset = cur;
+ int userDataLength = pdu[offset++] & 0xff;
+ int headerSeptets = 0;
+
+ if (hasUserDataHeader) {
+ int userDataHeaderLength = pdu[offset++] & 0xff;
+
+ byte[] udh = new byte[userDataHeaderLength];
+ System.arraycopy(pdu, offset, udh, 0, userDataHeaderLength);
+ userDataHeader = SmsHeader.parse(udh);
+ offset += userDataHeaderLength;
+
+ int headerBits = (userDataHeaderLength + 1) * 8;
+ headerSeptets = headerBits / 7;
+ headerSeptets += (headerBits % 7) > 0 ? 1 : 0;
+ 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];
+ System.arraycopy(pdu, offset, userData, 0, userData.length);
+ cur = offset;
+
+ if (dataInSeptets) {
+ // Return the number of septets
+ return userDataLength - headerSeptets;
+ } else {
+ // Return the number of octets
+ return userData.length;
+ }
+ }
+
+ /**
+ * Returns the user data payload, not including the headers
+ *
+ * @return the user data payload, not including the headers
+ */
+ byte[] getUserData() {
+ return userData;
+ }
+
+ /**
+ * Returns the number of padding bits at the begining of the user data
+ * array before the start of the septets.
+ *
+ * @return the number of padding bits at the begining of the user data
+ * array before the start of the septets
+ */
+ int getUserDataSeptetPadding() {
+ return mUserDataSeptetPadding;
+ }
+
+ /**
+ * Returns an object representing the user data headers
+ *
+ * @return an object representing the user data headers
+ *
+ * {@hide}
+ */
+ SmsHeader getUserDataHeader() {
+ return userDataHeader;
+ }
+
+/*
+ XXX Not sure what this one is supposed to be doing, and no one is using
+ it.
+ String getUserDataGSM8bit() {
+ // System.out.println("remainder of pud:" +
+ // HexDump.dumpHexString(pdu, cur, pdu.length - cur));
+ int count = pdu[cur++] & 0xff;
+ int size = pdu[cur++];
+
+ // skip over header for now
+ cur += size;
+
+ if (pdu[cur - 1] == 0x01) {
+ int tid = pdu[cur++] & 0xff;
+ int type = pdu[cur++] & 0xff;
+
+ size = pdu[cur++] & 0xff;
+
+ int i = cur;
+
+ while (pdu[i++] != '\0') {
+ }
+
+ int length = i - cur;
+ String mimeType = new String(pdu, cur, length);
+
+ cur += length;
+
+ if (false) {
+ System.out.println("tid = 0x" + HexDump.toHexString(tid));
+ System.out.println("type = 0x" + HexDump.toHexString(type));
+ System.out.println("header size = " + size);
+ System.out.println("mimeType = " + mimeType);
+ System.out.println("remainder of header:" +
+ HexDump.dumpHexString(pdu, cur, (size - mimeType.length())));
+ }
+
+ cur += size - mimeType.length();
+
+ // System.out.println("data count = " + count + " cur = " + cur
+ // + " :" + HexDump.dumpHexString(pdu, cur, pdu.length - cur));
+
+ MMSMessage msg = MMSMessage.parseEncoding(mContext, pdu, cur,
+ pdu.length - cur);
+ } else {
+ System.out.println(new String(pdu, cur, pdu.length - cur - 1));
+ }
+
+ return IccUtils.bytesToHexString(pdu);
+ }
+*/
+
+ /**
+ * Interprets the user data payload as pack GSM 7bit characters, and
+ * decodes them into a String.
+ *
+ * @param septetCount the number of septets in the user data payload
+ * @return a String with the decoded characters
+ */
+ String getUserDataGSM7Bit(int septetCount) {
+ String ret;
+
+ ret = GsmAlphabet.gsm7BitPackedToString(pdu, cur, septetCount,
+ mUserDataSeptetPadding);
+
+ cur += (septetCount * 7) / 8;
+
+ return ret;
+ }
+
+ /**
+ * Interprets the user data payload as UCS2 characters, and
+ * decodes them into a String.
+ *
+ * @param byteCount the number of bytes in the user data payload
+ * @return a String with the decoded characters
+ */
+ String getUserDataUCS2(int byteCount) {
+ String ret;
+
+ try {
+ ret = new String(pdu, cur, byteCount, "utf-16");
+ } catch (UnsupportedEncodingException ex) {
+ ret = "";
+ Log.e(LOG_TAG, "implausible UnsupportedEncodingException", ex);
+ }
+
+ cur += byteCount;
+ return ret;
+ }
+
+ boolean moreDataPresent() {
+ return (pdu.length > cur);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public int getProtocolIdentifier() {
+ return protocolIdentifier;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isReplace() {
+ return (protocolIdentifier & 0xc0) == 0x40
+ && (protocolIdentifier & 0x3f) > 0
+ && (protocolIdentifier & 0x3f) < 8;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isCphsMwiMessage() {
+ return ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageClear()
+ || ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageSet();
+ }
+
+ /** {@inheritDoc} */
+ public boolean isMWIClearMessage() {
+ if (isMwi && (mwiSense == false)) {
+ return true;
+ }
+
+ return originatingAddress != null
+ && ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageClear();
+ }
+
+ /** {@inheritDoc} */
+ public boolean isMWISetMessage() {
+ if (isMwi && (mwiSense == true)) {
+ return true;
+ }
+
+ return originatingAddress != null
+ && ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageSet();
+ }
+
+ /** {@inheritDoc} */
+ public boolean isMwiDontStore() {
+ if (isMwi && mwiDontStore) {
+ return true;
+ }
+
+ if (isCphsMwiMessage()) {
+ // See CPHS 4.2 Section B.4.2.1
+ // If the user data is a single space char, do not store
+ // the message. Otherwise, store and display as usual
+ if (" ".equals(getMessageBody())) {
+ ;
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ public int getStatus() {
+ return status;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isStatusReportMessage() {
+ return isStatusReportMessage;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isReplyPathPresent() {
+ return replyPathPresent;
+ }
+
+ /**
+ * TS 27.005 3.1, <pdu> definition "In the case of SMS: 3GPP TS 24.011 [6]
+ * SC address followed by 3GPP TS 23.040 [3] TPDU in hexadecimal format:
+ * ME/TA converts each octet of TP data unit into two IRA character long
+ * hexad number (e.g. octet with integer value 42 is presented to TE as two
+ * characters 2A (IRA 50 and 65))" ...in the case of cell broadcast,
+ * something else...
+ */
+ private void parsePdu(byte[] pdu) {
+ mPdu = pdu;
+ // Log.d(LOG_TAG, "raw sms mesage:");
+ // Log.d(LOG_TAG, s);
+
+ PduParser p = new PduParser(pdu);
+
+ scAddress = p.getSCAddress();
+
+ if (scAddress != null) {
+ if (Config.LOGD) Log.d(LOG_TAG, "SMS SC address: " + scAddress);
+ }
+
+ // TODO(mkf) support reply path, user data header indicator
+
+ // TP-Message-Type-Indicator
+ // 9.2.3
+ int firstByte = p.getByte();
+
+ mti = firstByte & 0x3;
+ switch (mti) {
+ // TP-Message-Type-Indicator
+ // 9.2.3
+ case 0:
+ parseSmsDeliver(p, firstByte);
+ break;
+ case 2:
+ parseSmsStatusReport(p, firstByte);
+ break;
+ default:
+ // TODO(mkf) the rest of these
+ throw new RuntimeException("Unsupported message type");
+ }
+ }
+
+ /**
+ * Parses a SMS-STATUS-REPORT message.
+ *
+ * @param p A PduParser, cued past the first byte.
+ * @param firstByte The first byte of the PDU, which contains MTI, etc.
+ */
+ private void parseSmsStatusReport(PduParser p, int firstByte) {
+ isStatusReportMessage = true;
+
+ // TP-Status-Report-Qualifier bit == 0 for SUBMIT
+ forSubmit = (firstByte & 0x20) == 0x00;
+ // TP-Message-Reference
+ messageRef = p.getByte();
+ // TP-Recipient-Address
+ recipientAddress = p.getAddress();
+ // TP-Service-Centre-Time-Stamp
+ scTimeMillis = p.getSCTimestampMillis();
+ // TP-Discharge-Time
+ dischargeTimeMillis = p.getSCTimestampMillis();
+ // TP-Status
+ status = p.getByte();
+
+ // The following are optional fields that may or may not be present.
+ if (p.moreDataPresent()) {
+ // TP-Parameter-Indicator
+ int extraParams = p.getByte();
+ int moreExtraParams = extraParams;
+ while ((moreExtraParams & 0x80) != 0) {
+ // We only know how to parse a few extra parameters, all
+ // indicated in the first TP-PI octet, so skip over any
+ // additional TP-PI octets.
+ moreExtraParams = p.getByte();
+ }
+ // TP-Protocol-Identifier
+ if ((extraParams & 0x01) != 0) {
+ protocolIdentifier = p.getByte();
+ }
+ // TP-Data-Coding-Scheme
+ if ((extraParams & 0x02) != 0) {
+ dataCodingScheme = p.getByte();
+ }
+ // TP-User-Data-Length (implies existence of TP-User-Data)
+ if ((extraParams & 0x04) != 0) {
+ boolean hasUserDataHeader = (firstByte & 0x40) == 0x40;
+ parseUserData(p, hasUserDataHeader);
+ }
+ }
+ }
+
+ private void parseSmsDeliver(PduParser p, int firstByte) {
+ replyPathPresent = (firstByte & 0x80) == 0x80;
+
+ originatingAddress = p.getAddress();
+
+ if (originatingAddress != null) {
+ if (Config.LOGV) Log.v(LOG_TAG, "SMS originating address: "
+ + originatingAddress.address);
+ }
+
+ // TP-Protocol-Identifier (TP-PID)
+ // TS 23.040 9.2.3.9
+ protocolIdentifier = p.getByte();
+
+ // TP-Data-Coding-Scheme
+ // see TS 23.038
+ dataCodingScheme = p.getByte();
+
+ if (Config.LOGV) {
+ Log.v(LOG_TAG, "SMS TP-PID:" + protocolIdentifier
+ + " data coding scheme: " + dataCodingScheme);
+ }
+
+ scTimeMillis = p.getSCTimestampMillis();
+
+ if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
+
+ boolean hasUserDataHeader = (firstByte & 0x40) == 0x40;
+
+ parseUserData(p, hasUserDataHeader);
+ }
+
+ /**
+ * Parses the User Data of an SMS.
+ *
+ * @param p The current PduParser.
+ * @param hasUserDataHeader Indicates whether a header is present in the
+ * User Data.
+ */
+ private void parseUserData(PduParser p, boolean hasUserDataHeader) {
+ boolean hasMessageClass = false;
+ boolean userDataCompressed = false;
+
+ int encodingType = ENCODING_UNKNOWN;
+
+ // Look up the data encoding scheme
+ if ((dataCodingScheme & 0x80) == 0) {
+ // Bits 7..4 == 0xxx
+ automaticDeletion = (0 != (dataCodingScheme & 0x40));
+ userDataCompressed = (0 != (dataCodingScheme & 0x20));
+ hasMessageClass = (0 != (dataCodingScheme & 0x10));
+
+ if (userDataCompressed) {
+ Log.w(LOG_TAG, "4 - Unsupported SMS data coding scheme "
+ + "(compression) " + (dataCodingScheme & 0xff));
+ } else {
+ switch ((dataCodingScheme >> 2) & 0x3) {
+ case 0: // GSM 7 bit default alphabet
+ encodingType = ENCODING_7BIT;
+ break;
+
+ case 2: // UCS 2 (16bit)
+ encodingType = ENCODING_16BIT;
+ break;
+
+ case 1: // 8 bit data
+ case 3: // reserved
+ Log.w(LOG_TAG, "1 - Unsupported SMS data coding scheme "
+ + (dataCodingScheme & 0xff));
+ encodingType = ENCODING_8BIT;
+ break;
+ }
+ }
+ } else if ((dataCodingScheme & 0xf0) == 0xf0) {
+ automaticDeletion = false;
+ hasMessageClass = true;
+ userDataCompressed = false;
+
+ if (0 == (dataCodingScheme & 0x04)) {
+ // GSM 7 bit default alphabet
+ encodingType = ENCODING_7BIT;
+ } else {
+ // 8 bit data
+ encodingType = ENCODING_8BIT;
+ }
+ } else if ((dataCodingScheme & 0xF0) == 0xC0
+ || (dataCodingScheme & 0xF0) == 0xD0
+ || (dataCodingScheme & 0xF0) == 0xE0) {
+ // 3GPP TS 23.038 V7.0.0 (2006-03) section 4
+
+ // 0xC0 == 7 bit, don't store
+ // 0xD0 == 7 bit, store
+ // 0xE0 == UCS-2, store
+
+ if ((dataCodingScheme & 0xF0) == 0xE0) {
+ encodingType = ENCODING_16BIT;
+ } else {
+ encodingType = ENCODING_7BIT;
+ }
+
+ userDataCompressed = false;
+ boolean active = ((dataCodingScheme & 0x08) == 0x08);
+
+ // bit 0x04 reserved
+
+ if ((dataCodingScheme & 0x03) == 0x00) {
+ isMwi = true;
+ mwiSense = active;
+ mwiDontStore = ((dataCodingScheme & 0xF0) == 0xC0);
+ } else {
+ isMwi = false;
+
+ Log.w(LOG_TAG, "MWI for fax, email, or other "
+ + (dataCodingScheme & 0xff));
+ }
+ } else {
+ Log.w(LOG_TAG, "3 - Unsupported SMS data coding scheme "
+ + (dataCodingScheme & 0xff));
+ }
+
+ // set both the user data and the user data header.
+ int count = p.constructUserData(hasUserDataHeader,
+ encodingType == ENCODING_7BIT);
+ this.userData = p.getUserData();
+ this.userDataHeader = p.getUserDataHeader();
+
+ switch (encodingType) {
+ case ENCODING_UNKNOWN:
+ case ENCODING_8BIT:
+ messageBody = null;
+ break;
+
+ case ENCODING_7BIT:
+ messageBody = p.getUserDataGSM7Bit(count);
+ break;
+
+ case ENCODING_16BIT:
+ messageBody = p.getUserDataUCS2(count);
+ break;
+ }
+
+ if (Config.LOGV) Log.v(LOG_TAG, "SMS message body (raw): '" + messageBody + "'");
+
+ if (messageBody != null) {
+ parseMessageBody();
+ }
+
+ if (!hasMessageClass) {
+ messageClass = MessageClass.UNKNOWN;
+ } else {
+ switch (dataCodingScheme & 0x3) {
+ case 0:
+ messageClass = MessageClass.CLASS_0;
+ break;
+ case 1:
+ messageClass = MessageClass.CLASS_1;
+ break;
+ case 2:
+ messageClass = MessageClass.CLASS_2;
+ break;
+ case 3:
+ messageClass = MessageClass.CLASS_3;
+ break;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MessageClass getMessageClass() {
+ return messageClass;
+ }
+
+}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java b/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
index 11ad52d183e3..e68655e76d0b 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/stk/AppInterface.java b/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
index a43e32fea726..2115dcfe2eca 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
@@ -141,7 +141,7 @@ public interface AppInterface {
void notifyBrowserTermination(boolean isErrorTermination);
/**
- * Notifies the SIM about the launch browser confirmation. This method
+ * Notifies the SIM about the launch browser confirmation. This method
* should be called only after the application gets notified by {@code
* CommandListener.onLaunchBrowser()} or inside that method.
*
@@ -165,19 +165,19 @@ public interface AppInterface {
*
* @param input The text string that the user has typed.
* @param helpRequired True if just help information is requested on a menu
- * item rather than menu selection. False if the menu
+ * item rather than menu selection. False if the menu
* item is actually selected.
*/
void notifyInput(String input, boolean helpRequired);
/**
- * Notifies the SIM that the user input a key in Yes/No scenario.
- * This method should be called only after the application gets notified by
+ * Notifies the SIM that the user input a key in Yes/No scenario.
+ * This method should be called only after the application gets notified by
* {@code CommandListener.onGetInkey()} or inside that method.
*
* @param yesNoResponse User's choice for Yes/No scenario.
* @param helpRequired True if just help information is requested on a menu
- * item rather than menu selection. False if the menu
+ * item rather than menu selection. False if the menu
* item is actually selected.
*/
void notifyInkey(boolean yesNoResponse, boolean helpRequired);
@@ -189,7 +189,7 @@ public interface AppInterface {
*
* @param key The key that the user has typed. If the SIM required
* @param helpRequired True if just help information is requested on a menu
- * item rather than menu selection. False if the menu
+ * item rather than menu selection. False if the menu
* item is actually selected.
*/
void notifyInkey(char key, boolean helpRequired);
@@ -236,12 +236,12 @@ public interface AppInterface {
* @param wantsHelp Indicates if the user requested help for the id item.
*/
void notifySelectedItem(int id, boolean wantsHelp);
-
+
/**
- * Notifies the SIM that No response was received from the user for display
+ * Notifies the SIM that No response was received from the user for display
* text message dialog.
- *
- * * @param terminationCode indication for display text termination. Uses
+ *
+ * * @param terminationCode indication for display text termination. Uses
* {@code ResultCode } values.
*/
public void notifyDisplayTextEnded(ResultCode terminationCode);
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java b/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java
index f5268e535f7f..52d0cb958f53 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java
@@ -20,9 +20,9 @@ import java.util.List;
/**
* Class for representing BER-TLV objects.
- *
+ *
* @see "ETSI TS 102 223 Annex C" for more information.
- *
+ *
* {@hide}
*/
class BerTlv {
@@ -41,16 +41,16 @@ class BerTlv {
/**
* Gets a list of ComprehensionTlv objects contained in this BER-TLV object.
- *
+ *
* @return A list of COMPREHENSION-TLV object
*/
public List<ComprehensionTlv> getComprehensionTlvs() {
return mCompTlvs;
}
-
+
/**
* Gets a tag id of the BER-TLV object.
- *
+ *
* @return A tag integer.
*/
public int getTag() {
@@ -59,7 +59,7 @@ class BerTlv {
/**
* Decodes a BER-TLV object from a byte array.
- *
+ *
* @param data A byte array to decode from
* @return A BER-TLV object decoded
* @throws ResultException
@@ -74,7 +74,7 @@ class BerTlv {
tag = data[curIndex++] & 0xff;
if (tag != BER_PROACTIVE_COMMAND_TAG) {
// If the buffer doesn't contain proactive command tag, but
- // start with a command details tlv object ==> skip the length
+ // start with a command details tlv object ==> skip the length
// parsing and look for tlv objects.
ComprehensionTlv ctlv = ComprehensionTlv.decode(data,
curIndex--);
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandListener.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandListener.java
index 5c9a3e9ad626..1204235a2bc7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandListener.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/CommandListener.java
@@ -40,7 +40,7 @@ public interface CommandListener {
* Call back function to be called when the SIM wants a call to be set up.
* Application must call {@code AppInterface.acceptOrRejectCall()} after
* this method returns or inside this method.
- *
+ *
* @param confirmMsg User confirmation phase message.
* @param textAttrs List of text attributes to be applied. Can be null.
* @param callMsg Call set up phase message.
@@ -65,7 +65,7 @@ public interface CommandListener {
* Call back function to be called for handling SET_UP_MENU proactive
* commands. The menu can be retrieved by calling {@code
* AppInterface.getMainMenu}.
- *
+ *
* @param menu application main menu.
*/
void onSetUpMenu(Menu menu);
@@ -95,7 +95,7 @@ public interface CommandListener {
* Call back function to be called for handling GET_INPUT proactive
* commands. Application must call {@code AppInterface.notifyInput()} after
* this method returns or inside this method.
- *
+ *
* @param text A text to be used as a prompt
* @param defaultText A text to be used as a default input
* @param minLen Mininum length of response (0 indicates there is no mininum
@@ -160,7 +160,7 @@ public interface CommandListener {
/**
* Call back function to be called for handling LAUNCH_BROWSER proactive
* commands.
- *
+ *
* @param useDefaultUrl If true, use the system default URL, otherwise use
* {@code url} as the URL.
* @param confirmMsg A text to be used as the user confirmation message. Can
@@ -175,7 +175,7 @@ public interface CommandListener {
/**
* Call back function to be called for handling PLAY_TONE proactive
* commands.
- *
+ *
* @param tone Tone to be played
* @param text A text to be displayed. Can be null.
* @param textAttrs List of text attributes to be applied. Can be null.
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 d39ad7b4ff36..4a067f16340c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
@@ -21,7 +21,7 @@ import android.graphics.Bitmap;
import java.util.List;
/**
- * Container class for proactive command parameters.
+ * Container class for proactive command parameters.
*
*/
class CommandParams {
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 3cf8ca67a5c6..c8f9d682cbdb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
@@ -22,9 +22,9 @@ import java.util.List;
/**
* Class for representing COMPREHENSION-TLV objects.
- *
+ *
* @see "ETSI TS 101 220 subsection 7.1.1"
- *
+ *
* {@hide}
*/
class ComprehensionTlv {
@@ -38,7 +38,7 @@ class ComprehensionTlv {
* Constructor. Private on purpose. Use
* {@link #decodeMany(byte[], int) decodeMany} or
* {@link #decode(byte[], int) decode} method.
- *
+ *
* @param tag The tag for this object
* @param cr Comprehension Required flag
* @param length Length of the value
@@ -76,7 +76,7 @@ class ComprehensionTlv {
/**
* Parses a list of COMPREHENSION-TLV objects from a byte array.
- *
+ *
* @param data A byte array containing data to be parsed
* @param startIndex Index in data at which to start parsing
* @return A list of COMPREHENSION-TLV objects parsed
@@ -97,7 +97,7 @@ class ComprehensionTlv {
/**
* Parses an COMPREHENSION-TLV object from a byte array.
- *
+ *
* @param data A byte array containing data to be parsed
* @param startIndex Index in data at which to start parsing
* @return A COMPREHENSION-TLV object parsed
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java b/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java
index ee9154191bce..870f2a970220 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java
@@ -28,9 +28,9 @@ import android.os.Message;
import android.util.Log;
/**
- * Class for loading icons from the SIM card. Has two states: single, for loading
+ * Class for loading icons from the SIM card. Has two states: single, for loading
* one icon. Multi, for loading icons list.
- *
+ *
*/
class IconLoader extends Handler {
// members
@@ -48,13 +48,13 @@ class IconLoader extends Handler {
private static IconLoader sLoader = null;
- // Loader state values.
+ // Loader state values.
private static final int STATE_SINGLE_ICON = 1;
private static final int STATE_MULTI_ICONS = 2;
- // Finished loading single record from a linear-fixed EF-IMG.
+ // Finished loading single record from a linear-fixed EF-IMG.
private static final int EVENT_READ_EF_IMG_RECOED_DONE = 1;
- // Finished loading single icon from a Transparent DF-Graphics.
+ // Finished loading single icon from a Transparent DF-Graphics.
private static final int EVENT_READ_ICON_DONE = 2;
// Finished loading single colour icon lookup table.
private static final int EVENT_READ_CLUT_DONE = 3;
@@ -64,7 +64,7 @@ class IconLoader extends Handler {
// CLUT entry size, {Red, Green, Black}
private static final int CLUT_ENTRY_SIZE = 3;
- static private final String TAG = "STK IconLoader";
+ static private final String TAG = "STK IconLoader";
private IconLoader(Looper looper , SIMFileHandler fh) {
super(looper);
@@ -104,7 +104,7 @@ class IconLoader extends Handler {
mState = STATE_SINGLE_ICON;
startLoadingIcon(recordNumber);
}
-
+
private void startLoadingIcon(int recordNumber) {
// Reset the load variables.
mId = null;
@@ -156,10 +156,10 @@ class IconLoader extends Handler {
}
/**
- * Handles Image descriptor parsing and required processing. This is the
+ * Handles Image descriptor parsing and required processing. This is the
* first step required to handle retrieving icons from the SIM.
- *
- * @param data byte [] containing Image Instance descriptor as defined in
+ *
+ * @param data byte [] containing Image Instance descriptor as defined in
* TS 51.011.
*/
private boolean handleImageDescriptor(byte[] rawData) {
@@ -213,7 +213,7 @@ class IconLoader extends Handler {
* @param data The raw data
* @param length The length of image body
* @return The bitmap
- */
+ */
public static Bitmap parseToBnW(byte[] data, int length){
int valueIndex = 0;
int width = data[valueIndex++] & 0xFF;
@@ -245,7 +245,7 @@ class IconLoader extends Handler {
* 0 is black
* 1 is white
* @param bit to decode
- * @return RGB color
+ * @return RGB color
*/
private static int bitToBnW(int bit){
if(bit == 1){
@@ -257,11 +257,11 @@ class IconLoader extends Handler {
/**
* a TS 131.102 image instance of code scheme '11' into color Bitmap
- *
+ *
* @param data The raw data
* @param length the length of image body
* @param transparency with or without transparency
- * @param clut coulor lookup table
+ * @param clut coulor lookup table
* @return The color bitmap
*/
public static Bitmap parseToRGB(byte[] data, int length,
@@ -302,9 +302,9 @@ class IconLoader extends Handler {
return Bitmap.createBitmap(pixels, width, height,
Bitmap.Config.ARGB_8888);
}
-
+
/**
- * Calculate bit mask for a given number of bits. The mask should enable to
+ * Calculate bit mask for a given number of bits. The mask should enable to
* make a bitwise and to the given number of bits.
* @param numOfBits number of bits to calculate mask for.
* @return bit mask
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java b/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java
index e1a20f6fe5f0..6e1f77a7b9c4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java
@@ -35,7 +35,8 @@ public class ImageDescriptor {
static final int CODING_SCHEME_BASIC = 0x11;
static final int CODING_SCHEME_COLOUR = 0x21;
- public static final int ID_LENGTH = 9;
+ // public static final int ID_LENGTH = 9;
+ // ID_LENGTH substituted by IccFileHandlerBase.GET_RESPONSE_EF_IMG_SIZE_BYTES
private static final String TAG = "ImageDescriptor";
@@ -51,7 +52,7 @@ public class ImageDescriptor {
/**
* Extract descriptor information about image instance.
- *
+ *
* @param rawData
* @param valueIndex
* @return ImageDescriptor
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Service.java b/telephony/java/com/android/internal/telephony/gsm/stk/Service.java
index c0ceeefe341c..c1ab99ac9ec7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Service.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/Service.java
@@ -30,8 +30,8 @@ import android.graphics.drawable.Drawable;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.gsm.EncodeException;
-import com.android.internal.telephony.gsm.GsmAlphabet;
+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;
@@ -55,31 +55,31 @@ import java.util.List;
/**
* Enumeration for representing the tag value of COMPREHENSION-TLV objects. If
* you want to get the actual value, call {@link #value() value} method.
- *
+ *
* {@hide}
*/
enum ComprehensionTlvTag {
- COMMAND_DETAILS(0x01),
- DEVICE_IDENTITIES(0x02),
- RESULT(0x03),
- DURATION(0x04),
- ALPHA_ID(0x05),
- USSD_STRING(0x0a),
- TEXT_STRING(0x0d),
- TONE(0x0e),
- ITEM(0x0f),
- ITEM_ID(0x10),
- RESPONSE_LENGTH(0x11),
- FILE_LIST(0x12),
- HELP_REQUEST(0x15),
- DEFAULT_TEXT(0x17),
- EVENT_LIST(0x19),
+ COMMAND_DETAILS(0x01),
+ DEVICE_IDENTITIES(0x02),
+ RESULT(0x03),
+ DURATION(0x04),
+ ALPHA_ID(0x05),
+ USSD_STRING(0x0a),
+ TEXT_STRING(0x0d),
+ TONE(0x0e),
+ ITEM(0x0f),
+ ITEM_ID(0x10),
+ RESPONSE_LENGTH(0x11),
+ FILE_LIST(0x12),
+ HELP_REQUEST(0x15),
+ DEFAULT_TEXT(0x17),
+ EVENT_LIST(0x19),
ICON_ID(0x1e),
ITEM_ICON_ID_LIST(0x1f),
- IMMEDIATE_RESPONSE(0x2b),
- LANGUAGE(0x2d),
+ IMMEDIATE_RESPONSE(0x2b),
+ LANGUAGE(0x2d),
URL(0x31),
- BROWSER_TERMINATION_CAUSE(0x34),
+ BROWSER_TERMINATION_CAUSE(0x34),
TEXT_ATTRIBUTE(0x50);
private int mValue;
@@ -90,7 +90,7 @@ enum ComprehensionTlvTag {
/**
* Returns the actual value of this COMPREHENSION-TLV object.
- *
+ *
* @return Actual tag value of this object
*/
public int value() {
@@ -102,24 +102,24 @@ enum ComprehensionTlvTag {
* Enumeration for representing "Type of Command" of proactive commands. If you
* want to create a CommandType object, call the static method {@link
* #fromInt(int) fromInt}.
- *
+ *
* {@hide}
*/
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;
@@ -130,7 +130,7 @@ enum CommandType {
/**
* 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
@@ -148,7 +148,7 @@ enum CommandType {
/**
* Main class that implements SIM Toolkit Service.
- *
+ *
* {@hide}
*/
public class Service extends Handler implements AppInterface {
@@ -156,9 +156,9 @@ public class Service extends Handler implements AppInterface {
// Service members.
private static Service sInstance;
private CommandsInterface mCmdIf;
- private SIMRecords mSimRecords;
+ private static SIMRecords mSimRecords;
private Context mContext;
- private SimCard mSimCard;
+ private static SimCard mSimCard;
private CommandListener mCmdListener;
private Object mCmdListenerLock = new Object();
private CommandParams mCmdParams = null;
@@ -209,7 +209,7 @@ public class Service extends Handler implements AppInterface {
public static final int UICC_EVENT_BROWSING_STATUS = 0x0f;
public static final int UICC_EVENT_FRAMES_INFO_CHANGE = 0x10;
public static final int UICC_EVENT_I_WLAN_ACESS_STATUS = 0x11;
-
+
// Command Qualifier values
static final int REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE = 0x00;
static final int REFRESH_NAA_INIT_AND_FILE_CHANGE = 0x02;
@@ -232,17 +232,17 @@ public class Service extends Handler implements AppInterface {
static final int APP_INDICATOR_INSTALLED_NORMAL = 2;
static final int APP_INDICATOR_INSTALLED_SPECIAL = 3;
private static final int APP_INDICATOR_LAUNCHED = 4;
- // Use setAppIndication(APP_INSTALL_INDICATOR) to go back for the original
+ // Use setAppIndication(APP_INSTALL_INDICATOR) to go back for the original
// install indication.
private static final int APP_INSTALL_INDICATOR = 5;
- // Container class to hold temporary icon identifier TLV object info.
+ // Container class to hold temporary icon identifier TLV object info.
class IconId {
int recordNumber;
boolean selfExplanatory;
}
- // Container class to hold temporary item icon identifier list TLV object info.
+ // Container class to hold temporary item icon identifier list TLV object info.
class ItemsIconId {
int [] recordNumbers;
boolean selfExplanatory;
@@ -282,10 +282,26 @@ public class Service extends Handler implements AppInterface {
mSimCard.registerForAbsent(this, EVENT_SIM_ABSENT, null);
}
+ public void dispose() {
+ mSimRecords.unregisterForRecordsLoaded(this);
+ mSimCard.unregisterForAbsent(this);
+ mCmdIf.unSetOnStkSessionEnd(this);
+ mCmdIf.unSetOnStkProactiveCmd(this);
+ mCmdIf.unSetOnStkEvent(this);
+ mCmdIf.unSetOnStkCallSetUp(this);
+
+ //removing instance
+ sInstance = null;
+ }
+
+ protected void finalize() {
+ Log.d(TAG, "Service finalized");
+ }
+
/**
* Used for retrieving the only Service object in the system. There is only
* one Service object.
- *
+ *
* @param ci CommandsInterface object
* @param sr SIMRecords object
* @return The only Service object in the system
@@ -298,6 +314,14 @@ public class Service extends Handler implements AppInterface {
return null;
}
sInstance = new Service(ci, sr, context, fh, sc);
+ } else if(mSimCard != sc && mSimRecords != sr) {
+ Log.d(TAG, "Reinitialize the Service with SimCard and SIMRecords.");
+ mSimCard = sc;
+ mSimRecords = sr;
+
+ // re-Register for SIM ready event.
+ mSimRecords.registerForRecordsLoaded(sInstance, EVENT_SIM_LOADED, null);
+ mSimCard.registerForAbsent(sInstance, EVENT_SIM_ABSENT, null);
}
return sInstance;
}
@@ -305,7 +329,7 @@ public class Service extends Handler implements AppInterface {
/**
* Used for retrieving the only Service object in the system. There is only
* one Service object.
- *
+ *
* @return The only Service object in the system
*/
public static Service getInstance() {
@@ -566,7 +590,7 @@ public class Service extends Handler implements AppInterface {
result = ResultCode.HELP_INFO_REQUIRED;
} else {
resp = new GetInkeyInputResponseData(Character.toString(key),
- request.isUcs2, false);
+ request.isUcs2, false);
}
sendTerminalResponse(request.cmdDet, result, false, 0, resp);
@@ -590,7 +614,7 @@ public class Service extends Handler implements AppInterface {
if (helpRequired) {
result = ResultCode.HELP_INFO_REQUIRED;
} else {
- resp = new GetInkeyInputResponseData(yesNoResponse);
+ resp = new GetInkeyInputResponseData(yesNoResponse);
}
sendTerminalResponse(cmdParams.cmdDet, result, false, 0, resp);
@@ -710,19 +734,19 @@ public class Service extends Handler implements AppInterface {
throw new AssertionError("Unrecognized STK command: " + msg.what);
}
}
-
+
/**
* Send terminal response for backward move in the proactive SIM session
* requested by the user
- *
+ *
* Only available when responding following proactive commands
- * DISPLAY_TEXT(0x21),
- * GET_INKEY(0x22),
- * GET_INPUT(0x23),
+ * DISPLAY_TEXT(0x21),
+ * GET_INKEY(0x22),
+ * GET_INPUT(0x23),
* SET_UP_MENU(0x25);
- *
+ *
* @return true if stk can send backward move response
- *
+ *
*/
public boolean backwardMove() {
CtlvCommandDetails cmdDet = null;
@@ -740,14 +764,14 @@ public class Service extends Handler implements AppInterface {
/**
* Send terminal response for proactive SIM session terminated by the user
- *
+ *
* Only available when responding following proactive commands
- * DISPLAY_TEXT(0x21),
- * GET_INKEY(0x22),
- * GET_INPUT(0x23),
+ * DISPLAY_TEXT(0x21),
+ * GET_INKEY(0x22),
+ * GET_INPUT(0x23),
* PLAY_TONE(0x20),
* SET_UP_MENU(0x25);
- *
+ *
* @return true if stk can send terminate session response
*/
public boolean terminateSession() {
@@ -777,7 +801,7 @@ public class Service extends Handler implements AppInterface {
/**
* Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL.
- *
+ *
* @param data Null object. Do not use this.
*/
private void handleSessionEnd(Object data) {
@@ -922,7 +946,7 @@ public class Service extends Handler implements AppInterface {
* This method parses the data transmitted from the SIM card, and handles
* the command according to the "Type of Command". Each proactive command is
* handled by a corresponding handleXXX() method.
- *
+ *
* @param data String containing SAT/USAT proactive command in hexadecimal
* format starting with command tag
*/
@@ -1052,7 +1076,7 @@ public class Service extends Handler implements AppInterface {
callStkApp(CommandType.DISPLAY_TEXT);
break;
case SELECT_ITEM:
-
+
SelectItemParams params = ((SelectItemParams) mNextCmdParams);
Menu menu = params.mMenu;
switch(params.mIconLoadState) {
@@ -1083,7 +1107,7 @@ public class Service extends Handler implements AppInterface {
+ "command types!");
}
}
-
+
private void callStkApp(CommandType cmdType) {
boolean needsResponse = false;
mCmdParams = mNextCmdParams;
@@ -1211,10 +1235,10 @@ public class Service extends Handler implements AppInterface {
/**
* Search for a COMPREHENSION-TLV object with the given tag from a list
- *
+ *
* @param tag A tag to search for
* @param ctlvs List of ComprehensionTlv objects used to search in
- *
+ *
* @return A ComprehensionTlv object that has the tag value of {@code tag}.
* If no object is found with the tag, null is returned.
*/
@@ -1229,10 +1253,10 @@ public class Service extends Handler implements AppInterface {
* list iterated by {@code iter}. {@code iter} points to the object next to
* the found object when this method returns. Used for searching the same
* list for similar tags, usually item id.
- *
+ *
* @param tag A tag to search for
* @param iter Iterator for ComprehensionTlv objects used for search
- *
+ *
* @return A ComprehensionTlv object that has the tag value of {@code tag}.
* If no object is found with the tag, null is returned.
*/
@@ -1250,7 +1274,7 @@ public class Service extends Handler implements AppInterface {
/**
* 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.
@@ -1281,7 +1305,7 @@ public class Service extends Handler implements AppInterface {
/**
* 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.
@@ -1310,14 +1334,14 @@ public class Service extends Handler implements AppInterface {
/**
* Processes SETUP_CALL proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
* command object
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
+ * @return true if the command is processing is pending and additional
* asynchronous processing is required.
*/
private void processSetupCall(CtlvCommandDetails cmdDet,
@@ -1373,14 +1397,14 @@ public class Service extends Handler implements AppInterface {
/**
* Processes DISPLAY_TEXT proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
* command object
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
+ * @return true if the command is processing is pending and additional
* asynchronous processing is required.
* @throws ResultException
*/
@@ -1399,8 +1423,8 @@ public class Service extends Handler implements AppInterface {
ctlvs);
if (ctlv != null) {
params.text = retrieveTextString(ctlv);
- }
- // If the tlv object doesn't exist or the it is a null object reply
+ }
+ // If the tlv object doesn't exist or the it is a null object reply
// with command not understood.
if (params.text == null) {
throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
@@ -1432,13 +1456,13 @@ public class Service extends Handler implements AppInterface {
mIconLoader.loadIcon(iconId.recordNumber, this
.obtainMessage(EVENT_LOAD_ICON_DONE));
return true;
- }
+ }
return false;
}
/**
* Processes SET_UP_MENU proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
@@ -1446,7 +1470,7 @@ public class Service extends Handler implements AppInterface {
* @param ctlvs Iterator for ComprehensionTlv objects following Command
* Details object and Device Identities object within the proactive
* command
- * @return true if the command is processing is pending and additional
+ * @return true if the command is processing is pending and additional
* asynchronous processing is required.
* @throws ResultException
*/
@@ -1483,7 +1507,7 @@ public class Service extends Handler implements AppInterface {
if (first && item == null) {
removeExistingMenu = true;
break;
- }
+ }
menu.items.add(retrieveItem(ctlv));
first = false;
} else {
@@ -1545,14 +1569,14 @@ public class Service extends Handler implements AppInterface {
/**
* Processes SET_UP_IDLE_MODE_TEXT proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
* command object
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
+ * @return true if the command is processing is pending and additional
* asynchronous processing is required.
* @throws ResultException
*/
@@ -1597,20 +1621,20 @@ public class Service extends Handler implements AppInterface {
mIconLoader.loadIcon(iconId.recordNumber, this
.obtainMessage(EVENT_LOAD_ICON_DONE));
return true;
- }
+ }
return false;
}
/**
* Processes GET_INKEY proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
* command object
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
+ * @return true if the command is processing is pending and additional
* asynchronous processing is required.
* @throws ResultException
*/
@@ -1662,14 +1686,14 @@ public class Service extends Handler implements AppInterface {
/**
* Processes GET_INPUT proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
* command object
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
+ * @return true if the command is processing is pending and additional
* asynchronous processing is required.
* @throws ResultException
*/
@@ -1744,7 +1768,7 @@ public class Service extends Handler implements AppInterface {
/**
* Processes REFRESH proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
@@ -1762,8 +1786,8 @@ public class Service extends Handler implements AppInterface {
}
// REFRESH proactive command is rerouted by the baseband and handled by
- // the telephony layer. IDLE TEXT should be removed for a REFRESH command
- // with "initialization" or "reset"
+ // the telephony layer. IDLE TEXT should be removed for a REFRESH command
+ // with "initialization" or "reset"
if (mNm == null) {
throw new ResultException(ResultCode.TERMINAL_CRNTLY_UNABLE_TO_PROCESS);
@@ -1785,14 +1809,14 @@ public class Service extends Handler implements AppInterface {
/**
* Processes SELECT_ITEM proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
* command object
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
+ * @return true if the command is processing is pending and additional
* asynchronous processing is required.
* @throws ResultException
*/
@@ -1842,7 +1866,7 @@ public class Service extends Handler implements AppInterface {
// subtract one.
menu.defaultItem = retrieveItemId(ctlv) - 1;
}
-
+
ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
if (ctlv != null) {
iconLoadState = SelectItemParams.LOAD_TITLE_ICON;
@@ -1902,7 +1926,7 @@ public class Service extends Handler implements AppInterface {
/**
* Processes EVENT_NOTIFY message from baseband.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
@@ -1947,14 +1971,14 @@ public class Service extends Handler implements AppInterface {
/**
* Processes SET_UP_EVENT_LIST proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
* command object
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
+ * @return true if the command is processing is pending and additional
* asynchronous processing is required.
*/
private boolean processSetUpEventList(CtlvCommandDetails cmdDet,
@@ -1979,14 +2003,14 @@ public class Service extends Handler implements AppInterface {
/**
* Processes LAUNCH_BROWSER proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
* command object
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
+ * @return true if the command is processing is pending and additional
* asynchronous processing is required.
* @throws ResultException
*/
@@ -2061,14 +2085,14 @@ public class Service extends Handler implements AppInterface {
/**
* Processes PLAY_TONE proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved from the proactive command
* object
* @param devIds Device Identities object retrieved from the proactive
* command object
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
+ * @return true if the command is processing is pending and additional
* asynchronous processing is required.t
* @throws ResultException
*/
@@ -2132,7 +2156,7 @@ public class Service extends Handler implements AppInterface {
/**
* Retrieves text from the Text COMPREHENSION-TLV object, and decodes it
* into a {@link java.lang.String}.
- *
+ *
* @param ctlv A Text COMPREHENSION-TLV object
* @return A {@link java.lang.String} object decoded from the Text object
* @throws ResultException
@@ -2180,7 +2204,7 @@ public class Service extends Handler implements AppInterface {
/**
* Retrieves Duration information from the Duration COMPREHENSION-TLV
* object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return A Duration object
* @throws ResultException
@@ -2204,7 +2228,7 @@ public class Service extends Handler implements AppInterface {
/**
* Retrieves Item information from the COMPREHENSION-TLV object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return An Item
* @throws ResultException
@@ -2234,7 +2258,7 @@ public class Service extends Handler implements AppInterface {
/**
* Retrieves Item id information from the COMPREHENSION-TLV object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return An Item id
* @throws ResultException
@@ -2309,7 +2333,7 @@ public class Service extends Handler implements AppInterface {
/**
* 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
@@ -2368,7 +2392,7 @@ public class Service extends Handler implements AppInterface {
/**
* 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
@@ -2392,7 +2416,7 @@ public class Service extends Handler implements AppInterface {
/**
* Handles RIL_UNSOL_STK_EVENT_NOTIFY unsolicited command from RIL.
- *
+ *
* @param data String containing SAT/USAT commands or responses sent by ME
* to SIM or commands handled by ME, in hexadecimal format starting
* with first byte of response data or command tag
@@ -2438,11 +2462,11 @@ public class Service extends Handler implements AppInterface {
}
// There are two scenarios for EVENT_NOTIFY messages:
- // 1. A proactive command which is partially handled by the baseband and
+ // 1. A proactive command which is partially handled by the baseband and
// requires UI processing from the application. This messages will be
// tagged with PROACTIVE COMMAND tag.
- // 2. A notification for an action completed by the baseband. This
- // messages will be tagged with UNKNOWN tag and the command type inside
+ // 2. A notification for an action completed by the baseband. This
+ // messages will be tagged with UNKNOWN tag and the command type inside
// the Command details object should indicate which action was completed.
if (berTlv.getTag() == BerTlv.BER_PROACTIVE_COMMAND_TAG) {
switch (cmdType) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkAppInstaller.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkAppInstaller.java
index 07e3e56a31fc..891dce9723cf 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkAppInstaller.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/StkAppInstaller.java
@@ -27,7 +27,7 @@ import android.util.Log;
*
*/
public class StkAppInstaller {
- // Application state actions: install, uninstall used by StkAppStateReceiver.
+ // Application state actions: install, uninstall used by StkAppStateReceiver.
static final String STK_APP_INSTALL_ACTION = "com.android.stk.action.INSTALL";
static final String STK_APP_UNINSTALL_ACTION = "com.android.stk.action.UNINSTALL";
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkAppStateReceiver.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkAppStateReceiver.java
index 778ca2ed3dea..7d1bb91bc481 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkAppStateReceiver.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/StkAppStateReceiver.java
@@ -23,8 +23,8 @@ import com.android.internal.telephony.gsm.stk.Service;
import android.util.Log;
/**
- * This class implements a Broadcast receiver. It waits for an intent sent by
- * the STK service and install/uninstall the STK application. If no intent is
+ * This class implements a Broadcast receiver. It waits for an intent sent by
+ * the STK service and install/uninstall the STK application. If no intent is
* received when the device finished booting, the application is then unistalled.
*/
public class StkAppStateReceiver extends BroadcastReceiver {
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
index 3e1879e6e704..15a5761c77f7 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -23,13 +23,13 @@ import android.util.Log;
import com.android.internal.os.HandlerThread;
import com.android.internal.telephony.BaseCommands;
+import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.gsm.CallFailCause;
-import com.android.internal.telephony.gsm.CommandException;
import com.android.internal.telephony.DriverCall;
+import com.android.internal.telephony.gsm.CallFailCause;
import com.android.internal.telephony.gsm.PDPContextState;
import com.android.internal.telephony.gsm.SuppServiceNotification;
+import com.android.internal.telephony.Phone;
import java.util.ArrayList;
@@ -489,13 +489,20 @@ public final class SimulatedCommands extends BaseCommands
}
/**
+ * @deprecated
+ */
+ public void getPDPContextList(Message result) {
+ getDataCallList(result);
+ }
+
+ /**
* returned message
* 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
*/
- public void getPDPContextList(Message result) {
+ public void getDataCallList(Message result) {
resultSuccess(result, new ArrayList<PDPContextState>(0));
}
@@ -745,8 +752,15 @@ public final class SimulatedCommands extends BaseCommands
resultSuccess(result, ret);
}
- public void
- getLastPdpFailCause (Message result) {
+ /**
+ * @deprecated
+ */
+ public void getLastPdpFailCause (Message result) {
+ unimplemented(result);
+ }
+
+ public void getLastDataCallFailCause(Message result) {
+ //
unimplemented(result);
}
@@ -925,16 +939,35 @@ public final class SimulatedCommands extends BaseCommands
unimplemented(response);
}
+ public void deleteSmsOnRuim(int index, Message response) {
+ Log.d(LOG_TAG, "Delete RUIM message at index " + index);
+ unimplemented(response);
+ }
+
public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
Log.d(LOG_TAG, "Write SMS to SIM with status " + status);
unimplemented(response);
}
+ public void writeSmsToRuim(int status, String pdu, Message response) {
+ Log.d(LOG_TAG, "Write SMS to RUIM with status " + status);
+ unimplemented(response);
+ }
public void setupDefaultPDP(String apn, String user, String password, Message result) {
unimplemented(result);
}
+ public void setupDataCall(String radioTechnology, String profile, String apn, String user,
+ String password, Message result) {
+ unimplemented(result);
+ }
+
+ public void deactivateDataCall(int cid, Message result) {unimplemented(result);}
+
+ /**
+ * @deprecated
+ */
public void deactivateDefaultPDP(int cid, Message result) {unimplemented(result);}
public void setPreferredNetworkType(int networkType , Message result) {
@@ -969,7 +1002,7 @@ public final class SimulatedCommands extends BaseCommands
}
return false;
}
-
+
public void setRadioPower(boolean on, Message result) {
if(on) {
if (isSimLocked()) {
@@ -990,6 +1023,10 @@ public final class SimulatedCommands extends BaseCommands
unimplemented(result);
}
+ public void acknowledgeLastIncomingCdmaSms(boolean success, Message result) {
+ unimplemented(result);
+ }
+
/**
* parameters equivilient to 27.007 AT+CRSM command
* response.obj will be an AsyncResult
@@ -1064,7 +1101,7 @@ public final class SimulatedCommands extends BaseCommands
* @param serviceClass is a sum of SERVICE_CLASSS_*
*/
public void setCallForward(int action, int cfReason, int serviceClass,
- String number, int timeSeconds, Message result) {unimplemented(result);}
+ String number, int timeSeconds, Message result) {unimplemented(result);}
/**
* cfReason is one of CF_REASON_*
@@ -1075,11 +1112,12 @@ public final class SimulatedCommands extends BaseCommands
* An array of length 0 means "disabled for all codes"
*/
public void queryCallForwardStatus(int cfReason, int serviceClass,
- String number, Message result) {unimplemented(result);}
+ String number, Message result) {unimplemented(result);}
public void setNetworkSelectionModeAutomatic(Message result) {unimplemented(result);}
- public void setNetworkSelectionModeManual(String operatorNumeric, Message result) {unimplemented(result);}
+ public void setNetworkSelectionModeManual(
+ String operatorNumeric, Message result) {unimplemented(result);}
/**
* Queries whether the current network selection mode is automatic
@@ -1308,43 +1346,47 @@ public final class SimulatedCommands extends BaseCommands
// ***** Methods for CDMA support
public void
getDeviceIdentity(Message response) {
- //TODO: to be implemented
-
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ unimplemented(response);
}
-
+
public void
getCDMASubscription(Message response) {
- //TODO: to be implemented
-
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ unimplemented(response);
}
public void
setCdmaSubscription(int cdmaSubscriptionType, Message response) {
- //TODO: to be implemented
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ unimplemented(response);
}
-
+
public void queryCdmaRoamingPreference(Message response) {
- //TODO: to be implemented
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ unimplemented(response);
}
-
+
public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
- //TODO: to be implemented
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ unimplemented(response);
}
public void
setPhoneType(int phoneType) {
- //TODO: to be implemented
-
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
}
-
+
public void getPreferredVoicePrivacy(Message result) {
- Log.w(LOG_TAG, "Warning, this function is not completely implemented in the class SimulatedCommands.java.");
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ unimplemented(result);
}
public void setPreferredVoicePrivacy(boolean enable, Message result) {
- Log.w(LOG_TAG, "Warning, this function is not completely implemented in the class SimulatedCommands.java.");
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ unimplemented(result);
}
-
+
/**
* Set the TTY mode for the CDMA phone
*
@@ -1353,9 +1395,10 @@ public final class SimulatedCommands extends BaseCommands
* @param response is callback message
*/
public void setTTYModeEnabled(boolean enable, Message response) {
- //TODO T: to be implemented
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ unimplemented(response);
}
-
+
/**
* Query the TTY mode for the CDMA phone
* (AsyncResult)response.obj).result is an int[] with element [0] set to
@@ -1365,7 +1408,38 @@ public final class SimulatedCommands extends BaseCommands
* @param response is callback message
*/
public void queryTTYModeEnabled(Message response) {
- //TODO T: to be implemented
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ unimplemented(response);
}
-
+
+ /**
+ * {@inheritDoc}
+ */
+ public void sendCDMAFeatureCode(String FeatureCode, Message response) {
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ unimplemented(response);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void sendCdmaSms(byte[] pdu, Message response){
+ Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
+ }
+
+ public void activateCdmaBroadcastSms(int activate, Message result) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void getCdmaBroadcastConfig(Message result) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setCdmaBroadcastConfig(int[] configValuesArray, Message result) {
+ // TODO Auto-generated method stub
+
+ }
+
}
diff --git a/telephony/jni/cdmasms/Android.mk b/telephony/jni/cdmasms/Android.mk
new file mode 100644
index 000000000000..3b8699664342
--- /dev/null
+++ b/telephony/jni/cdmasms/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ cdma_sms_jni.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libutils \
+ libandroid_runtime \
+ libnativehelper
+
+LOCAL_MODULE:= libcdma_sms_jni
+
+LOCAL_C_INCLUDES += \
+ $(JNI_H_INCLUDE) \
+ hardware/ril/include/telephony
+
+ifeq ($(TARGET_PRODUCT),generic)
+ LOCAL_C_INCLUDES += hardware/ril/reference-cdma-sms
+ LOCAL_SHARED_LIBRARIES += libreference-cdma-sms
+ LOCAL_CFLAGS += -DREFERENCE_CDMA_SMS
+else
+# define vendor implementation
+endif
+
+LOCAL_PRELINK_MODULE := false
+include $(BUILD_SHARED_LIBRARY)
diff --git a/telephony/jni/cdmasms/cdma_sms_jni.cpp b/telephony/jni/cdmasms/cdma_sms_jni.cpp
new file mode 100644
index 000000000000..4b5630e6b251
--- /dev/null
+++ b/telephony/jni/cdmasms/cdma_sms_jni.cpp
@@ -0,0 +1,1301 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file cdma_sms_jni.cpp
+ *
+ * This file implement the Java Native Interface
+ * for encoding and decoding of SMS
+ */
+
+
+#include <nativehelper/jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+#include <cdma_sms_jni.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+#ifdef REFERENCE_CDMA_SMS
+#include <reference-cdma-sms.h>
+#else
+//include vendor library
+#endif //REFERENCE_CDMA_SMS
+#ifdef __cplusplus
+}
+#endif //__cplusplus
+
+#undef LOG_TAG
+#define LOG_TAG "CDMA"
+#include <utils/Log.h>
+
+static RIL_CDMA_SMS_ClientBd *clientBdData = NULL;
+
+
+static jint getObjectIntField(JNIEnv * env, jobject obj, const char *name, jint * value)
+{
+ jclass clazz;
+ jfieldID field;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("getObjectIntField():");
+#endif
+
+ clazz = env->GetObjectClass(obj);
+ if (NULL == clazz) {
+ jniThrowException(env, "java/lang/Exception", NULL);
+ return JNI_FAILURE;
+ }
+
+ field = env->GetFieldID(clazz, name, "I");
+ env->DeleteLocalRef(clazz);
+
+ if (NULL == field) {
+ jniThrowException(env, "java/lang/NoSuchFieldException", name);
+ return JNI_FAILURE;
+ }
+
+ *value = env->GetIntField(obj, field);
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD(" %s = %d\n", name, *value);
+#endif
+
+ return JNI_SUCCESS;
+}
+
+static jint setObjectIntField(JNIEnv * env, jobject obj, const char *name, jint value)
+{
+ jclass clazz;
+ jfieldID field;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("setObjectIntField(): %s = %d\n", name, value);
+#endif
+
+ clazz = env->GetObjectClass(obj);
+ if (NULL == clazz) {
+ jniThrowException(env, "java/lang/Exception", NULL);
+ return JNI_FAILURE;
+ }
+
+ field = env->GetFieldID(clazz, name, "I");
+ env->DeleteLocalRef(clazz);
+
+ if (NULL == field) {
+ jniThrowException(env, "java/lang/NoSuchFieldException", name);
+ return JNI_FAILURE;
+ }
+
+ env->SetIntField(obj, field, value);
+
+ return JNI_SUCCESS;
+}
+
+static jint getObjectByteField(JNIEnv * env, jobject obj, const char *name, jbyte * value)
+{
+ jclass clazz;
+ jfieldID field;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("getObjectByteField():");
+#endif
+
+ clazz = env->GetObjectClass(obj);
+ if (NULL == clazz) {
+ jniThrowException(env, "java/lang/Exception", NULL);
+ return JNI_FAILURE;
+ }
+
+ field = env->GetFieldID(clazz, name, "B");
+ env->DeleteLocalRef(clazz);
+
+ if (NULL == field) {
+ jniThrowException(env, "java/lang/NoSuchFieldException", name);
+ return JNI_FAILURE;
+ }
+
+ *value = env->GetByteField(obj, field);
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD(" %s = %02x\n", name, *value);
+#endif
+
+ return JNI_SUCCESS;
+}
+
+static jint setObjectByteField(JNIEnv * env, jobject obj, const char *name, jbyte value)
+{
+ jclass clazz;
+ jfieldID field;
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("setObjectByteField(): %s = 0x%02x\n", name, value);
+#endif
+
+ clazz = env->GetObjectClass(obj);
+ if (NULL == clazz) {
+ jniThrowException(env, "java/lang/Exception", NULL);
+ return JNI_FAILURE;
+ }
+
+ field = env->GetFieldID(clazz, name, "B");
+ env->DeleteLocalRef(clazz);
+
+ if (NULL == field) {
+ jniThrowException(env, "java/lang/NoSuchFieldException", name);
+ return JNI_FAILURE;
+ }
+
+ env->SetByteField(obj, field, value);
+
+ return JNI_SUCCESS;
+}
+
+static jint getObjectBooleanField(JNIEnv * env, jobject obj, const char *name, jboolean * value)
+{
+ jclass clazz;
+ jfieldID field;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("getObjectBooleanField():");
+#endif
+
+ clazz = env->GetObjectClass(obj);
+ if (NULL == clazz) {
+ jniThrowException(env, "java/lang/Exception", NULL);
+ return JNI_FAILURE;
+ }
+
+ field = env->GetFieldID(clazz, name, "Z");
+ env->DeleteLocalRef(clazz);
+
+ if (NULL == field) {
+ jniThrowException(env, "java/lang/NoSuchFieldException", name);
+ return JNI_FAILURE;
+ }
+
+ *value = env->GetBooleanField(obj, field);
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD(" %s = %d\n", name, *value);
+#endif
+
+ return JNI_SUCCESS;
+}
+
+static jint setObjectBooleanField(JNIEnv * env, jobject obj, const char *name, jboolean value)
+{
+ jclass clazz;
+ jfieldID field;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("setObjectBooleanField(): %s = %d\n", name, value);
+#endif
+
+ clazz = env->GetObjectClass(obj);
+ if (NULL == clazz) {
+ jniThrowException(env, "java/lang/Exception", NULL);
+ return JNI_FAILURE;
+ }
+
+ field = env->GetFieldID(clazz, name, "Z");
+ env->DeleteLocalRef(clazz);
+
+ if (NULL == field) {
+ jniThrowException(env, "java/lang/NoSuchFieldException", name);
+ return JNI_FAILURE;
+ }
+
+ env->SetBooleanField(obj, field, value);
+
+ return JNI_SUCCESS;
+}
+
+static jint getObjectByteArrayField(JNIEnv * env, jobject obj, const char *name, jbyte* arrData, int* length)
+{
+ jclass clazz;
+ jfieldID field;
+ jbyte * data_buf;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("getObjectByteArrayField(): %s\n", name);
+#endif
+
+ clazz = env->GetObjectClass(obj);
+ if (NULL == clazz) {
+ jniThrowException(env, "java/lang/Exception", NULL);
+ return JNI_FAILURE;
+ }
+
+ field = env->GetFieldID(clazz, name, "[B");
+ env->DeleteLocalRef(clazz);
+
+ if (NULL == field) {
+ jniThrowException(env, "java/lang/NoSuchFieldException", name);
+ return JNI_FAILURE;
+ }
+
+ jbyteArray buffer = (jbyteArray)(env->GetObjectField(obj, field));
+ if (buffer != NULL) {
+ int len = env->GetArrayLength(buffer);
+ data_buf = env->GetByteArrayElements(buffer, NULL);
+ for (int i=0; i<len; i++) {
+ *arrData++ = data_buf[i];
+#ifdef DBG_LOG_LEVEL_B
+ LOGD(" [%d] = 0x%02x\n", i, data_buf[i]);
+#endif
+ }
+ *length = len;
+ } else {
+ jniThrowException(env, "java/lang/NullPointerException", NULL);
+ return JNI_FAILURE;
+ }
+
+ return JNI_SUCCESS;
+}
+
+static jint setObjectByteArrayField(JNIEnv * env, jobject obj, const char *name, jbyte* arrData, int length)
+{
+ jclass clazz;
+ jfieldID field;
+ jbyte* byte_buf;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("setObjectByteArrayField(): %s\n", name);
+#endif
+
+ clazz = env->GetObjectClass(obj);
+ if (NULL == clazz) {
+ jniThrowException(env, "java/lang/Exception", NULL);
+ return JNI_FAILURE;
+ }
+
+ field = env->GetFieldID(clazz, name, "[B");
+ env->DeleteLocalRef(clazz);
+
+ if (NULL == field) {
+ jniThrowException(env, "java/lang/NoSuchFieldException", name);
+ return JNI_FAILURE;
+ }
+
+ jbyteArray buffer = (jbyteArray)(env->GetObjectField(obj, field));
+ if (buffer == NULL) {
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("setObjectByteArrayField(): %s = null\n", name);
+#endif
+ buffer = env->NewByteArray(length);
+ env->SetObjectField(obj, field, buffer);
+ }
+
+ if (buffer != NULL) {
+#ifdef DBG_LOG_LEVEL_B
+ for (int i=0; i<length; i++) {
+ LOGD(" [%d] = 0x%02x\n", i, arrData[i]);
+ }
+#endif
+ env->SetByteArrayRegion(buffer, 0, length, arrData);
+ } else {
+ jniThrowException(env, "java/lang/NullPointerException", NULL);
+ return JNI_FAILURE;
+ }
+
+ return JNI_SUCCESS;
+}
+
+
+/* native interface */
+JNIEXPORT jint JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsConstructClientBD
+ (JNIEnv * env, jobject obj)
+{
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsConstructClientBD()...\n");
+#endif
+
+ clientBdData = (RIL_CDMA_SMS_ClientBd *)malloc(sizeof(RIL_CDMA_SMS_ClientBd));
+ if (NULL == clientBdData) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", "clientBdData memory allocation failed");
+ return JNI_FAILURE;
+ }
+ memset(clientBdData, 0, sizeof(RIL_CDMA_SMS_ClientBd));
+ return JNI_SUCCESS;
+}
+
+
+/* native interface */
+JNIEXPORT jint JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDestructClientBD
+ (JNIEnv * env, jobject obj)
+{
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsDestructClientBD()...\n");
+#endif
+
+ if (clientBdData == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException", "clientBdData is null");
+ return JNI_FAILURE;
+ }
+ free(clientBdData);
+ return JNI_SUCCESS;
+}
+
+
+/* native interface */
+JNIEXPORT jint JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetBearerDataPrimitives
+ (JNIEnv * env, jobject obj, jobject bearerData)
+{
+ jbyteArray mc_time = NULL;
+ jbyte mctime_buffer[6];
+ int length;
+ jint intData;
+ jbyte byteData;
+ jboolean booleanData;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsSetBearerDataPrimitives()...\n");
+#endif
+
+ // mask
+ if (getObjectIntField(env, bearerData, "mask", &intData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->mask = intData;
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->mask = 0x%x\n", clientBdData->mask);
+#endif
+
+ // message_id.type
+ if (getObjectByteField(env, bearerData, "messageType", &byteData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->message_id.type = (RIL_CDMA_SMS_BdMessageType)(byteData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->message_id.type = 0x%02x\n", clientBdData->message_id.type);
+#endif
+
+ // message_id.id_number
+ if ((clientBdData->mask & WMS_MASK_BD_MSG_ID) == WMS_MASK_BD_MSG_ID) {
+ if (getObjectIntField(env, bearerData, "messageID", &intData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->message_id.id_number = (RIL_CDMA_SMS_MessageNumber)(intData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->message_id.id_number = %d\n", clientBdData->message_id.id_number);
+#endif
+ }
+
+ // message_id.udh_present
+ if (getObjectBooleanField(env, bearerData, "hasUserDataHeader", &booleanData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->message_id.udh_present = (unsigned char)(booleanData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->message_id.udh_present = %d\n", clientBdData->message_id.udh_present);
+#endif
+
+ // user_response
+ // TODO
+
+ // mc_time
+ if ((clientBdData->mask & WMS_MASK_BD_MC_TIME) == WMS_MASK_BD_MC_TIME) {
+ if (getObjectByteArrayField(env, bearerData, "timeStamp", mctime_buffer, &length) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ if (mctime_buffer != NULL) {
+ clientBdData->mc_time.year = mctime_buffer[0];
+ clientBdData->mc_time.month = mctime_buffer[1];
+ clientBdData->mc_time.day = mctime_buffer[2];
+ clientBdData->mc_time.hour = mctime_buffer[3];
+ clientBdData->mc_time.minute = mctime_buffer[4];
+ clientBdData->mc_time.second = mctime_buffer[5];
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->mc_time.year = %d\n", clientBdData->mc_time.year);
+ LOGD("clientBdData->mc_time.month = %d\n", clientBdData->mc_time.month);
+ LOGD("clientBdData->mc_time.day = %d\n", clientBdData->mc_time.day);
+ LOGD("clientBdData->mc_time.hour = %d\n", clientBdData->mc_time.hour);
+ LOGD("clientBdData->mc_time.minute = %d\n", clientBdData->mc_time.minute);
+ LOGD("clientBdData->mc_time.second = %d\n", clientBdData->mc_time.second);
+#endif
+ }
+ }
+
+ // clientBdData->mc_time.timezone
+ // TODO
+
+ // validity_absolute;
+ // TODO
+
+ // validity_relative;
+ // TODO
+
+ // deferred_absolute
+ // TODO
+
+ // deferred_relative;
+ // TODO
+
+ // priority
+ // TODO
+
+ // privacy
+ // TODO
+
+ if ((clientBdData->mask & WMS_MASK_BD_REPLY_OPTION) == WMS_MASK_BD_REPLY_OPTION) {
+ // reply_option.user_ack_requested
+ if (getObjectBooleanField(env, bearerData, "userAckReq", &booleanData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->reply_option.user_ack_requested = (unsigned char)(booleanData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->reply_option.user_ack_requested = %d\n", clientBdData->reply_option.user_ack_requested);
+#endif
+ // reply_option.user_ack_requested
+ if (getObjectBooleanField(env, bearerData, "deliveryAckReq", &booleanData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->reply_option.delivery_ack_requested = (unsigned char)(booleanData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->reply_option.delivery_ack_requested = %d\n", clientBdData->reply_option.delivery_ack_requested);
+#endif
+ // reply_option.user_ack_requested
+ if (getObjectBooleanField(env, bearerData, "readAckReq", &booleanData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->reply_option.read_ack_requested = (unsigned char)(booleanData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->reply_option.read_ack_requested = %d\n", clientBdData->reply_option.read_ack_requested);
+#endif
+ }
+
+ // num_messages
+ if ((clientBdData->mask & WMS_MASK_BD_NUM_OF_MSGS) == WMS_MASK_BD_NUM_OF_MSGS) {
+ if (getObjectIntField(env, bearerData, "numberOfMessages", &intData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->num_messages = (unsigned char)(intData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->num_messages = %d\n", clientBdData->num_messages);
+#endif
+ }
+
+ // alert_mode
+ // TODO
+
+ // language
+ // TODO
+
+ // display_mode
+ if ((clientBdData->mask & WMS_MASK_BD_DISPLAY_MODE) == WMS_MASK_BD_DISPLAY_MODE) {
+ if (getObjectByteField(env, bearerData, "displayMode", &byteData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->display_mode = (RIL_CDMA_SMS_DisplayMode)(byteData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->display_mode = 0x%02x\n", clientBdData->display_mode);
+#endif
+ }
+
+ // delivery_status
+ if ((clientBdData->mask & WMS_MASK_BD_DELIVERY_STATUS) == WMS_MASK_BD_DELIVERY_STATUS) {
+ // delivery_status.error_class
+ if (getObjectIntField(env, bearerData, "errorClass", &intData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->delivery_status.error_class = (RIL_CDMA_SMS_ErrorClass)(intData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->delivery_status.error_class = %d\n", clientBdData->delivery_status.error_class);
+#endif
+ // delivery_status.status
+ if (getObjectIntField(env, bearerData, "messageStatus", &intData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->delivery_status.status = (RIL_CDMA_SMS_DeliveryStatusE)(intData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->delivery_status.status = %d\n", clientBdData->delivery_status.status);
+#endif
+ }
+
+ // deposit_index
+ // TODO
+
+ // ip_address
+ // TODO
+
+ // rsn_no_notify
+ // TODO
+
+ // other
+ // TODO
+
+ return JNI_SUCCESS;
+}
+
+
+/* native interface */
+JNIEXPORT jint JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetBearerDataPrimitives
+ (JNIEnv * env, jobject obj, jobject bearerData)
+{
+ jclass BearerDataClass;
+ jfieldID field;
+ jbyte mctime_buffer[6];
+ jbyteArray addr_array;
+ int length;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsGetBearerDataPrimitives()...\n");
+#endif
+
+ // mask
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->mask = 0x%x\n", clientBdData->mask);
+#endif
+ if (setObjectIntField(env, bearerData, "mask", clientBdData->mask) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // message_id.type
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->message_id.type = 0x%02x\n", clientBdData->message_id.type);
+#endif
+ if (setObjectByteField(env, bearerData, "messageType", (jbyte)clientBdData->message_id.type) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // message_id.id_number
+ if ((clientBdData->mask & WMS_MASK_BD_MSG_ID) == WMS_MASK_BD_MSG_ID) {
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->message_id.id_number = %d\n", clientBdData->message_id.id_number);
+#endif
+ if (setObjectIntField(env, bearerData, "messageID", clientBdData->message_id.id_number) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ }
+
+ // message_id.udh_present
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->message_id.udh_present = %d\n", clientBdData->message_id.udh_present);
+#endif
+ if (setObjectBooleanField(env, bearerData, "hasUserDataHeader", (jboolean)clientBdData->message_id.udh_present) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // user_response
+ // TODO
+
+ // mc_time
+ if ((clientBdData->mask & WMS_MASK_BD_MC_TIME) == WMS_MASK_BD_MC_TIME) {
+ jclass clazz= env->GetObjectClass(bearerData);
+ if (NULL == clazz)
+ return JNI_FAILURE;
+ jfieldID field = env->GetFieldID(clazz, "timeStamp", "[B");
+ env->DeleteLocalRef(clazz);
+
+ addr_array = env->NewByteArray((jsize)6);
+ env->SetObjectField(bearerData, field, addr_array);
+
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->mc_time.year = %d\n", clientBdData->mc_time.year);
+ LOGD("clientBdData->mc_time.month = %d\n", clientBdData->mc_time.month);
+ LOGD("clientBdData->mc_time.day = %d\n", clientBdData->mc_time.day);
+ LOGD("clientBdData->mc_time.hour = %d\n", clientBdData->mc_time.hour);
+ LOGD("clientBdData->mc_time.minute = %d\n", clientBdData->mc_time.minute);
+ LOGD("clientBdData->mc_time.second = %d\n", clientBdData->mc_time.second);
+#endif
+ mctime_buffer[0] = clientBdData->mc_time.year;
+ mctime_buffer[1] = clientBdData->mc_time.month;
+ mctime_buffer[2] = clientBdData->mc_time.day;
+ mctime_buffer[3] = clientBdData->mc_time.hour;
+ mctime_buffer[4] = clientBdData->mc_time.minute;
+ mctime_buffer[5] = clientBdData->mc_time.second;
+ length = sizeof(mctime_buffer) / sizeof(jbyte);
+ if (setObjectByteArrayField(env, bearerData, "timeStamp", mctime_buffer, length) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ }
+
+ // clientBdData->mc_time.timezone
+ // TODO
+
+ // validity_absolute;
+ // TODO
+
+ // validity_relative;
+ // TODO
+
+ // deferred_absolute
+ // TODO
+
+ // deferred_relative;
+ // TODO
+
+ // priority
+ // TODO
+
+ // privacy
+ // TODO
+
+ if ((clientBdData->mask & WMS_MASK_BD_REPLY_OPTION) == WMS_MASK_BD_REPLY_OPTION) {
+ // reply_option.user_ack_requested
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->reply_option.user_ack_requested = %d\n", clientBdData->reply_option.user_ack_requested);
+#endif
+ if (setObjectBooleanField(env, bearerData, "userAckReq", (jboolean)clientBdData->reply_option.user_ack_requested) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // reply_option.user_ack_requested
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->reply_option.delivery_ack_requested = %d\n", clientBdData->reply_option.delivery_ack_requested);
+#endif
+ if (setObjectBooleanField(env, bearerData, "deliveryAckReq", (jboolean)clientBdData->reply_option.delivery_ack_requested) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // reply_option.user_ack_requested
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->reply_option.read_ack_requested = %d\n", clientBdData->reply_option.read_ack_requested);
+#endif
+ if (setObjectBooleanField(env, bearerData, "readAckReq", (jboolean)clientBdData->reply_option.read_ack_requested) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ }
+
+ // num_messages
+ if ((clientBdData->mask & WMS_MASK_BD_NUM_OF_MSGS) == WMS_MASK_BD_NUM_OF_MSGS) {
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->num_messages = %d\n", clientBdData->num_messages);
+#endif
+ if (setObjectIntField(env, bearerData, "numberOfMessages", (int)clientBdData->num_messages) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ }
+
+ // alert_mode
+ // TODO
+
+ // language
+ // TODO
+
+ // display_mode
+ if ((clientBdData->mask & WMS_MASK_BD_DISPLAY_MODE) == WMS_MASK_BD_DISPLAY_MODE) {
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->display_mode = 0x%02x\n", clientBdData->display_mode);
+#endif
+ if (setObjectByteField(env, bearerData, "displayMode", (jbyte)clientBdData->display_mode) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ }
+
+ // delivery_status
+ if ((clientBdData->mask & WMS_MASK_BD_DELIVERY_STATUS) == WMS_MASK_BD_DELIVERY_STATUS) {
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->delivery_status.error_class = %d\n", clientBdData->delivery_status.error_class);
+#endif
+ // delivery_status.error_class
+ if (setObjectIntField(env, bearerData, "errorClass", (int)clientBdData->delivery_status.error_class) != JNI_SUCCESS)
+ return JNI_FAILURE;
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->delivery_status.status = %d\n", clientBdData->delivery_status.status);
+#endif
+ // delivery_status.status
+ if (setObjectIntField(env, bearerData, "messageStatus", (int)clientBdData->delivery_status.status) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ }
+
+ // deposit_index
+ // TODO
+
+ // ip_address
+ // TODO
+
+ // rsn_no_notify
+ // TODO
+
+ // other
+ // TODO
+
+ return JNI_SUCCESS;
+}
+
+
+/* native interface */
+JNIEXPORT jint JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserData
+ (JNIEnv * env, jobject obj, jobject userData)
+{
+ jclass UserDataClass;
+ jfieldID field;
+ jbyteArray arrData = NULL;
+ jbyte data_buf[RIL_CDMA_SMS_USER_DATA_MAX];
+ int length;
+ jint intData;
+ jbyte byteData;
+ jboolean booleanData;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsSetUserData()...\n");
+#endif
+
+ // set num_headers to 0 here, increment later
+ clientBdData->user_data.num_headers = 0;
+
+ // user_data.encoding
+ if (getObjectIntField(env, userData, "userDataEncoding", &intData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->user_data.encoding = (RIL_CDMA_SMS_UserDataEncoding)(intData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.encoding = %d\n", clientBdData->user_data.encoding);
+#endif
+
+ // is91ep_type
+ // TODO
+
+ // user_data.padding_bits
+ if (getObjectIntField(env, userData, "paddingBits", &intData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->user_data.padding_bits = (unsigned char)(intData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.padding_bits = %d\n", clientBdData->user_data.padding_bits);
+#endif
+
+ // user_data.data
+ if (getObjectByteArrayField(env, userData, "userData", data_buf, &length) != JNI_SUCCESS )
+ return JNI_FAILURE;
+ for (int i = 0; i < length; i++) {
+ clientBdData->user_data.data[i] = data_buf[i];
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.data[%d] = 0x%02x\n", i, clientBdData->user_data.data[i]);
+#endif
+ }
+
+ // user_data.data_len
+ // TODO
+
+ // number_of_digits
+ clientBdData->user_data.number_of_digits = (unsigned char)(length);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.number_of_digits = %d\n", clientBdData->user_data.number_of_digits);
+#endif
+
+ return JNI_SUCCESS;
+}
+
+
+/* native interface */
+JNIEXPORT jint JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserData
+ (JNIEnv * env, jobject obj, jobject userData)
+{
+ jclass UserDataClass;
+ jfieldID field;
+ jbyte *data_buf;
+ int length;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsGetUserData()...\n");
+#endif
+
+ // user_data.num_headers
+// if (setObjectIntField(env, userData, "mNumberOfHeaders", (int)clientBdData->user_data.num_headers) != JNI_SUCCESS)
+// return JNI_FAILURE;
+
+ // user_data.encoding
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.encoding = %d\n", clientBdData->user_data.encoding);
+#endif
+ if (setObjectIntField(env, userData, "userDataEncoding", clientBdData->user_data.encoding) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // is91ep_type
+ // TODO
+
+ // user_data.data_len
+// if (setObjectIntField(env, userData, "mDataLength", (int)clientBdData->user_data.data_len) != JNI_SUCCESS)
+// return JNI_FAILURE;
+
+ // user_data.padding_bits
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.padding_bits = %d\n", clientBdData->user_data.padding_bits);
+#endif
+ if (setObjectIntField(env, userData, "paddingBits", (int)clientBdData->user_data.padding_bits) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // user_data.data
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.data_len = %d\n", clientBdData->user_data.data_len);
+#endif
+ length = clientBdData->user_data.data_len;
+#ifdef DBG_LOG_LEVEL_A
+ for (int i = 0; i < length; i++) {
+ LOGD("clientBdData->user_data.data[%d] = 0x%02x\n", i, clientBdData->user_data.data[i]);
+ }
+#endif
+ data_buf = (jbyte*)clientBdData->user_data.data;
+ if (setObjectByteArrayField(env, userData, "userData", data_buf, length) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // number_of_digits
+ // TODO
+
+ return JNI_SUCCESS;
+}
+
+
+/* native interface */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserDataHeader
+ (JNIEnv * env, jobject obj, jint ID, jbyteArray data, jint length, jint index)
+{
+ jbyte data_buf[length];
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsSetUserDataHeader()...\n");
+#endif
+
+ env->GetByteArrayRegion(data, 0, length, data_buf);
+
+ // user_data.headers[index].header_id
+ clientBdData->user_data.headers[index].header_id = (RIL_CDMA_SMS_UdhId)(ID);
+
+ // user_data.headers[index].u
+ // TODO: add support for all udh id's
+ switch(clientBdData->user_data.headers[index].header_id)
+ {
+ case RIL_CDMA_SMS_UDH_CONCAT_8:
+ clientBdData->user_data.headers[index].u.concat_8.msg_ref = data_buf[0];
+ clientBdData->user_data.headers[index].u.concat_8.total_sm = data_buf[1];
+ clientBdData->user_data.headers[index].u.concat_8.seq_num = data_buf[2];
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].u.concat_8.msg_ref = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.msg_ref);
+ LOGD("clientBdData->user_data.headers[%d].u.concat_8.total_sm = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.total_sm);
+ LOGD("clientBdData->user_data.headers[%d].u.concat_8.seq_num = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.seq_num);
+#endif
+ break;
+ case RIL_CDMA_SMS_UDH_SPECIAL_SM:
+ clientBdData->user_data.headers[index].u.special_sm.msg_waiting = (RIL_CDMA_SMS_GWMsgWaiting)(
+ (data_buf[0] << 23) | (data_buf[1] << 15) |
+ (data_buf[2] << 7) | data_buf[3]);
+ clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind = (RIL_CDMA_SMS_GWMsgWaitingKind)(
+ (data_buf[4] << 23) | (data_buf[5] << 15) |
+ (data_buf[6] << 7) | data_buf[7]);
+ clientBdData->user_data.headers[index].u.special_sm.message_count = data_buf[8];
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting);
+ LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting_kind = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind);
+ LOGD("clientBdData->user_data.headers[%d].u.special_sm.message_count = 0x%02x\n", index, clientBdData->user_data.headers[index].u.special_sm.message_count);
+#endif
+ break;
+ case RIL_CDMA_SMS_UDH_PORT_8:
+ clientBdData->user_data.headers[index].u.wap_8.dest_port = data_buf[0];
+ clientBdData->user_data.headers[index].u.wap_8.orig_port = data_buf[1];
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].u.wap_8.dest_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.dest_port);
+ LOGD("clientBdData->user_data.headers[%d].u.wap_8.orig_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.orig_port);
+#endif
+ break;
+ case RIL_CDMA_SMS_UDH_PORT_16:
+ clientBdData->user_data.headers[index].u.wap_16.dest_port = (data_buf[0] << 7) | data_buf[1]; // unsigned short
+ clientBdData->user_data.headers[index].u.wap_16.orig_port = (data_buf[2] << 7) | data_buf[3]; // unsigned short
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].u.wap_16.dest_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.dest_port);
+ LOGD("clientBdData->user_data.headers[%d].u.wap_16.orig_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.orig_port);
+#endif
+ break;
+ case RIL_CDMA_SMS_UDH_CONCAT_16:
+ clientBdData->user_data.headers[index].u.concat_16.msg_ref = (data_buf[0] << 7) | data_buf[1]; // unsigned short
+ clientBdData->user_data.headers[index].u.concat_16.total_sm = data_buf[2];
+ clientBdData->user_data.headers[index].u.concat_16.seq_num = data_buf[3];
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].u.concat_16.msg_ref = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.msg_ref);
+ LOGD("clientBdData->user_data.headers[%d].u.concat_16.total_sm = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.total_sm);
+ LOGD("clientBdData->user_data.headers[%d].u.concat_16.seq_num = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.seq_num);
+#endif
+ break;
+ default:
+ break;
+ }
+
+ // increment num_of_headers
+ clientBdData->user_data.num_headers++;
+
+ return JNI_SUCCESS;
+}
+
+
+/* native interface */
+JNIEXPORT jbyteArray JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserDataHeader
+ (JNIEnv * env, jobject obj)
+{
+ jbyteArray arrData = NULL;
+ jbyte data_buf[sizeof(clientBdData->user_data.headers)];
+ int length = 0;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsGetUserDataHeader()...\n");
+#endif
+
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.num_headers = %d, size = %d\n", clientBdData->user_data.num_headers, sizeof(clientBdData->user_data.headers));
+#endif
+
+ for (int index = 0; index < clientBdData->user_data.num_headers; index++) {
+ // user_data.headers[index].header_id
+ data_buf[length++] = (jbyte)clientBdData->user_data.headers[index].header_id;
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].header_id = %d", index, clientBdData->user_data.headers[index].header_id);
+#endif
+
+ // user_data.headers[index].u
+ // TODO: add support for all udh id's
+ switch(clientBdData->user_data.headers[index].header_id)
+ {
+ case RIL_CDMA_SMS_UDH_CONCAT_8:
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].u.concat_8.msg_ref = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.msg_ref);
+ LOGD("clientBdData->user_data.headers[%d].u.concat_8.total_sm = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.total_sm);
+ LOGD("clientBdData->user_data.headers[%d].u.concat_8.seq_num = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.seq_num);
+#endif
+ data_buf[length++] = 3;
+ data_buf[length++] = clientBdData->user_data.headers[index].u.concat_8.msg_ref;
+ data_buf[length++] = clientBdData->user_data.headers[index].u.concat_8.total_sm;
+ data_buf[length++] = clientBdData->user_data.headers[index].u.concat_8.seq_num;
+ break;
+ case RIL_CDMA_SMS_UDH_SPECIAL_SM:
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting);
+ LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting_kind = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind);
+ LOGD("clientBdData->user_data.headers[%d].u.special_sm.message_count = 0x%02x\n", index, clientBdData->user_data.headers[index].u.special_sm.message_count);
+#endif
+ data_buf[length++] = 9;
+ data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0xFF000000) >> 23; // int
+ data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0x00FF0000) >> 15;
+ data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0x0000FF00) >> 7;
+ data_buf[length++] = clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0x000000FF;
+ data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0xFF000000) >> 23; // int
+ data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0x00FF0000) >> 15;
+ data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0x0000FF00) >> 7;
+ data_buf[length++] = clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0x000000FF;
+ data_buf[length++] = clientBdData->user_data.headers[index].u.special_sm.message_count;
+ break;
+ case RIL_CDMA_SMS_UDH_PORT_8:
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].u.wap_8.dest_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.dest_port);
+ LOGD("clientBdData->user_data.headers[%d].u.wap_8.orig_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.orig_port);
+#endif
+ data_buf[length++] = 2;
+ data_buf[length++] = clientBdData->user_data.headers[index].u.wap_8.dest_port;
+ data_buf[length++] = clientBdData->user_data.headers[index].u.wap_8.orig_port;
+ break;
+ case RIL_CDMA_SMS_UDH_PORT_16:
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].u.wap_16.dest_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.dest_port);
+ LOGD("clientBdData->user_data.headers[%d].u.wap_16.orig_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.orig_port);
+#endif
+ data_buf[length++] = 4;
+ data_buf[length++] = (clientBdData->user_data.headers[index].u.wap_16.dest_port & 0xFF00) >> 7; // unsigned short
+ data_buf[length++] = clientBdData->user_data.headers[index].u.wap_16.dest_port & 0x00FF;
+ data_buf[length++] = (clientBdData->user_data.headers[index].u.wap_16.orig_port & 0xFF00) >> 7; // unsigned short
+ data_buf[length++] = clientBdData->user_data.headers[index].u.wap_16.orig_port & 0x00FF;
+ break;
+ case RIL_CDMA_SMS_UDH_CONCAT_16:
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->user_data.headers[%d].u.concat_16.msg_ref = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.msg_ref);
+ LOGD("clientBdData->user_data.headers[%d].u.concat_16.total_sm = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.total_sm);
+ LOGD("clientBdData->user_data.headers[%d].u.concat_16.seq_num = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.seq_num);
+#endif
+ data_buf[length++] = 4;
+ data_buf[length++] = (clientBdData->user_data.headers[index].u.concat_16.msg_ref & 0xFF00) >> 7; // unsigned short
+ data_buf[length++] = clientBdData->user_data.headers[index].u.concat_16.msg_ref & 0x00FF;
+ data_buf[length++] = clientBdData->user_data.headers[index].u.concat_16.total_sm;
+ data_buf[length++] = clientBdData->user_data.headers[index].u.concat_16.seq_num;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (length != 0) {
+ arrData = env->NewByteArray((jsize)length);
+ env->SetByteArrayRegion(arrData, 0, length, data_buf);
+ }
+
+ return arrData;
+}
+
+
+/* native interface */
+JNIEXPORT jint JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetSmsAddress
+ (JNIEnv * env, jobject obj, jobject smsAddress)
+{
+ jclass SmsAddressClass;
+ jfieldID field;
+ jbyteArray arrData = NULL;
+ jbyte byte_buf[RIL_CDMA_SMS_ADDRESS_MAX];
+ int length;
+ jint intData;
+ jbyte byteData;
+ jboolean booleanData;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsSetSmsAddress()...\n");
+#endif
+
+ // callback.digit_mode
+ if (getObjectByteField(env, smsAddress, "digitMode", &byteData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->callback.digit_mode = (RIL_CDMA_SMS_DigitMode)(byteData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.digit_mode = 0x%02x\n", clientBdData->callback.digit_mode);
+#endif
+
+ // callback.number_mode
+ if (getObjectByteField(env, smsAddress, "numberMode", &byteData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->callback.number_mode = (RIL_CDMA_SMS_NumberMode)(byteData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.number_mode = 0x%02x\n", clientBdData->callback.number_mode);
+#endif
+
+ // callback.number_type
+ if (getObjectIntField(env, smsAddress, "ton", &intData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->callback.number_type = (RIL_CDMA_SMS_NumberType)(intData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.number_type = %d\n", clientBdData->callback.number_type);
+#endif
+
+ // callback.number_plan
+ if (getObjectByteField(env, smsAddress, "numberPlan", &byteData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->callback.number_plan = (RIL_CDMA_SMS_NumberPlan)(byteData);
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.number_plan = 0x%02x\n", clientBdData->callback.number_plan);
+#endif
+
+ // callback.number_of_digits
+ if (getObjectByteField(env, smsAddress, "numberOfDigits", &byteData) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ clientBdData->callback.number_of_digits = byteData;
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.number_of_digits = %d\n",clientBdData->callback.number_of_digits);
+#endif
+
+ // callback.digits
+ if (getObjectByteArrayField(env, smsAddress, "origBytes", byte_buf, &length) != JNI_SUCCESS)
+ return JNI_FAILURE;
+ for (int i = 0; i < clientBdData->callback.number_of_digits; i++) {
+ clientBdData->callback.digits[i] = byte_buf[i];
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.digits[%d] = 0x%02x\n", i, clientBdData->callback.digits[i]);
+#endif
+ }
+
+ return JNI_SUCCESS;
+}
+
+
+/* native interface */
+JNIEXPORT jint JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetSmsAddress
+ (JNIEnv * env, jobject obj, jobject smsAddress)
+{
+ jclass SmsAddressClass;
+ jfieldID field;
+ jbyteArray arrData = NULL;
+ jbyte *byte_buf;
+ int length;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsGetSmsAddress()...\n");
+#endif
+
+ // callback.digit_mode
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.digit_mode = 0x%02x\n", clientBdData->callback.digit_mode);
+#endif
+ if (setObjectByteField(env, smsAddress, "digitMode", (jbyte)clientBdData->callback.digit_mode) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // callback.number_mode
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.number_mode = 0x%02x\n", clientBdData->callback.number_mode);
+#endif
+ if (setObjectByteField(env, smsAddress, "numberMode", (jbyte)clientBdData->callback.number_mode) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // callback.number_type
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.number_type = %d\n", clientBdData->callback.number_type);
+#endif
+ if (setObjectIntField(env, smsAddress, "ton", (jint)clientBdData->callback.number_type) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // callback.number_plan
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.number_plan = 0x%02x\n", clientBdData->callback.number_plan);
+#endif
+ if (setObjectByteField(env, smsAddress, "numberPlan", (jbyte)clientBdData->callback.number_plan) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // callback.number_of_digits
+#ifdef DBG_LOG_LEVEL_A
+ LOGD("clientBdData->callback.number_of_digits = %d\n", clientBdData->callback.number_of_digits);
+#endif
+ if (setObjectByteField(env, smsAddress, "numberOfDigits", (jbyte)clientBdData->callback.number_of_digits) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ // callback.digits
+ byte_buf = (jbyte*)clientBdData->callback.digits;
+ length = clientBdData->callback.number_of_digits;
+#ifdef DBG_LOG_LEVEL_A
+ for (int i = 0; i < length; i++) {
+ LOGD("clientBdData->callback.digits[%d] = 0x%02x\n", i, clientBdData->callback.digits[i]);
+ }
+#endif
+
+ if (setObjectByteArrayField(env, smsAddress, "origBytes", byte_buf, length) != JNI_SUCCESS)
+ return JNI_FAILURE;
+
+ return JNI_SUCCESS;
+}
+
+
+/* native interface */
+JNIEXPORT jbyteArray JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsEncodeSms
+ (JNIEnv * env, jobject obj)
+{
+ RIL_CDMA_Encoded_SMS *encoded_sms = (RIL_CDMA_Encoded_SMS *)malloc(sizeof(RIL_CDMA_Encoded_SMS));
+ jbyte* data_buf;
+ jint result = JNI_SUCCESS;
+ jbyteArray encodedSMS;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsEncodeSms(): entry\n");
+#endif
+
+ if (NULL == encoded_sms) {
+ jniThrowException(env, "java/lang/NullPointerException", "encoded_sms is null");
+ return NULL;
+ }
+ memset(encoded_sms, 0, sizeof(RIL_CDMA_Encoded_SMS));
+
+ // call CDMA SMS encode function
+ if(wmsts_ril_cdma_encode_sms(clientBdData, encoded_sms) != RIL_E_SUCCESS) {
+ jniThrowException(env, "java/lang/Exception", "CDMA SMS Encoding failed");
+ return NULL;
+ }
+
+#ifdef DBG_LOG_LEVEL_A
+ LOGD(" EncodeSMS: length = %i\n", encoded_sms->length);
+#endif
+ encodedSMS = env->NewByteArray((jsize)encoded_sms->length);
+ env->SetByteArrayRegion(encodedSMS, 0, encoded_sms->length, (jbyte*)encoded_sms->data);
+ free(encoded_sms);
+
+ return encodedSMS;
+}
+
+
+/* native interface */
+JNIEXPORT jint JNICALL
+Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDecodeSms
+ (JNIEnv * env, jobject obj, jbyteArray encodedSMS)
+{
+ RIL_CDMA_Encoded_SMS *encoded_sms = (RIL_CDMA_Encoded_SMS *)malloc(sizeof(RIL_CDMA_Encoded_SMS));
+ jbyte* data_buf;
+ jint result = JNI_SUCCESS;
+ jsize length;
+
+#ifdef DBG_LOG_LEVEL_B
+ LOGD("nativeCdmaSmsDecodeSms(): entry\n");
+#endif
+
+ if (NULL == encoded_sms) {
+ jniThrowException(env, "java/lang/NullPointerException", "encoded_sms is null");
+ return JNI_FAILURE;
+ }
+ memset(encoded_sms, 0, sizeof(RIL_CDMA_Encoded_SMS));
+
+ length = env->GetArrayLength(encodedSMS);
+ if (length < 0 || length > 255) {
+ jniThrowException(env, "java/lang/ArrayIndexOutOfBounds", "wrong encoded SMS data length");
+ return JNI_FAILURE;
+ }
+ encoded_sms->length = length;
+#ifdef DBG_LOG_LEVEL_A
+ LOGD(" DecodeSMS: arrayLength = %d\n", encoded_sms->length);
+#endif
+ data_buf = env->GetByteArrayElements(encodedSMS, NULL);
+ encoded_sms->data = (unsigned char*)data_buf;
+ env->ReleaseByteArrayElements(encodedSMS, data_buf, 0);
+
+ // call CDMA SMS decode function
+ if(wmsts_ril_cdma_decode_sms(encoded_sms, clientBdData) != RIL_E_SUCCESS) {
+ jniThrowException(env, "java/lang/Exception", "CDMA SMS Decoding failed");
+ result = JNI_FAILURE;
+ }
+
+ free(encoded_sms);
+
+ return result;
+}
+
+
+// ---------------------------------------------------------------------------
+
+static const char *classPathName = "com/android/internal/telephony/cdma/sms/SmsDataCoding";
+
+static JNINativeMethod methods[] = {
+ /* name, signature, funcPtr */
+ {"nativeCdmaSmsConstructClientBD", "()I",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsConstructClientBD },
+ {"nativeCdmaSmsDestructClientBD", "()I",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDestructClientBD },
+ {"nativeCdmaSmsSetBearerDataPrimitives", "(Lcom/android/internal/telephony/cdma/sms/BearerData;)I",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetBearerDataPrimitives },
+ {"nativeCdmaSmsGetBearerDataPrimitives", "(Lcom/android/internal/telephony/cdma/sms/BearerData;)I",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetBearerDataPrimitives },
+ {"nativeCdmaSmsSetUserData", "(Lcom/android/internal/telephony/cdma/sms/UserData;)I",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserData },
+ {"nativeCdmaSmsGetUserData", "(Lcom/android/internal/telephony/cdma/sms/UserData;)I",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserData },
+ {"nativeCdmaSmsSetUserDataHeader", "(I[BII)I",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserDataHeader },
+ {"nativeCdmaSmsGetUserDataHeader", "()[B",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserDataHeader },
+ {"nativeCdmaSmsSetSmsAddress", "(Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetSmsAddress },
+ {"nativeCdmaSmsGetSmsAddress", "(Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetSmsAddress },
+ {"nativeCdmaSmsEncodeSms", "()[B",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsEncodeSms },
+ {"nativeCdmaSmsDecodeSms", "([B)I",
+ (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDecodeSms },
+};
+
+int register_android_cdma_sms_methods(JNIEnv *_env)
+{
+ return android::AndroidRuntime::registerNativeMethods(
+ _env, classPathName, methods, NELEM(methods));
+}
+
+// ---------------------------------------------------------------------------
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+ JNIEnv* env = NULL;
+ jint result = -1;
+
+ if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+ LOGE("ERROR: GetEnv failed\n");
+ goto bail;
+ }
+ assert(env != NULL);
+
+ if (register_android_cdma_sms_methods(env) < 0) {
+ LOGE("ERROR: CDMA SMS native registration failed\n");
+ goto bail;
+ }
+
+ /* success -- return valid version number */
+ result = JNI_VERSION_1_4;
+
+bail:
+ return result;
+}
diff --git a/telephony/jni/cdmasms/cdma_sms_jni.h b/telephony/jni/cdmasms/cdma_sms_jni.h
new file mode 100644
index 000000000000..253c006cd9a5
--- /dev/null
+++ b/telephony/jni/cdmasms/cdma_sms_jni.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_android_internal_telephony_cdma_sms_SmsDataCoding */
+
+#ifndef _Included_com_android_internal_telephony_cdma_sms_SmsDataCoding
+#define _Included_com_android_internal_telephony_cdma_sms_SmsDataCoding
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NULL
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NULL 0L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MSG_ID
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MSG_ID 1L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_USER_DATA
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_USER_DATA 2L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MC_TIME
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MC_TIME 8L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS 2048L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_CALLBACK
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_CALLBACK 16384L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE 32768L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_SUCCESS
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_SUCCESS 0L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FAILURE
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FAILURE 1L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_DATA_LEN_OUT_OF_RANGE
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_DATA_LEN_OUT_OF_RANGE 2L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_CLASS_UNKNOWN
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_CLASS_UNKNOWN 3L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FIELD_ID_UNKNOWN
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FIELD_ID_UNKNOWN 4L
+#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_OUT_OF_MEMORY
+#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_OUT_OF_MEMORY 5L
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsConstructClientBD
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsConstructClientBD
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsDestructClientBD
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDestructClientBD
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsSetBearerDataPrimitives
+ * Signature: (Lcom/android/internal/telephony/cdma/sms/BearerData;)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetBearerDataPrimitives
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsGetBearerDataPrimitives
+ * Signature: (Lcom/android/internal/telephony/cdma/sms/BearerData;)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetBearerDataPrimitives
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsSetUserData
+ * Signature: (Lcom/android/internal/telephony/cdma/sms/UserData;)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserData
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsGetUserData
+ * Signature: (Lcom/android/internal/telephony/cdma/sms/UserData;)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserData
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsSetUserDataHeader
+ * Signature: (I[BII)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserDataHeader
+ (JNIEnv *, jobject, jint, jbyteArray, jint, jint);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsGetUserDataHeader
+ * Signature: ()[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserDataHeader
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsSetSmsAddress
+ * Signature: (Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetSmsAddress
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsGetSmsAddress
+ * Signature: (Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetSmsAddress
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsEncodeSms
+ * Signature: ()[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsEncodeSms
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding
+ * Method: nativeCdmaSmsDecodeSms
+ * Signature: ([B)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDecodeSms
+ (JNIEnv *, jobject, jbyteArray);
+
+/**
+ * CDMA SMS return value defines
+ */
+#define JNI_SUCCESS \
+com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_SUCCESS /**< Successful operation */
+#define JNI_FAILURE \
+com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FAILURE /**< General failure */
+
+#ifdef __cplusplus
+}
+#endif
+#endif