summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeam Android CDMA <oss.android_cdma@teleca.com>2009-01-22 16:28:40 +0100
committerTeam Android CDMA <oss.android_cdma@teleca.com>2009-02-16 18:46:10 +0100
commitedc6899a2a0f5760d789ef4bb6b086c25a044048 (patch)
tree545c9e7cccd0d470f288e15d5c8327ee818028f3
parent9dd221e6d24b1cbbe19345f048bf27fbb97d62c1 (diff)
downloadbase-cdma-import.tar.gz
Extend ANDROID with CDMA mobile technology support . Feature Complete. Review Comments Fixedcdma-import
This contribution is final functional step of the first release of the CDMA extension of the Android telephony layers. It contains changes in the phone related applications, the application framework telephony packages and in the RIL daemon library space. The implementation of the CDMA support requires architectural changes in the telephony package and extensions of the RIL interface. The application interface (SDK interface) will be extended to provide CDMA specific features/information to the phone related application and other applications. Where ever possible the actual used radio technology is transparent for the application using mobile connections. This increment is tested on the Android emulator with a RIL simulator tool and also tested on a reference HW platform. The CDMA extension of the telephony stack can be used for Android phones supporting either CDMA mobile technology only or world mode including GSM/WCDMA and CDMA. The following CDMA technologies are considered: IS-95, CDMA2000 1xRTT, CDMA2000 1x EVDO. This contribution implements the following functionality: - start up, - access the CDMA subscription and other information from memory of from the card (either SIM, USIM or RUIM), - register to the network, - provides registration status to the application for displaying - be able to handle incoming and outgoing voice calls, - provide phone and call settings in the settings application - provide supplementary services in the settings application - provide supplementary services by in-call menues - handles TTY and enhance voice privacy - supports automatic radio technology change for a world mode phone from CDMA to GSM/UMTS or vice versa - send and receive SMS - configure and receive Broadcast SMS - receive WAP Push SMS Signed-off by : Saverio Labella, saverio.labella@teleca.com Sigmar Lingner, sigmar.lingner@teleca.com
-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